1289177Speter/* util.h --- utility functions for FSFS repo access 2289177Speter * 3289177Speter * ==================================================================== 4289177Speter * Licensed to the Apache Software Foundation (ASF) under one 5289177Speter * or more contributor license agreements. See the NOTICE file 6289177Speter * distributed with this work for additional information 7289177Speter * regarding copyright ownership. The ASF licenses this file 8289177Speter * to you under the Apache License, Version 2.0 (the 9289177Speter * "License"); you may not use this file except in compliance 10289177Speter * with the License. You may obtain a copy of the License at 11289177Speter * 12289177Speter * http://www.apache.org/licenses/LICENSE-2.0 13289177Speter * 14289177Speter * Unless required by applicable law or agreed to in writing, 15289177Speter * software distributed under the License is distributed on an 16289177Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17289177Speter * KIND, either express or implied. See the License for the 18289177Speter * specific language governing permissions and limitations 19289177Speter * under the License. 20289177Speter * ==================================================================== 21289177Speter */ 22289177Speter 23289177Speter#ifndef SVN_LIBSVN_FS__UTIL_H 24289177Speter#define SVN_LIBSVN_FS__UTIL_H 25289177Speter 26289177Speter#include "svn_fs.h" 27289177Speter#include "id.h" 28289177Speter 29289177Speter/* Functions for dealing with recoverable errors on mutable files 30289177Speter * 31289177Speter * Revprops, current, and txn-current files are mutable; that is, they 32289177Speter * change as part of normal fsfs operation, in constrat to revs files, or 33289177Speter * the format file, which are written once at create (or upgrade) time. 34289177Speter * When more than one host writes to the same repository, we will 35289177Speter * sometimes see these recoverable errors when accesssing these files. 36289177Speter * 37289177Speter * These errors all relate to NFS, and thus we only use this retry code if 38289177Speter * ESTALE is defined. 39289177Speter * 40289177Speter ** ESTALE 41289177Speter * 42289177Speter * In NFS v3 and under, the server doesn't track opened files. If you 43289177Speter * unlink(2) or rename(2) a file held open by another process *on the 44289177Speter * same host*, that host's kernel typically renames the file to 45289177Speter * .nfsXXXX and automatically deletes that when it's no longer open, 46289177Speter * but this behavior is not required. 47289177Speter * 48289177Speter * For obvious reasons, this does not work *across hosts*. No one 49289177Speter * knows about the opened file; not the server, and not the deleting 50289177Speter * client. So the file vanishes, and the reader gets stale NFS file 51289177Speter * handle. 52289177Speter * 53289177Speter ** EIO, ENOENT 54289177Speter * 55289177Speter * Some client implementations (at least the 2.6.18.5 kernel that ships 56289177Speter * with Ubuntu Dapper) sometimes give spurious ENOENT (only on open) or 57289177Speter * even EIO errors when trying to read these files that have been renamed 58289177Speter * over on some other host. 59289177Speter * 60289177Speter ** Solution 61289177Speter * 62289177Speter * Try open and read of such files in try_stringbuf_from_file(). Call 63289177Speter * this function within a loop of SVN_FS_FS__RECOVERABLE_RETRY_COUNT 64289177Speter * iterations (though, realistically, the second try will succeed). 65289177Speter */ 66289177Speter 67289177Speter#define SVN_FS_FS__RECOVERABLE_RETRY_COUNT 10 68289177Speter 69289177Speter/* Return TRUE is REV is packed in FS, FALSE otherwise. */ 70289177Spetersvn_boolean_t 71289177Spetersvn_fs_fs__is_packed_rev(svn_fs_t *fs, 72289177Speter svn_revnum_t rev); 73289177Speter 74289177Speter/* Return TRUE is REV's props have been packed in FS, FALSE otherwise. */ 75289177Spetersvn_boolean_t 76289177Spetersvn_fs_fs__is_packed_revprop(svn_fs_t *fs, 77289177Speter svn_revnum_t rev); 78289177Speter 79289177Speter/* Return the first revision in the pack / rev file containing REVISION in 80289177Speter * filesystem FS. For non-packed revs, this will simply be REVISION. */ 81289177Spetersvn_revnum_t 82289177Spetersvn_fs_fs__packed_base_rev(svn_fs_t *fs, 83289177Speter svn_revnum_t revision); 84289177Speter 85289177Speter/* Return the full path of the rev shard directory that will contain 86289177Speter * revision REV in FS. Allocate the result in POOL. 87289177Speter */ 88289177Speterconst char * 89289177Spetersvn_fs_fs__path_rev_shard(svn_fs_t *fs, 90289177Speter svn_revnum_t rev, 91289177Speter apr_pool_t *pool); 92289177Speter 93289177Speter/* Return the full path of the non-packed rev file containing revision REV 94289177Speter * in FS. Allocate the result in POOL. 95289177Speter */ 96289177Speterconst char * 97289177Spetersvn_fs_fs__path_rev(svn_fs_t *fs, 98289177Speter svn_revnum_t rev, 99289177Speter apr_pool_t *pool); 100289177Speter 101289177Speter/* Return the path of the pack-related file that for revision REV in FS. 102289177Speter * KIND specifies the file name base, e.g. "manifest" or "pack". 103289177Speter * The result will be allocated in POOL. 104289177Speter */ 105289177Speterconst char * 106289177Spetersvn_fs_fs__path_rev_packed(svn_fs_t *fs, 107289177Speter svn_revnum_t rev, 108289177Speter const char *kind, 109289177Speter apr_pool_t *pool); 110289177Speter 111289177Speter/* Return the full path of the "txn-current" file in FS. 112289177Speter * The result will be allocated in POOL. 113289177Speter */ 114289177Speterconst char * 115289177Spetersvn_fs_fs__path_txn_current(svn_fs_t *fs, 116289177Speter apr_pool_t *pool); 117289177Speter 118289177Speter/* Return the full path of the "txn-current-lock" file in FS. 119289177Speter * The result will be allocated in POOL. 120289177Speter */ 121289177Speterconst char * 122289177Spetersvn_fs_fs__path_txn_current_lock(svn_fs_t *fs, 123289177Speter apr_pool_t *pool); 124289177Speter 125289177Speter/* Return the full path of the global write lock file in FS. 126289177Speter * The result will be allocated in POOL. 127289177Speter */ 128289177Speterconst char * 129289177Spetersvn_fs_fs__path_lock(svn_fs_t *fs, 130289177Speter apr_pool_t *pool); 131289177Speter 132289177Speter/* Return the full path of the pack operation lock file in FS. 133289177Speter * The result will be allocated in POOL. 134289177Speter */ 135289177Speterconst char * 136289177Spetersvn_fs_fs__path_pack_lock(svn_fs_t *fs, 137289177Speter apr_pool_t *pool); 138289177Speter 139289177Speter/* Return the full path of the revprop generation file in FS. 140289177Speter * Allocate the result in POOL. 141289177Speter */ 142289177Speterconst char * 143289177Spetersvn_fs_fs__path_revprop_generation(svn_fs_t *fs, 144289177Speter apr_pool_t *pool); 145289177Speter 146289177Speter/* Return the full path of the revision properties pack shard directory 147289177Speter * that will contain the packed properties of revision REV in FS. 148289177Speter * Allocate the result in POOL. 149289177Speter */ 150289177Speterconst char * 151289177Spetersvn_fs_fs__path_revprops_pack_shard(svn_fs_t *fs, 152289177Speter svn_revnum_t rev, 153289177Speter apr_pool_t *pool); 154289177Speter 155289177Speter/* Set *PATH to the path of REV in FS, whether in a pack file or not. 156289177Speter Allocate *PATH in POOL. 157289177Speter 158289177Speter Note: If the caller does not have the write lock on FS, then the path is 159289177Speter not guaranteed to be correct or to remain correct after the function 160289177Speter returns, because the revision might become packed before or after this 161289177Speter call. If a file exists at that path, then it is correct; if not, then 162289177Speter the caller should call update_min_unpacked_rev() and re-try once. */ 163289177Speterconst char * 164289177Spetersvn_fs_fs__path_rev_absolute(svn_fs_t *fs, 165289177Speter svn_revnum_t rev, 166289177Speter apr_pool_t *pool); 167289177Speter 168289177Speter/* Return the full path of the revision properties shard directory that 169289177Speter * will contain the properties of revision REV in FS. 170289177Speter * Allocate the result in POOL. 171289177Speter */ 172289177Speterconst char * 173289177Spetersvn_fs_fs__path_revprops_shard(svn_fs_t *fs, 174289177Speter svn_revnum_t rev, 175289177Speter apr_pool_t *pool); 176289177Speter 177289177Speter/* Return the full path of the non-packed revision properties file that 178289177Speter * contains the props for revision REV in FS. Allocate the result in POOL. 179289177Speter */ 180289177Speterconst char * 181289177Spetersvn_fs_fs__path_revprops(svn_fs_t *fs, 182289177Speter svn_revnum_t rev, 183289177Speter apr_pool_t *pool); 184289177Speter 185289177Speter/* Return the path of the file storing the oldest non-packed revision in FS. 186289177Speter * The result will be allocated in POOL. 187289177Speter */ 188289177Speterconst char * 189289177Spetersvn_fs_fs__path_min_unpacked_rev(svn_fs_t *fs, 190289177Speter apr_pool_t *pool); 191289177Speter 192289177Speter/* Return the path of the 'transactions' directory in FS. 193289177Speter * The result will be allocated in POOL. 194289177Speter */ 195289177Speterconst char * 196289177Spetersvn_fs_fs__path_txns_dir(svn_fs_t *fs, 197289177Speter apr_pool_t *pool); 198289177Speter 199289177Speter/* Return the path of the directory containing the transaction TXN_ID in FS. 200289177Speter * The result will be allocated in POOL. 201289177Speter */ 202289177Speterconst char * 203289177Spetersvn_fs_fs__path_txn_dir(svn_fs_t *fs, 204289177Speter const svn_fs_fs__id_part_t *txn_id, 205289177Speter apr_pool_t *pool); 206289177Speter 207289177Speter/* Return the path of the 'txn-protorevs' directory in FS, even if that 208289177Speter * folder may not exist in FS. The result will be allocated in POOL. 209289177Speter */ 210289177Speterconst char * 211289177Spetersvn_fs_fs__path_txn_proto_revs(svn_fs_t *fs, 212289177Speter apr_pool_t *pool); 213289177Speter 214289177Speter/* Return the path of the proto-revision file for transaction TXN_ID in FS. 215289177Speter * The result will be allocated in POOL. 216289177Speter */ 217289177Speterconst char * 218289177Spetersvn_fs_fs__path_txn_proto_rev(svn_fs_t *fs, 219289177Speter const svn_fs_fs__id_part_t *txn_id, 220289177Speter apr_pool_t *pool); 221289177Speter 222289177Speter/* Return the path of the proto-revision lock file for transaction TXN_ID 223289177Speter * in FS. The result will be allocated in POOL. 224289177Speter */ 225289177Speterconst char * 226289177Spetersvn_fs_fs__path_txn_proto_rev_lock(svn_fs_t *fs, 227289177Speter const svn_fs_fs__id_part_t *txn_id, 228289177Speter apr_pool_t *pool); 229289177Speter 230289177Speter/* Return the path of the file containing the in-transaction node revision 231289177Speter * identified by ID in FS. The result will be allocated in POOL. 232289177Speter */ 233289177Speterconst char * 234289177Spetersvn_fs_fs__path_txn_node_rev(svn_fs_t *fs, 235289177Speter const svn_fs_id_t *id, 236289177Speter apr_pool_t *pool); 237289177Speter 238289177Speter/* Return the path of the file containing the in-transaction properties of 239289177Speter * the node identified by ID in FS. The result will be allocated in POOL. 240289177Speter */ 241289177Speterconst char * 242289177Spetersvn_fs_fs__path_txn_node_props(svn_fs_t *fs, 243289177Speter const svn_fs_id_t *id, 244289177Speter apr_pool_t *pool); 245289177Speter 246289177Speter/* Return the path of the file containing the directory entries of the 247289177Speter * in-transaction directory node identified by ID in FS. 248289177Speter * The result will be allocated in POOL. 249289177Speter */ 250289177Speterconst char * 251289177Spetersvn_fs_fs__path_txn_node_children(svn_fs_t *fs, 252289177Speter const svn_fs_id_t *id, 253289177Speter apr_pool_t *pool); 254289177Speter 255289177Speter/* Return the path of the file containing the log-to-phys index for 256289177Speter * the transaction identified by TXN_ID in FS. 257289177Speter * The result will be allocated in POOL. 258289177Speter */ 259289177Speterconst char* 260289177Spetersvn_fs_fs__path_l2p_proto_index(svn_fs_t *fs, 261289177Speter const svn_fs_fs__id_part_t *txn_id, 262289177Speter apr_pool_t *pool); 263289177Speter 264289177Speter/* Return the path of the file containing the phys-to-log index for 265289177Speter * the transaction identified by TXN_ID in FS. 266289177Speter * The result will be allocated in POOL. 267289177Speter */ 268289177Speterconst char* 269289177Spetersvn_fs_fs__path_p2l_proto_index(svn_fs_t *fs, 270289177Speter const svn_fs_fs__id_part_t *txn_id, 271289177Speter apr_pool_t *pool); 272289177Speter 273289177Speter/* Return the path of the file containing item_index counter for 274289177Speter * the transaction identified by TXN_ID in FS. 275289177Speter * The result will be allocated in POOL. 276289177Speter */ 277289177Speterconst char * 278289177Spetersvn_fs_fs__path_txn_item_index(svn_fs_t *fs, 279289177Speter const svn_fs_fs__id_part_t *txn_id, 280289177Speter apr_pool_t *pool); 281289177Speter 282289177Speter/* Return the path of the file containing the node origins cachs for 283289177Speter * the given NODE_ID in FS. The result will be allocated in POOL. 284289177Speter */ 285289177Speterconst char * 286289177Spetersvn_fs_fs__path_node_origin(svn_fs_t *fs, 287289177Speter const svn_fs_fs__id_part_t *node_id, 288289177Speter apr_pool_t *pool); 289289177Speter 290289177Speter/* Set *MIN_UNPACKED_REV to the integer value read from the file returned 291289177Speter * by #svn_fs_fs__path_min_unpacked_rev() for FS. 292289177Speter * Use POOL for temporary allocations. 293289177Speter */ 294289177Spetersvn_error_t * 295289177Spetersvn_fs_fs__read_min_unpacked_rev(svn_revnum_t *min_unpacked_rev, 296289177Speter svn_fs_t *fs, 297289177Speter apr_pool_t *pool); 298289177Speter 299289177Speter/* Check that BUF, a nul-terminated buffer of text from file PATH, 300289177Speter contains only digits at OFFSET and beyond, raising an error if not. 301289177Speter TITLE contains a user-visible description of the file, usually the 302289177Speter short file name. 303289177Speter 304289177Speter Uses POOL for temporary allocation. */ 305289177Spetersvn_error_t * 306289177Spetersvn_fs_fs__check_file_buffer_numeric(const char *buf, 307289177Speter apr_off_t offset, 308289177Speter const char *path, 309289177Speter const char *title, 310289177Speter apr_pool_t *pool); 311289177Speter 312289177Speter/* Re-read the MIN_UNPACKED_REV member of FS from disk. 313289177Speter * Use POOL for temporary allocations. 314289177Speter */ 315289177Spetersvn_error_t * 316289177Spetersvn_fs_fs__update_min_unpacked_rev(svn_fs_t *fs, 317289177Speter apr_pool_t *pool); 318289177Speter 319289177Speter/* Atomically update the 'min-unpacked-rev' file in FS to hold the specifed 320289177Speter * REVNUM. Perform temporary allocations in SCRATCH_POOL. 321289177Speter */ 322289177Spetersvn_error_t * 323289177Spetersvn_fs_fs__write_min_unpacked_rev(svn_fs_t *fs, 324289177Speter svn_revnum_t revnum, 325289177Speter apr_pool_t *scratch_pool); 326289177Speter 327289177Speter/* Set *REV, *NEXT_NODE_ID and *NEXT_COPY_ID to the values read from the 328289177Speter * 'current' file. For new FS formats, which only store the youngest 329289177Speter * revision, set the *NEXT_NODE_ID and *NEXT_COPY_ID to 0. Perform 330289177Speter * temporary allocations in POOL. 331289177Speter */ 332289177Spetersvn_error_t * 333289177Spetersvn_fs_fs__read_current(svn_revnum_t *rev, 334289177Speter apr_uint64_t *next_node_id, 335289177Speter apr_uint64_t *next_copy_id, 336289177Speter svn_fs_t *fs, 337289177Speter apr_pool_t *pool); 338289177Speter 339289177Speter/* Atomically update the 'current' file to hold the specifed REV, 340289177Speter NEXT_NODE_ID, and NEXT_COPY_ID. (The two next-ID parameters are 341289177Speter ignored and may be 0 if the FS format does not use them.) 342289177Speter Perform temporary allocations in POOL. */ 343289177Spetersvn_error_t * 344289177Spetersvn_fs_fs__write_current(svn_fs_t *fs, 345289177Speter svn_revnum_t rev, 346289177Speter apr_uint64_t next_node_id, 347289177Speter apr_uint64_t next_copy_id, 348289177Speter apr_pool_t *pool); 349289177Speter 350289177Speter/* Read the file at PATH and return its content in *CONTENT. *CONTENT will 351289177Speter * not be modified unless the whole file was read successfully. 352289177Speter * 353289177Speter * ESTALE, EIO and ENOENT will not cause this function to return an error 354289177Speter * unless LAST_ATTEMPT has been set. If MISSING is not NULL, indicate 355289177Speter * missing files (ENOENT) there. 356289177Speter * 357289177Speter * Use POOL for allocations. 358289177Speter */ 359289177Spetersvn_error_t * 360289177Spetersvn_fs_fs__try_stringbuf_from_file(svn_stringbuf_t **content, 361289177Speter svn_boolean_t *missing, 362289177Speter const char *path, 363289177Speter svn_boolean_t last_attempt, 364289177Speter apr_pool_t *pool); 365289177Speter 366289177Speter/* Read the file FNAME and store the contents in *BUF. 367289177Speter Allocations are performed in POOL. */ 368289177Spetersvn_error_t * 369289177Spetersvn_fs_fs__read_content(svn_stringbuf_t **content, 370289177Speter const char *fname, 371289177Speter apr_pool_t *pool); 372289177Speter 373289177Speter/* Reads a line from STREAM and converts it to a 64 bit integer to be 374289177Speter * returned in *RESULT. If we encounter eof, set *HIT_EOF and leave 375289177Speter * *RESULT unchanged. If HIT_EOF is NULL, EOF causes an "corrupt FS" 376289177Speter * error return. 377289177Speter * SCRATCH_POOL is used for temporary allocations. 378289177Speter */ 379289177Spetersvn_error_t * 380289177Spetersvn_fs_fs__read_number_from_stream(apr_int64_t *result, 381289177Speter svn_boolean_t *hit_eof, 382289177Speter svn_stream_t *stream, 383289177Speter apr_pool_t *scratch_pool); 384289177Speter 385289177Speter/* Move a file into place from OLD_FILENAME in the transactions 386289177Speter directory to its final location NEW_FILENAME in the repository. On 387289177Speter Unix, match the permissions of the new file to the permissions of 388289177Speter PERMS_REFERENCE. Temporary allocations are from POOL. 389289177Speter 390289177Speter This function almost duplicates svn_io_file_move(), but it tries to 391362181Sdim guarantee a flush if FLUSH_TO_DISK is non-zero. */ 392289177Spetersvn_error_t * 393289177Spetersvn_fs_fs__move_into_place(const char *old_filename, 394289177Speter const char *new_filename, 395289177Speter const char *perms_reference, 396362181Sdim svn_boolean_t flush_to_disk, 397289177Speter apr_pool_t *pool); 398289177Speter 399289177Speter/* Return TRUE, iff FS uses logical addressing. */ 400289177Spetersvn_boolean_t 401289177Spetersvn_fs_fs__use_log_addressing(svn_fs_t *fs); 402289177Speter 403289177Speter#endif 404