1 /* util.h --- utility functions for FSX repo access
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
20 * ====================================================================
23 #ifndef SVN_LIBSVN_FS__UTIL_H
24 #define SVN_LIBSVN_FS__UTIL_H
29 /* Functions for dealing with recoverable errors on mutable files
31 * Revprops, current, and txn-current files are mutable; that is, they
32 * change as part of normal fsx operation, in constrat to revs files, or
33 * the format file, which are written once at create (or upgrade) time.
34 * When more than one host writes to the same repository, we will
35 * sometimes see these recoverable errors when accesssing these files.
37 * These errors all relate to NFS, and thus we only use this retry code if
42 * In NFS v3 and under, the server doesn't track opened files. If you
43 * unlink(2) or rename(2) a file held open by another process *on the
44 * same host*, that host's kernel typically renames the file to
45 * .nfsXXXX and automatically deletes that when it's no longer open,
46 * but this behavior is not required.
48 * For obvious reasons, this does not work *across hosts*. No one
49 * knows about the opened file; not the server, and not the deleting
50 * client. So the file vanishes, and the reader gets stale NFS file
55 * Some client implementations (at least the 2.6.18.5 kernel that ships
56 * with Ubuntu Dapper) sometimes give spurious ENOENT (only on open) or
57 * even EIO errors when trying to read these files that have been renamed
58 * over on some other host.
62 * Try open and read of such files in try_stringbuf_from_file(). Call
63 * this function within a loop of SVN_FS_X__RECOVERABLE_RETRY_COUNT
64 * iterations (though, realistically, the second try will succeed).
67 #define SVN_FS_X__RECOVERABLE_RETRY_COUNT 10
69 /* Pathname helper functions */
71 /* Return TRUE is REV is packed in FS, FALSE otherwise. */
73 svn_fs_x__is_packed_rev(svn_fs_t *fs,
76 /* Return TRUE is REV is packed in FS, FALSE otherwise. */
78 svn_fs_x__is_packed_revprop(svn_fs_t *fs,
81 /* Return the first revision in the pack / rev file containing REV in
82 * filesystem FS. For non-packed revs, this will simply be REV. */
84 svn_fs_x__packed_base_rev(svn_fs_t *fs,
87 /* Return the number of revisions in the pack / rev file in FS that contains
90 svn_fs_x__pack_size(svn_fs_t *fs, svn_revnum_t rev);
92 /* Return the full path of the "format" file in FS.
93 * The result will be allocated in RESULT_POOL.
96 svn_fs_x__path_format(svn_fs_t *fs,
97 apr_pool_t *result_pool);
99 /* Return the path to the 'current' file in FS.
100 Perform allocation in RESULT_POOL. */
102 svn_fs_x__path_current(svn_fs_t *fs,
103 apr_pool_t *result_pool);
105 /* Return the full path of the "uuid" file in FS.
106 * The result will be allocated in RESULT_POOL.
109 svn_fs_x__path_uuid(svn_fs_t *fs,
110 apr_pool_t *result_pool);
112 /* Return the full path of the "txn-current" file in FS.
113 * The result will be allocated in RESULT_POOL.
116 svn_fs_x__path_txn_current(svn_fs_t *fs,
117 apr_pool_t *result_pool);
119 /* Return the full path of the "txn-current-lock" file in FS.
120 * The result will be allocated in RESULT_POOL.
123 svn_fs_x__path_txn_current_lock(svn_fs_t *fs,
124 apr_pool_t *result_pool);
126 /* Return the full path of the global write lock file in FS.
127 * The result will be allocated in RESULT_POOL.
130 svn_fs_x__path_lock(svn_fs_t *fs,
131 apr_pool_t *result_pool);
133 /* Return the full path of the pack operation lock file in FS.
134 * The result will be allocated in RESULT_POOL.
137 svn_fs_x__path_pack_lock(svn_fs_t *fs,
138 apr_pool_t *result_pool);
140 /* Return the full path of the revprop generation file in FS.
141 * Allocate the result in RESULT_POOL.
144 svn_fs_x__path_revprop_generation(svn_fs_t *fs,
145 apr_pool_t *result_pool);
147 /* Return the path of the pack-related file that for revision REV in FS.
148 * KIND specifies the file name base, e.g. "pack".
149 * The result will be allocated in RESULT_POOL.
152 svn_fs_x__path_rev_packed(svn_fs_t *fs,
155 apr_pool_t *result_pool);
157 /* Return the full path of the rev shard directory that will contain
158 * revision REV in FS. Allocate the result in RESULT_POOL.
161 svn_fs_x__path_rev_shard(svn_fs_t *fs,
163 apr_pool_t *result_pool);
165 /* Return the full path of the non-packed rev file containing revision REV
166 * in FS. Allocate the result in RESULT_POOL.
169 svn_fs_x__path_rev(svn_fs_t *fs,
171 apr_pool_t *result_pool);
173 /* Set *PATH to the path of REV in FS, whether in a pack file or not.
174 Allocate *PATH in RESULT_POOL.
176 Note: If the caller does not have the write lock on FS, then the path is
177 not guaranteed to be correct or to remain correct after the function
178 returns, because the revision might become packed before or after this
179 call. If a file exists at that path, then it is correct; if not, then
180 the caller should call update_min_unpacked_rev() and re-try once. */
182 svn_fs_x__path_rev_absolute(svn_fs_t *fs,
184 apr_pool_t *result_pool);
186 /* Return the full path of the revision properties shard directory that
187 * will contain the properties of revision REV in FS.
188 * Allocate the result in RESULT_POOL.
191 svn_fs_x__path_revprops_shard(svn_fs_t *fs,
193 apr_pool_t *result_pool);
195 /* Return the full path of the revision properties pack shard directory
196 * that will contain the packed properties of revision REV in FS.
197 * Allocate the result in RESULT_POOL.
200 svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs,
202 apr_pool_t *result_pool);
204 /* Return the full path of the non-packed revision properties file that
205 * contains the props for revision REV in FS.
206 * Allocate the result in RESULT_POOL.
209 svn_fs_x__path_revprops(svn_fs_t *fs,
211 apr_pool_t *result_pool);
213 /* Convert the TXN_ID into a string, allocated from RESULT_POOL.
216 svn_fs_x__txn_name(svn_fs_x__txn_id_t txn_id,
217 apr_pool_t *result_pool);
219 /* Convert TXN_NAME into an ID and return it in *TXN_ID. */
221 svn_fs_x__txn_by_name(svn_fs_x__txn_id_t *txn_id,
222 const char *txn_name);
224 /* Return the path of the directory containing the transaction TXN_ID in FS.
225 * The result will be allocated in RESULT_POOL.
228 svn_fs_x__path_txn_dir(svn_fs_t *fs,
229 svn_fs_x__txn_id_t txn_id,
230 apr_pool_t *result_pool);
232 /* Return the path of the 'transactions' directory in FS.
233 * The result will be allocated in RESULT_POOL.
236 svn_fs_x__path_txns_dir(svn_fs_t *fs,
237 apr_pool_t *result_pool);
239 /* Return the name of the sha1->rep mapping file in transaction TXN_ID
240 * within FS for the given SHA1 checksum. Use POOL for allocations.
243 svn_fs_x__path_txn_sha1(svn_fs_t *fs,
244 svn_fs_x__txn_id_t txn_id,
245 const unsigned char *sha1,
248 /* Return the path of the 'txn-protorevs' directory in FS, even if that
249 * folder may not exist in FS. The result will be allocated in RESULT_POOL.
252 svn_fs_x__path_txn_proto_revs(svn_fs_t *fs,
253 apr_pool_t *result_pool);
255 /* Return the path of the changes file for transaction TXN_ID in FS.
256 * The result will be allocated in RESULT_POOL.
259 svn_fs_x__path_txn_changes(svn_fs_t *fs,
260 svn_fs_x__txn_id_t txn_id,
261 apr_pool_t *result_pool);
263 /* Return the path of the file containing the log-to-phys index for
264 * the transaction identified by TXN_ID in FS.
265 * The result will be allocated in RESULT_POOL.
268 svn_fs_x__path_l2p_proto_index(svn_fs_t *fs,
269 svn_fs_x__txn_id_t txn_id,
270 apr_pool_t *result_pool);
272 /* Return the path of the file containing the phys-to-log index for
273 * the transaction identified by TXN_ID in FS.
274 * The result will be allocated in RESULT_POOL.
277 svn_fs_x__path_p2l_proto_index(svn_fs_t *fs,
278 svn_fs_x__txn_id_t txn_id,
279 apr_pool_t *result_pool);
281 /* Return the path of the file containing the transaction properties for
282 * the transaction identified by TXN_ID in FS.
283 * The result will be allocated in RESULT_POOL.
286 svn_fs_x__path_txn_props(svn_fs_t *fs,
287 svn_fs_x__txn_id_t txn_id,
288 apr_pool_t *result_pool);
290 /* Return the path of the file containing the "final" transaction
291 * properties for the transaction identified by TXN_ID in FS.
292 * The result will be allocated in RESULT_POOL.
295 svn_fs_x__path_txn_props_final(svn_fs_t *fs,
296 svn_fs_x__txn_id_t txn_id,
297 apr_pool_t *result_pool);
299 /* Return the path of the file containing the node and copy ID counters for
300 * the transaction identified by TXN_ID in FS.
301 * The result will be allocated in RESULT_POOL.
304 svn_fs_x__path_txn_next_ids(svn_fs_t *fs,
305 svn_fs_x__txn_id_t txn_id,
306 apr_pool_t *result_pool);
308 /* Return the path of the file storing the oldest non-packed revision in FS.
309 * The result will be allocated in RESULT_POOL.
312 svn_fs_x__path_min_unpacked_rev(svn_fs_t *fs,
313 apr_pool_t *result_pool);
315 /* Return the path of the file containing item_index counter for
316 * the transaction identified by TXN_ID in FS.
317 * The result will be allocated in RESULT_POOL.
320 svn_fs_x__path_txn_item_index(svn_fs_t *fs,
321 svn_fs_x__txn_id_t txn_id,
322 apr_pool_t *result_pool);
324 /* Return the path of the proto-revision file for transaction TXN_ID in FS.
325 * The result will be allocated in RESULT_POOL.
328 svn_fs_x__path_txn_proto_rev(svn_fs_t *fs,
329 svn_fs_x__txn_id_t txn_id,
330 apr_pool_t *result_pool);
332 /* Return the path of the proto-revision lock file for transaction TXN_ID
333 * in FS. The result will be allocated in RESULT_POOL.
336 svn_fs_x__path_txn_proto_rev_lock(svn_fs_t *fs,
337 svn_fs_x__txn_id_t txn_id,
338 apr_pool_t *result_pool);
340 /* Return the path of the file containing the in-transaction node revision
341 * identified by ID in FS.
342 * The result will be allocated in RESULT_POOL, temporaries in SCRATCH_POOL.
345 svn_fs_x__path_txn_node_rev(svn_fs_t *fs,
346 const svn_fs_x__id_t *id,
347 apr_pool_t *result_pool,
348 apr_pool_t *scratch_pool);
350 /* Return the path of the file containing the in-transaction properties of
351 * the node identified by ID in FS.
352 * The result will be allocated in RESULT_POOL, temporaries in SCRATCH_POOL.
355 svn_fs_x__path_txn_node_props(svn_fs_t *fs,
356 const svn_fs_x__id_t *id,
357 apr_pool_t *result_pool,
358 apr_pool_t *scratch_pool);
360 /* Return the path of the file containing the directory entries of the
361 * in-transaction directory node identified by ID in FS.
362 * The result will be allocated in RESULT_POOL, temporaries in SCRATCH_POOL.
365 svn_fs_x__path_txn_node_children(svn_fs_t *fs,
366 const svn_fs_x__id_t *id,
367 apr_pool_t *result_pool,
368 apr_pool_t *scratch_pool);
370 /* Check that BUF, a nul-terminated buffer of text from file PATH,
371 contains only digits at OFFSET and beyond, raising an error if not.
372 TITLE contains a user-visible description of the file, usually the
375 Uses SCRATCH_POOL for temporary allocation. */
377 svn_fs_x__check_file_buffer_numeric(const char *buf,
381 apr_pool_t *scratch_pool);
383 /* Set *MIN_UNPACKED_REV to the integer value read from the file returned
384 * by #svn_fs_fs__path_min_unpacked_rev() for FS.
385 * Use SCRATCH_POOL for temporary allocations.
388 svn_fs_x__read_min_unpacked_rev(svn_revnum_t *min_unpacked_rev,
390 apr_pool_t *scratch_pool);
392 /* Re-read the MIN_UNPACKED_REV member of FS from disk.
393 * Use SCRATCH_POOL for temporary allocations.
396 svn_fs_x__update_min_unpacked_rev(svn_fs_t *fs,
397 apr_pool_t *scratch_pool);
399 /* Atomically update the 'min-unpacked-rev' file in FS to hold the specifed
400 * REVNUM. Perform temporary allocations in SCRATCH_POOL.
403 svn_fs_x__write_min_unpacked_rev(svn_fs_t *fs,
405 apr_pool_t *scratch_pool);
407 /* Set *REV to the value read from the 'current' file. Perform temporary
408 * allocations in SCRATCH_POOL.
411 svn_fs_x__read_current(svn_revnum_t *rev,
413 apr_pool_t *scratch_pool);
415 /* Atomically update the 'current' file to hold the specifed REV.
416 Perform temporary allocations in SCRATCH_POOL. */
418 svn_fs_x__write_current(svn_fs_t *fs,
420 apr_pool_t *scratch_pool);
422 /* Read the file at PATH and return its content in *CONTENT, allocated in
423 * RESULT_POOL. *CONTENT will not be modified unless the whole file was
426 * ESTALE, EIO and ENOENT will not cause this function to return an error
427 * unless LAST_ATTEMPT has been set. If MISSING is not NULL, indicate
428 * missing files (ENOENT) there.
431 svn_fs_x__try_stringbuf_from_file(svn_stringbuf_t **content,
432 svn_boolean_t *missing,
434 svn_boolean_t last_attempt,
435 apr_pool_t *result_pool);
437 /* Fetch the current offset of FILE into *OFFSET_P.
438 * Perform temporary allocations in SCRATCH_POOL. */
440 svn_fs_x__get_file_offset(apr_off_t *offset_p,
442 apr_pool_t *scratch_pool);
444 /* Read the file FNAME and store the contents in *BUF.
445 Allocations are performed in RESULT_POOL. */
447 svn_fs_x__read_content(svn_stringbuf_t **content,
449 apr_pool_t *result_pool);
451 /* Reads a line from STREAM and converts it to a 64 bit integer to be
452 * returned in *RESULT. If we encounter eof, set *HIT_EOF and leave
453 * *RESULT unchanged. If HIT_EOF is NULL, EOF causes an "corrupt FS"
455 * SCRATCH_POOL is used for temporary allocations.
458 svn_fs_x__read_number_from_stream(apr_int64_t *result,
459 svn_boolean_t *hit_eof,
460 svn_stream_t *stream,
461 apr_pool_t *scratch_pool);
463 /* Move a file into place from OLD_FILENAME in the transactions
464 directory to its final location NEW_FILENAME in the repository. On
465 Unix, match the permissions of the new file to the permissions of
466 PERMS_REFERENCE. Temporary allocations are from SCRATCH_POOL.
468 This function almost duplicates svn_io_file_move(), but it tries to
469 guarantee a flush. */
471 svn_fs_x__move_into_place(const char *old_filename,
472 const char *new_filename,
473 const char *perms_reference,
474 apr_pool_t *scratch_pool);