fs.h revision 269847
1/* fs.h : interface to Subversion filesystem, private to libsvn_fs 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#ifndef SVN_LIBSVN_FS_FS_H 24#define SVN_LIBSVN_FS_FS_H 25 26#include <apr_pools.h> 27#include <apr_hash.h> 28#include <apr_network_io.h> 29 30#include "svn_fs.h" 31#include "svn_config.h" 32#include "private/svn_atomic.h" 33#include "private/svn_cache.h" 34#include "private/svn_fs_private.h" 35#include "private/svn_sqlite.h" 36#include "private/svn_mutex.h" 37#include "private/svn_named_atomic.h" 38 39#ifdef __cplusplus 40extern "C" { 41#endif /* __cplusplus */ 42 43 44/*** The filesystem structure. ***/ 45 46/* Following are defines that specify the textual elements of the 47 native filesystem directories and revision files. */ 48 49/* Names of special files in the fs_fs filesystem. */ 50#define PATH_FORMAT "format" /* Contains format number */ 51#define PATH_UUID "uuid" /* Contains UUID */ 52#define PATH_CURRENT "current" /* Youngest revision */ 53#define PATH_LOCK_FILE "write-lock" /* Revision lock file */ 54#define PATH_REVS_DIR "revs" /* Directory of revisions */ 55#define PATH_REVPROPS_DIR "revprops" /* Directory of revprops */ 56#define PATH_TXNS_DIR "transactions" /* Directory of transactions */ 57#define PATH_NODE_ORIGINS_DIR "node-origins" /* Lazy node-origin cache */ 58#define PATH_TXN_PROTOS_DIR "txn-protorevs" /* Directory of proto-revs */ 59#define PATH_TXN_CURRENT "txn-current" /* File with next txn key */ 60#define PATH_TXN_CURRENT_LOCK "txn-current-lock" /* Lock for txn-current */ 61#define PATH_LOCKS_DIR "locks" /* Directory of locks */ 62#define PATH_MIN_UNPACKED_REV "min-unpacked-rev" /* Oldest revision which 63 has not been packed. */ 64#define PATH_REVPROP_GENERATION "revprop-generation" 65 /* Current revprop generation*/ 66#define PATH_MANIFEST "manifest" /* Manifest file name */ 67#define PATH_PACKED "pack" /* Packed revision data file */ 68#define PATH_EXT_PACKED_SHARD ".pack" /* Extension for packed 69 shards */ 70/* If you change this, look at tests/svn_test_fs.c(maybe_install_fsfs_conf) */ 71#define PATH_CONFIG "fsfs.conf" /* Configuration */ 72 73/* Names of special files and file extensions for transactions */ 74#define PATH_CHANGES "changes" /* Records changes made so far */ 75#define PATH_TXN_PROPS "props" /* Transaction properties */ 76#define PATH_NEXT_IDS "next-ids" /* Next temporary ID assignments */ 77#define PATH_PREFIX_NODE "node." /* Prefix for node filename */ 78#define PATH_EXT_TXN ".txn" /* Extension of txn dir */ 79#define PATH_EXT_CHILDREN ".children" /* Extension for dir contents */ 80#define PATH_EXT_PROPS ".props" /* Extension for node props */ 81#define PATH_EXT_REV ".rev" /* Extension of protorev file */ 82#define PATH_EXT_REV_LOCK ".rev-lock" /* Extension of protorev lock file */ 83/* Names of files in legacy FS formats */ 84#define PATH_REV "rev" /* Proto rev file */ 85#define PATH_REV_LOCK "rev-lock" /* Proto rev (write) lock file */ 86 87/* Names of sections and options in fsfs.conf. */ 88#define CONFIG_SECTION_CACHES "caches" 89#define CONFIG_OPTION_FAIL_STOP "fail-stop" 90#define CONFIG_SECTION_REP_SHARING "rep-sharing" 91#define CONFIG_OPTION_ENABLE_REP_SHARING "enable-rep-sharing" 92#define CONFIG_SECTION_DELTIFICATION "deltification" 93#define CONFIG_OPTION_ENABLE_DIR_DELTIFICATION "enable-dir-deltification" 94#define CONFIG_OPTION_ENABLE_PROPS_DELTIFICATION "enable-props-deltification" 95#define CONFIG_OPTION_MAX_DELTIFICATION_WALK "max-deltification-walk" 96#define CONFIG_OPTION_MAX_LINEAR_DELTIFICATION "max-linear-deltification" 97#define CONFIG_SECTION_PACKED_REVPROPS "packed-revprops" 98#define CONFIG_OPTION_REVPROP_PACK_SIZE "revprop-pack-size" 99#define CONFIG_OPTION_COMPRESS_PACKED_REVPROPS "compress-packed-revprops" 100 101/* The format number of this filesystem. 102 This is independent of the repository format number, and 103 independent of any other FS back ends. */ 104#define SVN_FS_FS__FORMAT_NUMBER 6 105 106/* The minimum format number that supports svndiff version 1. */ 107#define SVN_FS_FS__MIN_SVNDIFF1_FORMAT 2 108 109/* The minimum format number that supports transaction ID generation 110 using a transaction sequence in the txn-current file. */ 111#define SVN_FS_FS__MIN_TXN_CURRENT_FORMAT 3 112 113/* The minimum format number that supports the "layout" filesystem 114 format option. */ 115#define SVN_FS_FS__MIN_LAYOUT_FORMAT_OPTION_FORMAT 3 116 117/* The minimum format number that stores protorevs in a separate directory. */ 118#define SVN_FS_FS__MIN_PROTOREVS_DIR_FORMAT 3 119 120/* The minimum format number that doesn't keep node and copy ID counters. */ 121#define SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT 3 122 123/* The minimum format number that maintains minfo-here and minfo-count 124 noderev fields. */ 125#define SVN_FS_FS__MIN_MERGEINFO_FORMAT 3 126 127/* The minimum format number that allows rep sharing. */ 128#define SVN_FS_FS__MIN_REP_SHARING_FORMAT 4 129 130/* The minimum format number that supports packed shards. */ 131#define SVN_FS_FS__MIN_PACKED_FORMAT 4 132 133/* The minimum format number that stores node kinds in changed-paths lists. */ 134#define SVN_FS_FS__MIN_KIND_IN_CHANGED_FORMAT 4 135 136/* 1.8 deltification options should work with any FSFS repo but to avoid 137 * issues with very old servers, restrict those options to the 1.6+ format*/ 138#define SVN_FS_FS__MIN_DELTIFICATION_FORMAT 4 139 140/* The 1.7-dev format, never released, that packed revprops into SQLite 141 revprops.db . */ 142#define SVN_FS_FS__PACKED_REVPROP_SQLITE_DEV_FORMAT 5 143 144/* The minimum format number that supports packed revprops. */ 145#define SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT 6 146 147/* The minimum format number that supports a configuration file (fsfs.conf) */ 148#define SVN_FS_FS__MIN_CONFIG_FILE 4 149 150/* Private FSFS-specific data shared between all svn_txn_t objects that 151 relate to a particular transaction in a filesystem (as identified 152 by transaction id and filesystem UUID). Objects of this type are 153 allocated in their own subpool of the common pool. */ 154typedef struct fs_fs_shared_txn_data_t 155{ 156 /* The next transaction in the list, or NULL if there is no following 157 transaction. */ 158 struct fs_fs_shared_txn_data_t *next; 159 160 /* This transaction's ID. For repositories whose format is less 161 than SVN_FS_FS__MIN_TXN_CURRENT_FORMAT, the ID is in the form 162 <rev>-<uniqueifier>, where <uniqueifier> runs from 0-99999 (see 163 create_txn_dir_pre_1_5() in fs_fs.c). For newer repositories, 164 the form is <rev>-<200 digit base 36 number> (see 165 create_txn_dir() in fs_fs.c). */ 166 char txn_id[SVN_FS__TXN_MAX_LEN+1]; 167 168 /* Whether the transaction's prototype revision file is locked for 169 writing by any thread in this process (including the current 170 thread; recursive locks are not permitted). This is effectively 171 a non-recursive mutex. */ 172 svn_boolean_t being_written; 173 174 /* The pool in which this object has been allocated; a subpool of the 175 common pool. */ 176 apr_pool_t *pool; 177} fs_fs_shared_txn_data_t; 178 179/* On most operating systems apr implements file locks per process, not 180 per file. On Windows apr implements the locking as per file handle 181 locks, so we don't have to add our own mutex for just in-process 182 synchronization. */ 183/* Compare ../libsvn_subr/named_atomic.c:USE_THREAD_MUTEX */ 184#if APR_HAS_THREADS && !defined(WIN32) 185#define SVN_FS_FS__USE_LOCK_MUTEX 1 186#else 187#define SVN_FS_FS__USE_LOCK_MUTEX 0 188#endif 189 190/* Private FSFS-specific data shared between all svn_fs_t objects that 191 relate to a particular filesystem, as identified by filesystem UUID. 192 Objects of this type are allocated in the common pool. */ 193typedef struct fs_fs_shared_data_t 194{ 195 /* A list of shared transaction objects for each transaction that is 196 currently active, or NULL if none are. All access to this list, 197 including the contents of the objects stored in it, is synchronised 198 under TXN_LIST_LOCK. */ 199 fs_fs_shared_txn_data_t *txns; 200 201 /* A free transaction object, or NULL if there is no free object. 202 Access to this object is synchronised under TXN_LIST_LOCK. */ 203 fs_fs_shared_txn_data_t *free_txn; 204 205 /* A lock for intra-process synchronization when accessing the TXNS list. */ 206 svn_mutex__t *txn_list_lock; 207 208 /* A lock for intra-process synchronization when grabbing the 209 repository write lock. */ 210 svn_mutex__t *fs_write_lock; 211 212 /* A lock for intra-process synchronization when locking the 213 txn-current file. */ 214 svn_mutex__t *txn_current_lock; 215 216 /* The common pool, under which this object is allocated, subpools 217 of which are used to allocate the transaction objects. */ 218 apr_pool_t *common_pool; 219} fs_fs_shared_data_t; 220 221/* Data structure for the 1st level DAG node cache. */ 222typedef struct fs_fs_dag_cache_t fs_fs_dag_cache_t; 223 224/* Key type for all caches that use revision + offset / counter as key. */ 225typedef struct pair_cache_key_t 226{ 227 svn_revnum_t revision; 228 229 apr_int64_t second; 230} pair_cache_key_t; 231 232/* Private (non-shared) FSFS-specific data for each svn_fs_t object. 233 Any caches in here may be NULL. */ 234typedef struct fs_fs_data_t 235{ 236 /* The format number of this FS. */ 237 int format; 238 /* The maximum number of files to store per directory (for sharded 239 layouts) or zero (for linear layouts). */ 240 int max_files_per_dir; 241 242 /* The revision that was youngest, last time we checked. */ 243 svn_revnum_t youngest_rev_cache; 244 245 /* The fsfs.conf file, parsed. Allocated in FS->pool. */ 246 svn_config_t *config; 247 248 /* Caches of immutable data. (Note that if these are created with 249 svn_cache__create_memcache, the data can be shared between 250 multiple svn_fs_t's for the same filesystem.) */ 251 252 /* A cache of revision root IDs, mapping from (svn_revnum_t *) to 253 (svn_fs_id_t *). (Not threadsafe.) */ 254 svn_cache__t *rev_root_id_cache; 255 256 /* Caches native dag_node_t* instances and acts as a 1st level cache */ 257 fs_fs_dag_cache_t *dag_node_cache; 258 259 /* DAG node cache for immutable nodes. Maps (revision, fspath) 260 to (dag_node_t *). This is the 2nd level cache for DAG nodes. */ 261 svn_cache__t *rev_node_cache; 262 263 /* A cache of the contents of immutable directories; maps from 264 unparsed FS ID to a apr_hash_t * mapping (const char *) dirent 265 names to (svn_fs_dirent_t *). */ 266 svn_cache__t *dir_cache; 267 268 /* Fulltext cache; currently only used with memcached. Maps from 269 rep key (revision/offset) to svn_stringbuf_t. */ 270 svn_cache__t *fulltext_cache; 271 272 /* Access object to the atomics namespace used by revprop caching. 273 Will be NULL until the first access. */ 274 svn_atomic_namespace__t *revprop_namespace; 275 276 /* Access object to the revprop "generation". Will be NULL until 277 the first access. */ 278 svn_named_atomic__t *revprop_generation; 279 280 /* Access object to the revprop update timeout. Will be NULL until 281 the first access. */ 282 svn_named_atomic__t *revprop_timeout; 283 284 /* Revision property cache. Maps from (rev,generation) to apr_hash_t. */ 285 svn_cache__t *revprop_cache; 286 287 /* Node properties cache. Maps from rep key to apr_hash_t. */ 288 svn_cache__t *properties_cache; 289 290 /* Pack manifest cache; a cache mapping (svn_revnum_t) shard number to 291 a manifest; and a manifest is a mapping from (svn_revnum_t) revision 292 number offset within a shard to (apr_off_t) byte-offset in the 293 respective pack file. */ 294 svn_cache__t *packed_offset_cache; 295 296 /* Cache for txdelta_window_t objects; the key is (revFilePath, offset) */ 297 svn_cache__t *txdelta_window_cache; 298 299 /* Cache for combined windows as svn_stringbuf_t objects; 300 the key is (revFilePath, offset) */ 301 svn_cache__t *combined_window_cache; 302 303 /* Cache for node_revision_t objects; the key is (revision, id offset) */ 304 svn_cache__t *node_revision_cache; 305 306 /* Cache for change lists as APR arrays of change_t * objects; the key 307 is the revision */ 308 svn_cache__t *changes_cache; 309 310 /* Cache for svn_mergeinfo_t objects; the key is a combination of 311 revision, inheritance flags and path. */ 312 svn_cache__t *mergeinfo_cache; 313 314 /* Cache for presence of svn_mergeinfo_t on a noderev; the key is a 315 combination of revision, inheritance flags and path; value is "1" 316 if the node has mergeinfo, "0" if it doesn't. */ 317 svn_cache__t *mergeinfo_existence_cache; 318 319 /* TRUE while the we hold a lock on the write lock file. */ 320 svn_boolean_t has_write_lock; 321 322 /* If set, there are or have been more than one concurrent transaction */ 323 svn_boolean_t concurrent_transactions; 324 325 /* Temporary cache for changed directories yet to be committed; maps from 326 unparsed FS ID to ###x. NULL outside transactions. */ 327 svn_cache__t *txn_dir_cache; 328 329 /* Data shared between all svn_fs_t objects for a given filesystem. */ 330 fs_fs_shared_data_t *shared; 331 332 /* The sqlite database used for rep caching. */ 333 svn_sqlite__db_t *rep_cache_db; 334 335 /* Thread-safe boolean */ 336 svn_atomic_t rep_cache_db_opened; 337 338 /* The oldest revision not in a pack file. It also applies to revprops 339 * if revprop packing has been enabled by the FSFS format version. */ 340 svn_revnum_t min_unpacked_rev; 341 342 /* Whether rep-sharing is supported by the filesystem 343 * and allowed by the configuration. */ 344 svn_boolean_t rep_sharing_allowed; 345 346 /* File size limit in bytes up to which multiple revprops shall be packed 347 * into a single file. */ 348 apr_int64_t revprop_pack_size; 349 350 /* Whether packed revprop files shall be compressed. */ 351 svn_boolean_t compress_packed_revprops; 352 353 /* Whether directory nodes shall be deltified just like file nodes. */ 354 svn_boolean_t deltify_directories; 355 356 /* Whether nodes properties shall be deltified. */ 357 svn_boolean_t deltify_properties; 358 359 /* Restart deltification histories after each multiple of this value */ 360 apr_int64_t max_deltification_walk; 361 362 /* Maximum number of length of the linear part at the top of the 363 * deltification history after which skip deltas will be used. */ 364 apr_int64_t max_linear_deltification; 365 366 /* Pointer to svn_fs_open. */ 367 svn_error_t *(*svn_fs_open_)(svn_fs_t **, const char *, apr_hash_t *, 368 apr_pool_t *); 369} fs_fs_data_t; 370 371 372/*** Filesystem Transaction ***/ 373typedef struct transaction_t 374{ 375 /* property list (const char * name, svn_string_t * value). 376 may be NULL if there are no properties. */ 377 apr_hash_t *proplist; 378 379 /* node revision id of the root node. */ 380 const svn_fs_id_t *root_id; 381 382 /* node revision id of the node which is the root of the revision 383 upon which this txn is base. (unfinished only) */ 384 const svn_fs_id_t *base_id; 385 386 /* copies list (const char * copy_ids), or NULL if there have been 387 no copies in this transaction. */ 388 apr_array_header_t *copies; 389 390} transaction_t; 391 392 393/*** Representation ***/ 394/* If you add fields to this, check to see if you need to change 395 * svn_fs_fs__rep_copy. */ 396typedef struct representation_t 397{ 398 /* Checksums for the contents produced by this representation. 399 This checksum is for the contents the rep shows to consumers, 400 regardless of how the rep stores the data under the hood. It is 401 independent of the storage (fulltext, delta, whatever). 402 403 If checksum is NULL, then for compatibility behave as though this 404 checksum matches the expected checksum. 405 406 The md5 checksum is always filled, unless this is rep which was 407 retrieved from the rep-cache. The sha1 checksum is only computed on 408 a write, for use with rep-sharing; it may be read from an existing 409 representation, but otherwise it is NULL. */ 410 svn_checksum_t *md5_checksum; 411 svn_checksum_t *sha1_checksum; 412 413 /* Revision where this representation is located. */ 414 svn_revnum_t revision; 415 416 /* Offset into the revision file where it is located. */ 417 apr_off_t offset; 418 419 /* The size of the representation in bytes as seen in the revision 420 file. */ 421 svn_filesize_t size; 422 423 /* The size of the fulltext of the representation. If this is 0, 424 * the fulltext size is equal to representation size in the rev file, */ 425 svn_filesize_t expanded_size; 426 427 /* Is this representation a transaction? */ 428 const char *txn_id; 429 430 /* For rep-sharing, we need a way of uniquifying node-revs which share the 431 same representation (see svn_fs_fs__noderev_same_rep_key() ). So, we 432 store the original txn of the node rev (not the rep!), along with some 433 intra-node uniqification content. 434 435 May be NULL, in which case, it is considered to match other NULL 436 values.*/ 437 const char *uniquifier; 438} representation_t; 439 440 441/*** Node-Revision ***/ 442/* If you add fields to this, check to see if you need to change 443 * copy_node_revision in dag.c. */ 444typedef struct node_revision_t 445{ 446 /* node kind */ 447 svn_node_kind_t kind; 448 449 /* The node-id for this node-rev. */ 450 const svn_fs_id_t *id; 451 452 /* predecessor node revision id, or NULL if there is no predecessor 453 for this node revision */ 454 const svn_fs_id_t *predecessor_id; 455 456 /* If this node-rev is a copy, where was it copied from? */ 457 const char *copyfrom_path; 458 svn_revnum_t copyfrom_rev; 459 460 /* Helper for history tracing, root of the parent tree from whence 461 this node-rev was copied. */ 462 svn_revnum_t copyroot_rev; 463 const char *copyroot_path; 464 465 /* number of predecessors this node revision has (recursively), or 466 -1 if not known (for backward compatibility). */ 467 int predecessor_count; 468 469 /* representation key for this node's properties. may be NULL if 470 there are no properties. */ 471 representation_t *prop_rep; 472 473 /* representation for this node's data. may be NULL if there is 474 no data. */ 475 representation_t *data_rep; 476 477 /* path at which this node first came into existence. */ 478 const char *created_path; 479 480 /* is this the unmodified root of a transaction? */ 481 svn_boolean_t is_fresh_txn_root; 482 483 /* Number of nodes with svn:mergeinfo properties that are 484 descendants of this node (including it itself) */ 485 apr_int64_t mergeinfo_count; 486 487 /* Does this node itself have svn:mergeinfo? */ 488 svn_boolean_t has_mergeinfo; 489 490} node_revision_t; 491 492 493/*** Change ***/ 494typedef struct change_t 495{ 496 /* Path of the change. */ 497 const char *path; 498 499 /* Node revision ID of the change. */ 500 const svn_fs_id_t *noderev_id; 501 502 /* The kind of change. */ 503 svn_fs_path_change_kind_t kind; 504 505 /* Text or property mods? */ 506 svn_boolean_t text_mod; 507 svn_boolean_t prop_mod; 508 509 /* Node kind (possibly svn_node_unknown). */ 510 svn_node_kind_t node_kind; 511 512 /* Copyfrom revision and path. */ 513 svn_revnum_t copyfrom_rev; 514 const char * copyfrom_path; 515 516} change_t; 517 518 519#ifdef __cplusplus 520} 521#endif /* __cplusplus */ 522 523#endif /* SVN_LIBSVN_FS_FS_H */ 524