diff options
Diffstat (limited to 'subversion/libsvn_fs_x/util.h')
| -rw-r--r-- | subversion/libsvn_fs_x/util.h | 476 | 
1 files changed, 476 insertions, 0 deletions
| diff --git a/subversion/libsvn_fs_x/util.h b/subversion/libsvn_fs_x/util.h new file mode 100644 index 000000000000..0010723ed4bf --- /dev/null +++ b/subversion/libsvn_fs_x/util.h @@ -0,0 +1,476 @@ +/* util.h --- utility functions for FSX repo access + * + * ==================================================================== + *    Licensed to the Apache Software Foundation (ASF) under one + *    or more contributor license agreements.  See the NOTICE file + *    distributed with this work for additional information + *    regarding copyright ownership.  The ASF licenses this file + *    to you under the Apache License, Version 2.0 (the + *    "License"); you may not use this file except in compliance + *    with the License.  You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + *    Unless required by applicable law or agreed to in writing, + *    software distributed under the License is distributed on an + *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + *    KIND, either express or implied.  See the License for the + *    specific language governing permissions and limitations + *    under the License. + * ==================================================================== + */ + +#ifndef SVN_LIBSVN_FS__UTIL_H +#define SVN_LIBSVN_FS__UTIL_H + +#include "svn_fs.h" +#include "id.h" + +/* Functions for dealing with recoverable errors on mutable files + * + * Revprops, current, and txn-current files are mutable; that is, they + * change as part of normal fsx operation, in constrat to revs files, or + * the format file, which are written once at create (or upgrade) time. + * When more than one host writes to the same repository, we will + * sometimes see these recoverable errors when accesssing these files. + * + * These errors all relate to NFS, and thus we only use this retry code if + * ESTALE is defined. + * + ** ESTALE + * + * In NFS v3 and under, the server doesn't track opened files.  If you + * unlink(2) or rename(2) a file held open by another process *on the + * same host*, that host's kernel typically renames the file to + * .nfsXXXX and automatically deletes that when it's no longer open, + * but this behavior is not required. + * + * For obvious reasons, this does not work *across hosts*.  No one + * knows about the opened file; not the server, and not the deleting + * client.  So the file vanishes, and the reader gets stale NFS file + * handle. + * + ** EIO, ENOENT + * + * Some client implementations (at least the 2.6.18.5 kernel that ships + * with Ubuntu Dapper) sometimes give spurious ENOENT (only on open) or + * even EIO errors when trying to read these files that have been renamed + * over on some other host. + * + ** Solution + * + * Try open and read of such files in try_stringbuf_from_file().  Call + * this function within a loop of SVN_FS_X__RECOVERABLE_RETRY_COUNT + * iterations (though, realistically, the second try will succeed). + */ + +#define SVN_FS_X__RECOVERABLE_RETRY_COUNT 10 + +/* Pathname helper functions */ + +/* Return TRUE is REV is packed in FS, FALSE otherwise. */ +svn_boolean_t +svn_fs_x__is_packed_rev(svn_fs_t *fs, +                        svn_revnum_t rev); + +/* Return TRUE is REV is packed in FS, FALSE otherwise. */ +svn_boolean_t +svn_fs_x__is_packed_revprop(svn_fs_t *fs, +                            svn_revnum_t rev); + +/* Return the first revision in the pack / rev file containing REV in + * filesystem FS.  For non-packed revs, this will simply be REV. */ +svn_revnum_t +svn_fs_x__packed_base_rev(svn_fs_t *fs, +                          svn_revnum_t rev); + +/* Return the number of revisions in the pack / rev file in FS that contains + * revision REV. */ +svn_revnum_t +svn_fs_x__pack_size(svn_fs_t *fs, svn_revnum_t rev); + +/* Return the full path of the "format" file in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_format(svn_fs_t *fs, +                      apr_pool_t *result_pool); + +/* Return the path to the 'current' file in FS. +   Perform allocation in RESULT_POOL. */ +const char * +svn_fs_x__path_current(svn_fs_t *fs, +                       apr_pool_t *result_pool); + +/* Return the full path of the "uuid" file in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_uuid(svn_fs_t *fs, +                    apr_pool_t *result_pool); + +/* Return the full path of the "txn-current" file in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_current(svn_fs_t *fs, +                           apr_pool_t *result_pool); + +/* Return the full path of the "txn-current-lock" file in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_current_lock(svn_fs_t *fs, +                                apr_pool_t *result_pool); + +/* Return the full path of the global write lock file in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_lock(svn_fs_t *fs, +                    apr_pool_t *result_pool); + +/* Return the full path of the pack operation lock file in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_pack_lock(svn_fs_t *fs, +                         apr_pool_t *result_pool); + +/* Return the full path of the revprop generation file in FS. + * Allocate the result in RESULT_POOL. + */ +const char * +svn_fs_x__path_revprop_generation(svn_fs_t *fs, +                                  apr_pool_t *result_pool); + +/* Return the path of the pack-related file that for revision REV in FS. + * KIND specifies the file name base, e.g. "pack". + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_rev_packed(svn_fs_t *fs, +                          svn_revnum_t rev, +                          const char *kind, +                          apr_pool_t *result_pool); + +/* Return the full path of the rev shard directory that will contain + * revision REV in FS.  Allocate the result in RESULT_POOL. + */ +const char * +svn_fs_x__path_rev_shard(svn_fs_t *fs, +                         svn_revnum_t rev, +                         apr_pool_t *result_pool); + +/* Return the full path of the non-packed rev file containing revision REV + * in FS.  Allocate the result in RESULT_POOL. + */ +const char * +svn_fs_x__path_rev(svn_fs_t *fs, +                   svn_revnum_t rev, +                   apr_pool_t *result_pool); + +/* Set *PATH to the path of REV in FS, whether in a pack file or not. +   Allocate *PATH in RESULT_POOL. + +   Note: If the caller does not have the write lock on FS, then the path is +   not guaranteed to be correct or to remain correct after the function +   returns, because the revision might become packed before or after this +   call.  If a file exists at that path, then it is correct; if not, then +   the caller should call update_min_unpacked_rev() and re-try once. */ +const char * +svn_fs_x__path_rev_absolute(svn_fs_t *fs, +                            svn_revnum_t rev, +                            apr_pool_t *result_pool); + +/* Return the full path of the revision properties shard directory that + * will contain the properties of revision REV in FS. + * Allocate the result in RESULT_POOL. + */ +const char * +svn_fs_x__path_revprops_shard(svn_fs_t *fs, +                              svn_revnum_t rev, +                              apr_pool_t *result_pool); + +/* Return the full path of the revision properties pack shard directory + * that will contain the packed properties of revision REV in FS. + * Allocate the result in RESULT_POOL. + */ +const char * +svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs, +                                   svn_revnum_t rev, +                                   apr_pool_t *result_pool); + +/* Return the full path of the non-packed revision properties file that + * contains the props for revision REV in FS. + * Allocate the result in RESULT_POOL. + */ +const char * +svn_fs_x__path_revprops(svn_fs_t *fs, +                        svn_revnum_t rev, +                        apr_pool_t *result_pool); + +/* Convert the TXN_ID into a string, allocated from RESULT_POOL. + */ +const char * +svn_fs_x__txn_name(svn_fs_x__txn_id_t txn_id, +                   apr_pool_t *result_pool); + +/* Convert TXN_NAME into an ID and return it in *TXN_ID. */ +svn_error_t * +svn_fs_x__txn_by_name(svn_fs_x__txn_id_t *txn_id, +                      const char *txn_name); + +/* Return the path of the directory containing the transaction TXN_ID in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_dir(svn_fs_t *fs, +                       svn_fs_x__txn_id_t txn_id, +                       apr_pool_t *result_pool); + +/* Return the path of the 'transactions' directory in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txns_dir(svn_fs_t *fs, +                        apr_pool_t *result_pool); + +/* Return the name of the sha1->rep mapping file in transaction TXN_ID + * within FS for the given SHA1 checksum.  Use POOL for allocations. + */ +const char * +svn_fs_x__path_txn_sha1(svn_fs_t *fs, +                        svn_fs_x__txn_id_t txn_id, +                        const unsigned char *sha1, +                        apr_pool_t *pool); + +/* Return the path of the 'txn-protorevs' directory in FS, even if that + * folder may not exist in FS.  The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_proto_revs(svn_fs_t *fs, +                              apr_pool_t *result_pool); + +/* Return the path of the changes file for transaction TXN_ID in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_changes(svn_fs_t *fs, +                           svn_fs_x__txn_id_t txn_id, +                           apr_pool_t *result_pool); + +/* Return the path of the file containing the log-to-phys index for + * the transaction identified by TXN_ID in FS. + * The result will be allocated in RESULT_POOL. + */ +const char* +svn_fs_x__path_l2p_proto_index(svn_fs_t *fs, +                               svn_fs_x__txn_id_t txn_id, +                               apr_pool_t *result_pool); + +/* Return the path of the file containing the phys-to-log index for + * the transaction identified by TXN_ID in FS. + * The result will be allocated in RESULT_POOL. + */ +const char* +svn_fs_x__path_p2l_proto_index(svn_fs_t *fs, +                               svn_fs_x__txn_id_t txn_id, +                               apr_pool_t *result_pool); + +/* Return the path of the file containing the transaction properties for + * the transaction identified by TXN_ID in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_props(svn_fs_t *fs, +                         svn_fs_x__txn_id_t txn_id, +                         apr_pool_t *result_pool); + +/* Return the path of the file containing the "final" transaction + * properties for the transaction identified by TXN_ID in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_props_final(svn_fs_t *fs, +                               svn_fs_x__txn_id_t txn_id, +                               apr_pool_t *result_pool); + +/* Return the path of the file containing the node and copy ID counters for + * the transaction identified by TXN_ID in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_next_ids(svn_fs_t *fs, +                            svn_fs_x__txn_id_t txn_id, +                            apr_pool_t *result_pool); + +/* Return the path of the file storing the oldest non-packed revision in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_min_unpacked_rev(svn_fs_t *fs, +                                apr_pool_t *result_pool); + +/* Return the path of the file containing item_index counter for + * the transaction identified by TXN_ID in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_item_index(svn_fs_t *fs, +                              svn_fs_x__txn_id_t txn_id, +                              apr_pool_t *result_pool); + +/* Return the path of the proto-revision file for transaction TXN_ID in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_proto_rev(svn_fs_t *fs, +                             svn_fs_x__txn_id_t txn_id, +                             apr_pool_t *result_pool); + +/* Return the path of the proto-revision lock file for transaction TXN_ID + * in FS.  The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_proto_rev_lock(svn_fs_t *fs, +                                  svn_fs_x__txn_id_t txn_id, +                                  apr_pool_t *result_pool); + +/* Return the path of the file containing the in-transaction node revision + * identified by ID in FS. + * The result will be allocated in RESULT_POOL, temporaries in SCRATCH_POOL. + */ +const char * +svn_fs_x__path_txn_node_rev(svn_fs_t *fs, +                            const svn_fs_x__id_t *id, +                            apr_pool_t *result_pool, +                            apr_pool_t *scratch_pool); + +/* Return the path of the file containing the in-transaction properties of + * the node identified by ID in FS. + * The result will be allocated in RESULT_POOL, temporaries in SCRATCH_POOL. + */ +const char * +svn_fs_x__path_txn_node_props(svn_fs_t *fs, +                              const svn_fs_x__id_t *id, +                              apr_pool_t *result_pool, +                              apr_pool_t *scratch_pool); + +/* Return the path of the file containing the directory entries of the + * in-transaction directory node identified by ID in FS. + * The result will be allocated in RESULT_POOL, temporaries in SCRATCH_POOL. + */ +const char * +svn_fs_x__path_txn_node_children(svn_fs_t *fs, +                                 const svn_fs_x__id_t *id, +                                 apr_pool_t *result_pool, +                                 apr_pool_t *scratch_pool); + +/* Check that BUF, a nul-terminated buffer of text from file PATH, +   contains only digits at OFFSET and beyond, raising an error if not. +   TITLE contains a user-visible description of the file, usually the +   short file name. + +   Uses SCRATCH_POOL for temporary allocation. */ +svn_error_t * +svn_fs_x__check_file_buffer_numeric(const char *buf, +                                    apr_off_t offset, +                                    const char *path, +                                    const char *title, +                                    apr_pool_t *scratch_pool); + +/* Set *MIN_UNPACKED_REV to the integer value read from the file returned + * by #svn_fs_fs__path_min_unpacked_rev() for FS. + * Use SCRATCH_POOL for temporary allocations. + */ +svn_error_t * +svn_fs_x__read_min_unpacked_rev(svn_revnum_t *min_unpacked_rev, +                                svn_fs_t *fs, +                                apr_pool_t *scratch_pool); + +/* Re-read the MIN_UNPACKED_REV member of FS from disk. + * Use SCRATCH_POOL for temporary allocations. + */ +svn_error_t * +svn_fs_x__update_min_unpacked_rev(svn_fs_t *fs, +                                  apr_pool_t *scratch_pool); + +/* Atomically update the 'min-unpacked-rev' file in FS to hold the specifed + * REVNUM.  Perform temporary allocations in SCRATCH_POOL. + */ +svn_error_t * +svn_fs_x__write_min_unpacked_rev(svn_fs_t *fs, +                                 svn_revnum_t revnum, +                                 apr_pool_t *scratch_pool); + +/* Set *REV to the value read from the 'current' file.  Perform temporary + * allocations in SCRATCH_POOL. + */ +svn_error_t * +svn_fs_x__read_current(svn_revnum_t *rev, +                       svn_fs_t *fs, +                       apr_pool_t *scratch_pool); + +/* Atomically update the 'current' file to hold the specifed REV. +   Perform temporary allocations in SCRATCH_POOL. */ +svn_error_t * +svn_fs_x__write_current(svn_fs_t *fs, +                        svn_revnum_t rev, +                        apr_pool_t *scratch_pool); + +/* Read the file at PATH and return its content in *CONTENT, allocated in + * RESULT_POOL.  *CONTENT will not be modified unless the whole file was + * read successfully. + * + * ESTALE, EIO and ENOENT will not cause this function to return an error + * unless LAST_ATTEMPT has been set.  If MISSING is not NULL, indicate + * missing files (ENOENT) there. + */ +svn_error_t * +svn_fs_x__try_stringbuf_from_file(svn_stringbuf_t **content, +                                  svn_boolean_t *missing, +                                  const char *path, +                                  svn_boolean_t last_attempt, +                                  apr_pool_t *result_pool); + +/* Fetch the current offset of FILE into *OFFSET_P. + * Perform temporary allocations in SCRATCH_POOL. */ +svn_error_t * +svn_fs_x__get_file_offset(apr_off_t *offset_p, +                          apr_file_t *file, +                          apr_pool_t *scratch_pool); + +/* Read the file FNAME and store the contents in *BUF. +   Allocations are performed in RESULT_POOL. */ +svn_error_t * +svn_fs_x__read_content(svn_stringbuf_t **content, +                       const char *fname, +                       apr_pool_t *result_pool); + +/* Reads a line from STREAM and converts it to a 64 bit integer to be + * returned in *RESULT.  If we encounter eof, set *HIT_EOF and leave + * *RESULT unchanged.  If HIT_EOF is NULL, EOF causes an "corrupt FS" + * error return. + * SCRATCH_POOL is used for temporary allocations. + */ +svn_error_t * +svn_fs_x__read_number_from_stream(apr_int64_t *result, +                                  svn_boolean_t *hit_eof, +                                  svn_stream_t *stream, +                                  apr_pool_t *scratch_pool); + +/* Move a file into place from OLD_FILENAME in the transactions +   directory to its final location NEW_FILENAME in the repository.  On +   Unix, match the permissions of the new file to the permissions of +   PERMS_REFERENCE.  Temporary allocations are from SCRATCH_POOL. + +   This function almost duplicates svn_io_file_move(), but it tries to +   guarantee a flush. */ +svn_error_t * +svn_fs_x__move_into_place(const char *old_filename, +                          const char *new_filename, +                          const char *perms_reference, +                          apr_pool_t *scratch_pool); + +#endif | 
