summaryrefslogtreecommitdiff
path: root/subversion/libsvn_fs_x/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_fs_x/util.h')
-rw-r--r--subversion/libsvn_fs_x/util.h476
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 0000000..0010723
--- /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