summaryrefslogtreecommitdiff
path: root/subversion/libsvn_fs_fs/fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_fs_fs/fs.c')
-rw-r--r--subversion/libsvn_fs_fs/fs.c151
1 files changed, 119 insertions, 32 deletions
diff --git a/subversion/libsvn_fs_fs/fs.c b/subversion/libsvn_fs_fs/fs.c
index 482878c..d0ba734 100644
--- a/subversion/libsvn_fs_fs/fs.c
+++ b/subversion/libsvn_fs_fs/fs.c
@@ -38,8 +38,10 @@
#include "tree.h"
#include "lock.h"
#include "id.h"
+#include "rep-cache.h"
#include "svn_private_config.h"
#include "private/svn_fs_util.h"
+#include "private/svn_subr_private.h"
#include "../libsvn_fs/fs-loader.h"
@@ -73,7 +75,8 @@ fs_serialized_init(svn_fs_t *fs, apr_pool_t *common_pool, apr_pool_t *pool)
know of a better way of associating such data with the
repository. */
- key = apr_pstrcat(pool, SVN_FSFS_SHARED_USERDATA_PREFIX, ffd->uuid,
+ SVN_ERR_ASSERT(fs->uuid);
+ key = apr_pstrcat(pool, SVN_FSFS_SHARED_USERDATA_PREFIX, fs->uuid,
(char *) NULL);
status = apr_pool_userdata_get(&val, key, common_pool);
if (status)
@@ -85,33 +88,21 @@ fs_serialized_init(svn_fs_t *fs, apr_pool_t *common_pool, apr_pool_t *pool)
ffsd = apr_pcalloc(common_pool, sizeof(*ffsd));
ffsd->common_pool = common_pool;
-#if SVN_FS_FS__USE_LOCK_MUTEX
/* POSIX fcntl locks are per-process, so we need a mutex for
intra-process synchronization when grabbing the repository write
lock. */
- status = apr_thread_mutex_create(&ffsd->fs_write_lock,
- APR_THREAD_MUTEX_DEFAULT, common_pool);
- if (status)
- return svn_error_wrap_apr(status,
- _("Can't create FSFS write-lock mutex"));
+ SVN_ERR(svn_mutex__init(&ffsd->fs_write_lock,
+ SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
/* ... not to mention locking the txn-current file. */
- status = apr_thread_mutex_create(&ffsd->txn_current_lock,
- APR_THREAD_MUTEX_DEFAULT, common_pool);
- if (status)
- return svn_error_wrap_apr(status,
- _("Can't create FSFS txn-current mutex"));
-#endif
-#if APR_HAS_THREADS
- /* We also need a mutex for synchronising access to the active
- transaction list and free transaction pointer. */
- status = apr_thread_mutex_create(&ffsd->txn_list_lock,
- APR_THREAD_MUTEX_DEFAULT, common_pool);
- if (status)
- return svn_error_wrap_apr(status,
- _("Can't create FSFS txn list mutex"));
-#endif
+ SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock,
+ SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
+ /* We also need a mutex for synchronizing access to the active
+ transaction list and free transaction pointer. This one is
+ enabled unconditionally. */
+ SVN_ERR(svn_mutex__init(&ffsd->txn_list_lock,
+ TRUE, common_pool));
key = apr_pstrdup(common_pool, key);
status = apr_pool_userdata_set(ffsd, key, NULL, common_pool);
@@ -137,6 +128,46 @@ fs_set_errcall(svn_fs_t *fs,
return SVN_NO_ERROR;
}
+struct fs_freeze_baton_t {
+ svn_fs_t *fs;
+ svn_fs_freeze_func_t freeze_func;
+ void *freeze_baton;
+};
+
+static svn_error_t *
+fs_freeze_body(void *baton,
+ apr_pool_t *pool)
+{
+ struct fs_freeze_baton_t *b = baton;
+ svn_boolean_t exists;
+
+ SVN_ERR(svn_fs_fs__exists_rep_cache(&exists, b->fs, pool));
+ if (exists)
+ SVN_ERR(svn_fs_fs__lock_rep_cache(b->fs, pool));
+
+ SVN_ERR(b->freeze_func(b->freeze_baton, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+fs_freeze(svn_fs_t *fs,
+ svn_fs_freeze_func_t freeze_func,
+ void *freeze_baton,
+ apr_pool_t *pool)
+{
+ struct fs_freeze_baton_t b;
+
+ b.fs = fs;
+ b.freeze_func = freeze_func;
+ b.freeze_baton = freeze_baton;
+
+ SVN_ERR(svn_fs__check_fs(fs, TRUE));
+ SVN_ERR(svn_fs_fs__with_write_lock(fs, fs_freeze_body, &b, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* The vtable associated with a specific open filesystem. */
@@ -145,7 +176,6 @@ static fs_vtable_t fs_vtable = {
svn_fs_fs__revision_prop,
svn_fs_fs__revision_proplist,
svn_fs_fs__change_rev_prop,
- svn_fs_fs__get_uuid,
svn_fs_fs__set_uuid,
svn_fs_fs__revision_root,
svn_fs_fs__begin_txn,
@@ -158,7 +188,9 @@ static fs_vtable_t fs_vtable = {
svn_fs_fs__unlock,
svn_fs_fs__get_lock,
svn_fs_fs__get_locks,
- fs_set_errcall,
+ svn_fs_fs__verify_root,
+ fs_freeze,
+ fs_set_errcall
};
@@ -255,19 +287,40 @@ fs_upgrade(svn_fs_t *fs, const char *path, apr_pool_t *pool,
}
static svn_error_t *
+fs_verify(svn_fs_t *fs, const char *path,
+ svn_revnum_t start,
+ svn_revnum_t end,
+ svn_fs_progress_notify_func_t notify_func,
+ void *notify_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool,
+ apr_pool_t *common_pool)
+{
+ SVN_ERR(svn_fs__check_fs(fs, FALSE));
+ SVN_ERR(initialize_fs_struct(fs));
+ SVN_ERR(svn_fs_fs__open(fs, path, pool));
+ SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
+ SVN_ERR(fs_serialized_init(fs, common_pool, pool));
+ return svn_fs_fs__verify(fs, start, end, notify_func, notify_baton,
+ cancel_func, cancel_baton, pool);
+}
+
+static svn_error_t *
fs_pack(svn_fs_t *fs,
const char *path,
svn_fs_pack_notify_t notify_func,
void *notify_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
- apr_pool_t *pool)
+ apr_pool_t *pool,
+ apr_pool_t *common_pool)
{
SVN_ERR(svn_fs__check_fs(fs, FALSE));
SVN_ERR(initialize_fs_struct(fs));
SVN_ERR(svn_fs_fs__open(fs, path, pool));
SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
- SVN_ERR(fs_serialized_init(fs, pool, pool));
+ SVN_ERR(fs_serialized_init(fs, common_pool, pool));
return svn_fs_fs__pack(fs, notify_func, notify_baton,
cancel_func, cancel_baton, pool);
}
@@ -276,16 +329,36 @@ fs_pack(svn_fs_t *fs,
/* This implements the fs_library_vtable_t.hotcopy() API. Copy a
- possibly live Subversion filesystem from SRC_PATH to DEST_PATH.
+ possibly live Subversion filesystem SRC_FS from SRC_PATH to a
+ DST_FS at DEST_PATH. If INCREMENTAL is TRUE, make an effort not to
+ re-copy data which already exists in DST_FS.
The CLEAN_LOGS argument is ignored and included for Subversion
1.0.x compatibility. Perform all temporary allocations in POOL. */
static svn_error_t *
-fs_hotcopy(const char *src_path,
- const char *dest_path,
+fs_hotcopy(svn_fs_t *src_fs,
+ svn_fs_t *dst_fs,
+ const char *src_path,
+ const char *dst_path,
svn_boolean_t clean_logs,
+ svn_boolean_t incremental,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
apr_pool_t *pool)
{
- return svn_fs_fs__hotcopy(src_path, dest_path, pool);
+ SVN_ERR(svn_fs__check_fs(src_fs, FALSE));
+ SVN_ERR(initialize_fs_struct(src_fs));
+ SVN_ERR(svn_fs_fs__open(src_fs, src_path, pool));
+ SVN_ERR(svn_fs_fs__initialize_caches(src_fs, pool));
+ SVN_ERR(fs_serialized_init(src_fs, pool, pool));
+
+ SVN_ERR(svn_fs__check_fs(dst_fs, FALSE));
+ SVN_ERR(initialize_fs_struct(dst_fs));
+ /* In INCREMENTAL mode, svn_fs_fs__hotcopy() will open DST_FS.
+ Otherwise, it's not an FS yet --- possibly just an empty dir --- so
+ can't be opened.
+ */
+ return svn_fs_fs__hotcopy(src_fs, dst_fs, src_path, dst_path,
+ incremental, cancel_func, cancel_baton, pool);
}
@@ -331,6 +404,17 @@ fs_get_description(void)
return _("Module for working with a plain file (FSFS) repository.");
}
+static svn_error_t *
+fs_set_svn_fs_open(svn_fs_t *fs,
+ svn_error_t *(*svn_fs_open_)(svn_fs_t **,
+ const char *,
+ apr_hash_t *,
+ apr_pool_t *))
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+ ffd->svn_fs_open_ = svn_fs_open_;
+ return SVN_NO_ERROR;
+}
/* Base FS library vtable, used by the FS loader library. */
@@ -341,12 +425,15 @@ static fs_library_vtable_t library_vtable = {
fs_open,
fs_open_for_recovery,
fs_upgrade,
+ fs_verify,
fs_delete_fs,
fs_hotcopy,
fs_get_description,
svn_fs_fs__recover,
fs_pack,
- fs_logfiles
+ fs_logfiles,
+ NULL /* parse_id */,
+ fs_set_svn_fs_open
};
svn_error_t *
@@ -366,7 +453,7 @@ svn_fs_fs__init(const svn_version_t *loader_version,
return svn_error_createf(SVN_ERR_VERSION_MISMATCH, NULL,
_("Unsupported FS loader version (%d) for fsfs"),
loader_version->major);
- SVN_ERR(svn_ver_check_list(fs_version(), checklist));
+ SVN_ERR(svn_ver_check_list2(fs_version(), checklist, svn_ver_equal));
*vtable = &library_vtable;
return SVN_NO_ERROR;