1 /* fs.h : interface to Subversion filesystem, private to libsvn_fs
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_FS_H
24 #define SVN_LIBSVN_FS_FS_H
26 #include <apr_pools.h>
28 #include <apr_network_io.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"
41 #endif /* __cplusplus */
44 /*** The filesystem structure. ***/
46 /* Following are defines that specify the textual elements of the
47 native filesystem directories and revision files. */
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
70 /* If you change this, look at tests/svn_test_fs.c(maybe_install_fsfs_conf) */
71 #define PATH_CONFIG "fsfs.conf" /* Configuration */
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 */
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"
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
106 /* The minimum format number that supports svndiff version 1. */
107 #define SVN_FS_FS__MIN_SVNDIFF1_FORMAT 2
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
113 /* The minimum format number that supports the "layout" filesystem
115 #define SVN_FS_FS__MIN_LAYOUT_FORMAT_OPTION_FORMAT 3
117 /* The minimum format number that stores protorevs in a separate directory. */
118 #define SVN_FS_FS__MIN_PROTOREVS_DIR_FORMAT 3
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
123 /* The minimum format number that maintains minfo-here and minfo-count
125 #define SVN_FS_FS__MIN_MERGEINFO_FORMAT 3
127 /* The minimum format number that allows rep sharing. */
128 #define SVN_FS_FS__MIN_REP_SHARING_FORMAT 4
130 /* The minimum format number that supports packed shards. */
131 #define SVN_FS_FS__MIN_PACKED_FORMAT 4
133 /* The minimum format number that stores node kinds in changed-paths lists. */
134 #define SVN_FS_FS__MIN_KIND_IN_CHANGED_FORMAT 4
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
140 /* The 1.7-dev format, never released, that packed revprops into SQLite
142 #define SVN_FS_FS__PACKED_REVPROP_SQLITE_DEV_FORMAT 5
144 /* The minimum format number that supports packed revprops. */
145 #define SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT 6
147 /* The minimum format number that supports a configuration file (fsfs.conf) */
148 #define SVN_FS_FS__MIN_CONFIG_FILE 4
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. */
154 typedef struct fs_fs_shared_txn_data_t
156 /* The next transaction in the list, or NULL if there is no following
158 struct fs_fs_shared_txn_data_t *next;
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];
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;
174 /* The pool in which this object has been allocated; a subpool of the
177 } fs_fs_shared_txn_data_t;
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
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
187 #define SVN_FS_FS__USE_LOCK_MUTEX 0
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. */
193 typedef struct fs_fs_shared_data_t
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;
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;
205 /* A lock for intra-process synchronization when accessing the TXNS list. */
206 svn_mutex__t *txn_list_lock;
208 /* A lock for intra-process synchronization when grabbing the
209 repository write lock. */
210 svn_mutex__t *fs_write_lock;
212 /* A lock for intra-process synchronization when locking the
214 svn_mutex__t *txn_current_lock;
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;
221 /* Data structure for the 1st level DAG node cache. */
222 typedef struct fs_fs_dag_cache_t fs_fs_dag_cache_t;
224 /* Key type for all caches that use revision + offset / counter as key. */
225 typedef struct pair_cache_key_t
227 svn_revnum_t revision;
232 /* Private (non-shared) FSFS-specific data for each svn_fs_t object.
233 Any caches in here may be NULL. */
234 typedef struct fs_fs_data_t
236 /* The format number of this FS. */
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;
242 /* The revision that was youngest, last time we checked. */
243 svn_revnum_t youngest_rev_cache;
245 /* The fsfs.conf file, parsed. Allocated in FS->pool. */
246 svn_config_t *config;
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.) */
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;
256 /* Caches native dag_node_t* instances and acts as a 1st level cache */
257 fs_fs_dag_cache_t *dag_node_cache;
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;
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;
268 /* Fulltext cache; currently only used with memcached. Maps from
269 rep key (revision/offset) to svn_string_t. */
270 svn_cache__t *fulltext_cache;
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;
276 /* Access object to the revprop "generation". Will be NULL until
278 svn_named_atomic__t *revprop_generation;
280 /* Access object to the revprop update timeout. Will be NULL until
282 svn_named_atomic__t *revprop_timeout;
284 /* Revision property cache. Maps from (rev,generation) to apr_hash_t. */
285 svn_cache__t *revprop_cache;
287 /* Node properties cache. Maps from rep key to apr_hash_t. */
288 svn_cache__t *properties_cache;
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;
296 /* Cache for txdelta_window_t objects; the key is (revFilePath, offset) */
297 svn_cache__t *txdelta_window_cache;
299 /* Cache for combined windows as svn_stringbuf_t objects;
300 the key is (revFilePath, offset) */
301 svn_cache__t *combined_window_cache;
303 /* Cache for node_revision_t objects; the key is (revision, id offset) */
304 svn_cache__t *node_revision_cache;
306 /* Cache for change lists as APR arrays of change_t * objects; the key
308 svn_cache__t *changes_cache;
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;
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;
319 /* TRUE while the we hold a lock on the write lock file. */
320 svn_boolean_t has_write_lock;
322 /* If set, there are or have been more than one concurrent transaction */
323 svn_boolean_t concurrent_transactions;
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;
329 /* Data shared between all svn_fs_t objects for a given filesystem. */
330 fs_fs_shared_data_t *shared;
332 /* The sqlite database used for rep caching. */
333 svn_sqlite__db_t *rep_cache_db;
335 /* Thread-safe boolean */
336 svn_atomic_t rep_cache_db_opened;
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;
342 /* Whether rep-sharing is supported by the filesystem
343 * and allowed by the configuration. */
344 svn_boolean_t rep_sharing_allowed;
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;
350 /* Whether packed revprop files shall be compressed. */
351 svn_boolean_t compress_packed_revprops;
353 /* Whether directory nodes shall be deltified just like file nodes. */
354 svn_boolean_t deltify_directories;
356 /* Whether nodes properties shall be deltified. */
357 svn_boolean_t deltify_properties;
359 /* Restart deltification histories after each multiple of this value */
360 apr_int64_t max_deltification_walk;
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;
366 /* Pointer to svn_fs_open. */
367 svn_error_t *(*svn_fs_open_)(svn_fs_t **, const char *, apr_hash_t *,
372 /*** Filesystem Transaction ***/
373 typedef struct transaction_t
375 /* property list (const char * name, svn_string_t * value).
376 may be NULL if there are no properties. */
377 apr_hash_t *proplist;
379 /* node revision id of the root node. */
380 const svn_fs_id_t *root_id;
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;
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;
393 /*** Representation ***/
394 /* If you add fields to this, check to see if you need to change
395 * svn_fs_fs__rep_copy. */
396 typedef struct representation_t
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).
403 If checksum is NULL, then for compatibility behave as though this
404 checksum matches the expected checksum.
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;
413 /* Revision where this representation is located. */
414 svn_revnum_t revision;
416 /* Offset into the revision file where it is located. */
419 /* The size of the representation in bytes as seen in the revision
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;
427 /* Is this representation a transaction? */
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.
435 May be NULL, in which case, it is considered to match other NULL
437 const char *uniquifier;
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. */
444 typedef struct node_revision_t
447 svn_node_kind_t kind;
449 /* The node-id for this node-rev. */
450 const svn_fs_id_t *id;
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;
456 /* If this node-rev is a copy, where was it copied from? */
457 const char *copyfrom_path;
458 svn_revnum_t copyfrom_rev;
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;
465 /* number of predecessors this node revision has (recursively), or
466 -1 if not known (for backward compatibility). */
467 int predecessor_count;
469 /* representation key for this node's properties. may be NULL if
470 there are no properties. */
471 representation_t *prop_rep;
473 /* representation for this node's data. may be NULL if there is
475 representation_t *data_rep;
477 /* path at which this node first came into existence. */
478 const char *created_path;
480 /* is this the unmodified root of a transaction? */
481 svn_boolean_t is_fresh_txn_root;
483 /* Number of nodes with svn:mergeinfo properties that are
484 descendants of this node (including it itself) */
485 apr_int64_t mergeinfo_count;
487 /* Does this node itself have svn:mergeinfo? */
488 svn_boolean_t has_mergeinfo;
494 typedef struct change_t
496 /* Path of the change. */
499 /* Node revision ID of the change. */
500 const svn_fs_id_t *noderev_id;
502 /* The kind of change. */
503 svn_fs_path_change_kind_t kind;
505 /* Text or property mods? */
506 svn_boolean_t text_mod;
507 svn_boolean_t prop_mod;
509 /* Node kind (possibly svn_node_unknown). */
510 svn_node_kind_t node_kind;
512 /* Copyfrom revision and path. */
513 svn_revnum_t copyfrom_rev;
514 const char * copyfrom_path;
521 #endif /* __cplusplus */
523 #endif /* SVN_LIBSVN_FS_FS_H */