]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/subversion/subversion/libsvn_fs_base/bdb/checksum-reps-table.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / subversion / subversion / libsvn_fs_base / bdb / checksum-reps-table.c
1 /* checksum-reps-table.c : operations on the `checksum-reps' table
2  *
3  * ====================================================================
4  *    Licensed to the Apache Software Foundation (ASF) under one
5  *    or more contributor license agreements.  See the NOTICE file
6  *    distributed with this work for additional information
7  *    regarding copyright ownership.  The ASF licenses this file
8  *    to you under the Apache License, Version 2.0 (the
9  *    "License"); you may not use this file except in compliance
10  *    with the License.  You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *    Unless required by applicable law or agreed to in writing,
15  *    software distributed under the License is distributed on an
16  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  *    KIND, either express or implied.  See the License for the
18  *    specific language governing permissions and limitations
19  *    under the License.
20  * ====================================================================
21  */
22
23 #include <apr_strings.h>
24
25 #include "bdb_compat.h"
26 #include "../fs.h"
27 #include "../err.h"
28 #include "../key-gen.h"
29 #include "dbt.h"
30 #include "../trail.h"
31 #include "bdb-err.h"
32 #include "../../libsvn_fs/fs-loader.h"
33 #include "checksum-reps-table.h"
34
35 #include "svn_private_config.h"
36
37 \f
38 int svn_fs_bdb__open_checksum_reps_table(DB **checksum_reps_p,
39                                          DB_ENV *env,
40                                          svn_boolean_t create)
41 {
42   const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
43   DB *checksum_reps;
44   int error;
45
46   BDB_ERR(svn_fs_bdb__check_version());
47   BDB_ERR(db_create(&checksum_reps, env, 0));
48   error = (checksum_reps->open)(SVN_BDB_OPEN_PARAMS(checksum_reps, NULL),
49                                 "checksum-reps", 0, DB_BTREE,
50                                 open_flags, 0666);
51
52   /* Create the checksum-reps table if it doesn't exist. */
53   if (error == ENOENT && (! create))
54     {
55       BDB_ERR(checksum_reps->close(checksum_reps, 0));
56       return svn_fs_bdb__open_checksum_reps_table(checksum_reps_p, env, TRUE);
57     }
58
59   /* Create the initial `next-key' table entry.  */
60   if (create)
61     {
62       DBT key, value;
63       BDB_ERR(checksum_reps->put(checksum_reps, 0,
64                                  svn_fs_base__str_to_dbt(&key, NEXT_KEY_KEY),
65                                  svn_fs_base__str_to_dbt(&value, "0"), 0));
66     }
67
68   BDB_ERR(error);
69
70   *checksum_reps_p = checksum_reps;
71   return 0;
72 }
73
74 svn_error_t *svn_fs_bdb__get_checksum_rep(const char **rep_key,
75                                           svn_fs_t *fs,
76                                           svn_checksum_t *checksum,
77                                           trail_t *trail,
78                                           apr_pool_t *pool)
79 {
80   base_fs_data_t *bfd = fs->fsap_data;
81   DBT key, value;
82   int db_err;
83
84   /* We only allow SHA1 checksums in this table. */
85   if (checksum->kind != svn_checksum_sha1)
86     return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
87                             _("Only SHA1 checksums can be used as keys in the "
88                               "checksum-reps table.\n"));
89
90   svn_fs_base__trail_debug(trail, "checksum-reps", "get");
91   db_err = bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
92                                    svn_fs_base__checksum_to_dbt(&key, checksum),
93                                    svn_fs_base__result_dbt(&value), 0);
94   svn_fs_base__track_dbt(&value, pool);
95
96   if (db_err == DB_NOTFOUND)
97     return svn_fs_base__err_no_such_checksum_rep(fs, checksum);
98
99   *rep_key = apr_pstrmemdup(pool, value.data, value.size);
100   return SVN_NO_ERROR;
101 }
102
103 svn_error_t *svn_fs_bdb__set_checksum_rep(svn_fs_t *fs,
104                                           svn_checksum_t *checksum,
105                                           const char *rep_key,
106                                           trail_t *trail,
107                                           apr_pool_t *pool)
108 {
109   base_fs_data_t *bfd = fs->fsap_data;
110   DBT key, value;
111   int db_err;
112
113   /* We only allow SHA1 checksums in this table. */
114   if (checksum->kind != svn_checksum_sha1)
115     return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
116                             _("Only SHA1 checksums can be used as keys in the "
117                               "checksum-reps table.\n"));
118
119   /* Create a key from our CHECKSUM. */
120   svn_fs_base__checksum_to_dbt(&key, checksum);
121
122   /* Check to see if we already have a mapping for CHECKSUM.  If so,
123      and the value is the same one we were about to write, that's
124      cool -- just do nothing.  If, however, the value is *different*,
125      that's a red flag!  */
126   svn_fs_base__trail_debug(trail, "checksum-reps", "get");
127   db_err = bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
128                                    &key, svn_fs_base__result_dbt(&value), 0);
129   svn_fs_base__track_dbt(&value, pool);
130   if (db_err != DB_NOTFOUND)
131     {
132       const char *sum_str = svn_checksum_to_cstring_display(checksum, pool);
133       return svn_error_createf
134         (SVN_ERR_FS_ALREADY_EXISTS, NULL,
135          _("Representation key for checksum '%s' exists in filesystem '%s'."),
136          sum_str, fs->path);
137     }
138
139   /* Create a value from our REP_KEY, and add this record to the table. */
140   svn_fs_base__str_to_dbt(&value, rep_key);
141   svn_fs_base__trail_debug(trail, "checksum-reps", "put");
142   SVN_ERR(BDB_WRAP(fs, N_("storing checksum-reps record"),
143                    bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn,
144                                            &key, &value, 0)));
145   return SVN_NO_ERROR;
146 }
147
148 svn_error_t *svn_fs_bdb__delete_checksum_rep(svn_fs_t *fs,
149                                              svn_checksum_t *checksum,
150                                              trail_t *trail,
151                                              apr_pool_t *pool)
152 {
153   base_fs_data_t *bfd = fs->fsap_data;
154   DBT key;
155
156   /* We only allow SHA1 checksums in this table. */
157   if (checksum->kind != svn_checksum_sha1)
158     return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
159                             _("Only SHA1 checksums can be used as keys in the "
160                               "checksum-reps table.\n"));
161
162   svn_fs_base__checksum_to_dbt(&key, checksum);
163   svn_fs_base__trail_debug(trail, "checksum-reps", "del");
164   SVN_ERR(BDB_WRAP(fs, N_("deleting entry from 'checksum-reps' table"),
165                    bfd->checksum_reps->del(bfd->checksum_reps,
166                                            trail->db_txn, &key, 0)));
167   return SVN_NO_ERROR;
168 }
169
170 svn_error_t *svn_fs_bdb__reserve_rep_reuse_id(const char **id_p,
171                                               svn_fs_t *fs,
172                                               trail_t *trail,
173                                               apr_pool_t *pool)
174 {
175   base_fs_data_t *bfd = fs->fsap_data;
176   DBT query, result;
177   apr_size_t len;
178   char next_key[MAX_KEY_SIZE];
179   int db_err;
180
181   svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
182
183   /* Get the current value associated with the `next-key' key in the
184      `checksum-reps' table.  */
185   svn_fs_base__trail_debug(trail, "checksum-reps", "get");
186   SVN_ERR(BDB_WRAP(fs, N_("allocating new representation reuse ID "
187                          "(getting 'next-key')"),
188                    bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
189                                            &query,
190                                            svn_fs_base__result_dbt(&result),
191                                            0)));
192   svn_fs_base__track_dbt(&result, pool);
193
194   /* Set our return value. */
195   *id_p = apr_pstrmemdup(pool, result.data, result.size);
196
197   /* Bump to future key. */
198   len = result.size;
199   svn_fs_base__next_key(result.data, &len, next_key);
200   svn_fs_base__trail_debug(trail, "checksum_reps", "put");
201   db_err = bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn,
202                                    svn_fs_base__str_to_dbt(&query,
203                                                            NEXT_KEY_KEY),
204                                    svn_fs_base__str_to_dbt(&result, next_key),
205                                    0);
206
207   return BDB_WRAP(fs, N_("bumping next representation reuse ID"), db_err);
208 }