You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/05/26 10:57:34 UTC
svn commit: r1681721 [1/3] - in /subversion/branches/move-tracking-2: ./
subversion/ subversion/include/ subversion/include/private/
subversion/libsvn_client/ subversion/libsvn_fs_fs/ subversion/libsvn_fs_x/
subversion/libsvn_subr/ subversion/libsvn_wc...
Author: julianfoad
Date: Tue May 26 08:57:33 2015
New Revision: 1681721
URL: http://svn.apache.org/r1681721
Log:
On the 'move-tracking-2' branch: catch up to trunk@1681720.
Removed:
subversion/branches/move-tracking-2/subversion/include/private/svn_pseudo_md5.h
subversion/branches/move-tracking-2/subversion/libsvn_subr/pseudo_md5.c
Modified:
subversion/branches/move-tracking-2/ (props changed)
subversion/branches/move-tracking-2/subversion/ (props changed)
subversion/branches/move-tracking-2/subversion/include/private/svn_cmdline_private.h
subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h
subversion/branches/move-tracking-2/subversion/include/svn_error.h
subversion/branches/move-tracking-2/subversion/include/svn_fs.h
subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/cached_data.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.h
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/recovery.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache-db.sql
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.h
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rev_file.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/structure
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.h
subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_x/ (props changed)
subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache-db.sql
subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.c
subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.h
subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/checksum.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/cmdline.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/config_file.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.h
subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c
subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c
subversion/branches/move-tracking-2/subversion/svn/svn.c
subversion/branches/move-tracking-2/subversion/svnbench/svnbench.c
subversion/branches/move-tracking-2/subversion/svnmucc/svnmucc.c
subversion/branches/move-tracking-2/subversion/svnrdump/svnrdump.c
subversion/branches/move-tracking-2/subversion/svnsync/svnsync.c
subversion/branches/move-tracking-2/subversion/tests/cmdline/basic_tests.py
subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn--help_stderr (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn--version--quiet_stderr (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn--version--quiet_stdout (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn--version--verbose_stderr (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn--version--verbose_stdout (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn--version_stderr (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn--version_stdout (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_help--version_stderr (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_help--version_stdout (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_help_bogus-cmd_stderr (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_help_bogus-cmd_stdout (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stderr (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout (contents, props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_help_stderr (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_stderr (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/getopt_tests_data/svn_stdout (props changed)
subversion/branches/move-tracking-2/subversion/tests/cmdline/lock_tests.py
subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmucc_tests.py
subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/ (props changed)
subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-sequential-test.c
subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c
subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/cache-test.c
subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/checksum-test.c
subversion/branches/move-tracking-2/subversion/tests/svn_test_fs.c
subversion/branches/move-tracking-2/subversion/tests/svn_test_main.c
subversion/branches/move-tracking-2/tools/ (props changed)
subversion/branches/move-tracking-2/tools/client-side/bash_completion
Propchange: subversion/branches/move-tracking-2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 26 08:57:33 2015
@@ -1,5 +1,7 @@
+/subversion/branches/1.10-cache-improvements:1675666-1677522,1679679,1679681,1679859
/subversion/branches/1.5.x-r30215:870312
/subversion/branches/1.7.x-fs-verify:1146708,1161180
+/subversion/branches/1.9-cache-improvements:1678948-1679863
/subversion/branches/10Gb:1388102,1388163-1388190,1388195,1388202,1388205,1388211,1388276,1388362,1388375,1388394,1388636,1388639-1388640,1388643-1388644,1388654,1388720,1388789,1388795,1388801,1388805,1388807,1388810,1388816,1389044,1389276,1389289,1389662,1389867,1390017,1390209,1390216,1390407,1390409,1390414,1390419,1390955
/subversion/branches/atomic-revprop:965046-1000689
/subversion/branches/authzperf:1615360
@@ -88,4 +90,4 @@
/subversion/branches/verify-at-commit:1462039-1462408
/subversion/branches/verify-keep-going:1439280-1546110
/subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1606692-1678693
+/subversion/trunk:1606692-1681720
Propchange: subversion/branches/move-tracking-2/subversion/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 26 08:57:33 2015
@@ -82,4 +82,4 @@
/subversion/branches/verify-at-commit/subversion:1462039-1462408
/subversion/branches/verify-keep-going/subversion:1439280-1546110
/subversion/branches/wc-collate-path/subversion:1402685-1480384
-/subversion/trunk/subversion:1606692-1678693
+/subversion/trunk/subversion:1606692-1681720
Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_cmdline_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_cmdline_private.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_cmdline_private.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_cmdline_private.h Tue May 26 08:57:33 2015
@@ -88,7 +88,7 @@ typedef struct svn_cmdline__config_argum
* containing svn_cmdline__config_argument_t* elements, allocating the option
* data in @a pool
*
- * [Since 1.9/1.10:] If the file, section, or option value is not recognized,
+ * [Since 1.9:] If the file, section, or option value is not recognized,
* warn to @c stderr, using @a prefix as in svn_handle_warning2().
*
* @since New in 1.7.
@@ -224,6 +224,20 @@ svn_boolean_t
svn_cmdline__be_interactive(svn_boolean_t non_interactive,
svn_boolean_t force_interactive);
+/* Parses the argument value of '--trust-server-cert-failures' OPT_ARG into
+ * the expected booleans for passing to svn_cmdline_create_auth_baton2()
+ *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_cmdline__parse_trust_options(
+ svn_boolean_t *trust_server_cert_unknown_ca,
+ svn_boolean_t *trust_server_cert_cn_mismatch,
+ svn_boolean_t *trust_server_cert_expired,
+ svn_boolean_t *trust_server_cert_not_yet_valid,
+ svn_boolean_t *trust_server_cert_other_failure,
+ const char *opt_arg,
+ apr_pool_t *scratch_pool);
#ifdef __cplusplus
}
Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h Tue May 26 08:57:33 2015
@@ -83,6 +83,8 @@ svn_wc__get_file_external_editor(const s
const char *recorded_url,
const svn_opt_revision_t *recorded_peg_rev,
const svn_opt_revision_t *recorded_rev,
+ svn_wc_conflict_resolver_func2_t conflict_func,
+ void *conflict_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
Modified: subversion/branches/move-tracking-2/subversion/include/svn_error.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_error.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_error.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_error.h Tue May 26 08:57:33 2015
@@ -165,18 +165,16 @@ svn_error_wrap_apr(apr_status_t status,
...)
__attribute__((format(printf, 2, 3)));
-/** A quick n' easy way to create a wrapped exception with your own
- * message, before throwing it up the stack. (It uses all of the
- * @a child's fields.)
+/** If @child is SVN_NO_ERROR, return SVN_NO_ERROR.
+ * Else, prepend a new error to the error chain of @a child. The new error
+ * uses @a new_msg as error message but all other error attributes (such
+ * as the error code) are copied from @a child.
*/
svn_error_t *
svn_error_quick_wrap(svn_error_t *child,
const char *new_msg);
-/** A quick n' easy way to create a wrapped exception with your own
- * printf-style error message produced by passing @a fmt, using
- * apr_psprintf(), before throwing it up the stack. (It uses all of the
- * @a child's fields.)
+/** Like svn_error_quick_wrap(), but with format string support.
*
* @since New in 1.9.
*/
Modified: subversion/branches/move-tracking-2/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_fs.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_fs.h Tue May 26 08:57:33 2015
@@ -1422,7 +1422,7 @@ svn_fs_revision_root_revision(svn_fs_roo
* Unicode canonical decomposition and ordering. No directory entry
* may be named '.', '..', or the empty string. Given a directory
* entry name which fails to meet these requirements, a filesystem
- * function returns an SVN_ERR_FS_PATH_SYNTAX error.
+ * function returns an #SVN_ERR_FS_PATH_SYNTAX error.
*
* A directory path is a sequence of zero or more directory entry
* names, separated by slash characters (U+002f), and possibly ending
@@ -1430,7 +1430,7 @@ svn_fs_revision_root_revision(svn_fs_roo
* characters are treated as if they were a single slash. If a path
* ends with a slash, it refers to the same node it would without the
* slash, but that node must be a directory, or else the function
- * returns an SVN_ERR_FS_NOT_DIRECTORY error.
+ * may return an #SVN_ERR_FS_NOT_DIRECTORY error.
*
* A path consisting of the empty string, or a string containing only
* slashes, refers to the root directory.
Modified: subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_client/externals.c Tue May 26 08:57:33 2015
@@ -538,6 +538,8 @@ switch_file_external(const char *local_a
record_url,
record_peg_revision,
record_revision,
+ ctx->conflict_func2,
+ ctx->conflict_baton2,
ctx->cancel_func,
ctx->cancel_baton,
ctx->notify_func2,
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/cached_data.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/cached_data.c Tue May 26 08:57:33 2015
@@ -2524,11 +2524,43 @@ read_dir_entries(apr_array_header_t *ent
return SVN_NO_ERROR;
}
-/* Fetch the contents of a directory into ENTRIES. Values are stored
+/* For directory NODEREV in FS, return the *FILENAME and *FILESIZE of its
+ * in-txn representation. If the directory representation is comitted data,
+ * set *FILENAME to NULL and *FILESIZE to SVN_INVALID_FILESIZE. Allocate
+ * *FILENAME in RESULT_POOL and use SCRATCH_POOL for temporaries. */
+static svn_error_t *
+get_txn_dir_info(const char **filename,
+ svn_filesize_t *filesize,
+ svn_fs_t *fs,
+ node_revision_t *noderev,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const svn_io_dirent2_t *dirent;
+
+ if (noderev->data_rep && svn_fs_fs__id_txn_used(&noderev->data_rep->txn_id))
+ {
+ *filename = svn_fs_fs__path_txn_node_children(fs, noderev->id,
+ result_pool);
+
+ SVN_ERR(svn_io_stat_dirent2(&dirent, *filename, FALSE, FALSE,
+ scratch_pool, scratch_pool));
+ *filesize = dirent->filesize;
+ }
+ else
+ {
+ *filename = NULL;
+ *filesize = SVN_INVALID_FILESIZE;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Fetch the contents of a directory into DIR. Values are stored
as filename to string mappings; further conversion is necessary to
convert them into svn_fs_dirent_t values. */
static svn_error_t *
-get_dir_contents(apr_array_header_t **entries,
+get_dir_contents(svn_fs_fs__dir_data_t *dir,
svn_fs_t *fs,
node_revision_t *noderev,
apr_pool_t *result_pool,
@@ -2536,18 +2568,24 @@ get_dir_contents(apr_array_header_t **en
{
svn_stream_t *contents;
- *entries = apr_array_make(result_pool, 16, sizeof(svn_fs_dirent_t *));
+ /* Initialize the result. */
+ dir->entries = apr_array_make(result_pool, 16, sizeof(svn_fs_dirent_t *));
+ dir->txn_filesize = SVN_INVALID_FILESIZE;
+
+ /* Read dir contents - unless there is none in which case we are done. */
if (noderev->data_rep && svn_fs_fs__id_txn_used(&noderev->data_rep->txn_id))
{
- const char *filename
- = svn_fs_fs__path_txn_node_children(fs, noderev->id, scratch_pool);
+ /* Get location & current size of the directory representation. */
+ const char *filename;
+ SVN_ERR(get_txn_dir_info(&filename, &dir->txn_filesize, fs, noderev,
+ scratch_pool, scratch_pool));
/* The representation is mutable. Read the old directory
contents from the mutable children file, followed by the
changes we've made in this transaction. */
SVN_ERR(svn_stream_open_readonly(&contents, filename, scratch_pool,
scratch_pool));
- SVN_ERR(read_dir_entries(*entries, contents, TRUE, noderev->id,
+ SVN_ERR(read_dir_entries(dir->entries, contents, TRUE, noderev->id,
result_pool, scratch_pool));
SVN_ERR(svn_stream_close(contents));
}
@@ -2567,7 +2605,7 @@ get_dir_contents(apr_array_header_t **en
/* de-serialize hash */
contents = svn_stream_from_stringbuf(text, scratch_pool);
- SVN_ERR(read_dir_entries(*entries, contents, FALSE, noderev->id,
+ SVN_ERR(read_dir_entries(dir->entries, contents, FALSE, noderev->id,
result_pool, scratch_pool));
}
@@ -2623,6 +2661,7 @@ svn_fs_fs__rep_contents_dir(apr_array_he
{
pair_cache_key_t pair_key = { 0 };
const void *key;
+ svn_fs_fs__dir_data_t *dir;
/* find the cache we may use */
svn_cache__t *cache = locate_dir_cache(fs, &key, &pair_key, noderev,
@@ -2631,19 +2670,34 @@ svn_fs_fs__rep_contents_dir(apr_array_he
{
svn_boolean_t found;
- SVN_ERR(svn_cache__get((void **)entries_p, &found, cache, key,
+ SVN_ERR(svn_cache__get((void **)&dir, &found, cache, key,
result_pool));
if (found)
- return SVN_NO_ERROR;
+ {
+ /* Verify that the cached dir info is not stale
+ * (no-op for committed data). */
+ const char *filename;
+ svn_filesize_t filesize;
+ SVN_ERR(get_txn_dir_info(&filename, &filesize, fs, noderev,
+ scratch_pool, scratch_pool));
+
+ if (filesize == dir->txn_filesize)
+ {
+ /* Still valid. Done. */
+ *entries_p = dir->entries;
+ return SVN_NO_ERROR;
+ }
+ }
}
/* Read in the directory contents. */
- SVN_ERR(get_dir_contents(entries_p, fs, noderev, result_pool,
- scratch_pool));
+ dir = apr_pcalloc(scratch_pool, sizeof(*dir));
+ SVN_ERR(get_dir_contents(dir, fs, noderev, result_pool, scratch_pool));
+ *entries_p = dir->entries;
/* Update the cache, if we are to use one. */
if (cache)
- SVN_ERR(svn_cache__set(cache, key, *entries_p, scratch_pool));
+ SVN_ERR(svn_cache__set(cache, key, dir, scratch_pool));
return SVN_NO_ERROR;
}
@@ -2675,13 +2729,22 @@ svn_fs_fs__rep_contents_dir_entry(svn_fs
scratch_pool);
if (cache)
{
+ extract_dir_entry_baton_t baton;
+
+ const char *filename;
+ svn_filesize_t filesize;
+ SVN_ERR(get_txn_dir_info(&filename, &filesize, fs, noderev,
+ scratch_pool, scratch_pool));
+
/* Cache lookup. */
+ baton.txn_filesize = filesize;
+ baton.name = name;
SVN_ERR(svn_cache__get_partial((void **)dirent,
&found,
cache,
key,
svn_fs_fs__extract_dir_entry,
- (void*)name,
+ &baton,
result_pool));
}
@@ -2735,8 +2798,8 @@ svn_fs_fs__get_proplist(apr_hash_t **pro
{
svn_string_t *id_str = svn_fs_fs__id_unparse(noderev->id, pool);
- svn_error_clear(svn_stream_close(stream));
- return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
+ err = svn_error_compose_create(err, svn_stream_close(stream));
+ return svn_error_quick_wrapf(err,
_("malformed property list for node-revision '%s' in '%s'"),
id_str->data, filename);
}
@@ -2767,9 +2830,9 @@ svn_fs_fs__get_proplist(apr_hash_t **pro
if (err)
{
svn_string_t *id_str = svn_fs_fs__id_unparse(noderev->id, pool);
-
- svn_error_clear(svn_stream_close(stream));
- return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
+
+ err = svn_error_compose_create(err, svn_stream_close(stream));
+ return svn_error_quick_wrapf(err,
_("malformed property list for node-revision '%s'"),
id_str->data);
}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c Tue May 26 08:57:33 2015
@@ -162,9 +162,11 @@ fs_freeze_body(void *baton,
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));
+ SVN_ERR(svn_fs_fs__with_rep_cache_lock(b->fs,
+ b->freeze_func, b->freeze_baton,
+ pool));
+ else
+ SVN_ERR(b->freeze_func(b->freeze_baton, pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h Tue May 26 08:57:33 2015
@@ -623,6 +623,18 @@ typedef struct change_t
svn_fs_path_change2_t info;
} change_t;
+
+/*** Directory (only used at the cache interface) ***/
+typedef struct svn_fs_fs__dir_data_t
+{
+ /* Contents, i.e. all directory entries, sorted by name. */
+ apr_array_header_t *entries;
+
+ /* SVN_INVALID_FILESIZE for committed data, otherwise the length of the
+ * in-txn on-disk representation of that directory. */
+ svn_filesize_t txn_filesize;
+} svn_fs_fs__dir_data_t;
+
#ifdef __cplusplus
}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c Tue May 26 08:57:33 2015
@@ -1917,9 +1917,8 @@ get_node_origins_from_file(svn_fs_t *fs,
*node_origins = apr_hash_make(pool);
err = svn_hash_read2(*node_origins, stream, SVN_HASH_TERMINATOR, pool);
if (err)
- return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
- _("malformed node origin data in '%s'"),
- node_origins_file);
+ return svn_error_quick_wrapf(err, _("malformed node origin data in '%s'"),
+ node_origins_file);
return svn_stream_close(stream);
}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c Tue May 26 08:57:33 2015
@@ -222,7 +222,7 @@ write_digest_file(apr_hash_t *children,
svn_io_file_del_none, pool, pool));
if ((err = svn_hash_write2(hash, stream, SVN_HASH_TERMINATOR, pool)))
{
- svn_error_clear(svn_stream_close(stream));
+ err = svn_error_compose_create(err, svn_stream_close(stream));
return svn_error_createf(err->apr_err,
err,
_("Cannot write lock/entries hashfile '%s'"),
@@ -273,7 +273,7 @@ read_digest_file(apr_hash_t **children_p
hash = apr_hash_make(pool);
if ((err = svn_hash_read2(hash, stream, SVN_HASH_TERMINATOR, pool)))
{
- svn_error_clear(svn_stream_close(stream));
+ err = svn_error_compose_create(err, svn_stream_close(stream));
return svn_error_createf(err->apr_err,
err,
_("Can't parse lock/entries hashfile '%s'"),
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.c Tue May 26 08:57:33 2015
@@ -189,6 +189,19 @@ svn_fs_fs__unparse_revision_trailer(apr_
changes_offset);
}
+/* If ERR is not NULL, wrap it MESSAGE. The latter must have an %ld
+ * format parameter that will be filled with REV. */
+static svn_error_t *
+wrap_footer_error(svn_error_t *err,
+ const char *message,
+ svn_revnum_t rev)
+{
+ if (err)
+ return svn_error_quick_wrapf(err, message, rev);
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_fs_fs__parse_footer(apr_off_t *l2p_offset,
svn_checksum_t **l2p_checksum,
@@ -196,6 +209,7 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
svn_checksum_t **p2l_checksum,
svn_stringbuf_t *footer,
svn_revnum_t rev,
+ apr_off_t footer_offset,
apr_pool_t *result_pool)
{
apr_int64_t val;
@@ -204,17 +218,20 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
/* Get the L2P offset. */
const char *str = svn_cstring_tokenize(" ", &last_str);
if (str == NULL)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- _("Invalid revision footer"));
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "Invalid r%ld footer", rev);
- SVN_ERR(svn_cstring_atoi64(&val, str));
+ SVN_ERR(wrap_footer_error(svn_cstring_strtoi64(&val, str, 0,
+ footer_offset - 1, 10),
+ "Invalid L2P offset in r%ld footer",
+ rev));
*l2p_offset = (apr_off_t)val;
/* Get the L2P checksum. */
str = svn_cstring_tokenize(" ", &last_str);
if (str == NULL)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- _("Invalid revision footer"));
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "Invalid r%ld footer", rev);
SVN_ERR(svn_checksum_parse_hex(l2p_checksum, svn_checksum_md5, str,
result_pool));
@@ -222,17 +239,33 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
/* Get the P2L offset. */
str = svn_cstring_tokenize(" ", &last_str);
if (str == NULL)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- _("Invalid revision footer"));
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "Invalid r%ld footer", rev);
- SVN_ERR(svn_cstring_atoi64(&val, str));
+ SVN_ERR(wrap_footer_error(svn_cstring_strtoi64(&val, str, 0,
+ footer_offset - 1, 10),
+ "Invalid P2L offset in r%ld footer",
+ rev));
*p2l_offset = (apr_off_t)val;
+ /* The P2L indes follows the L2P index */
+ if (*p2l_offset <= *l2p_offset)
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "P2L offset %s must be larger than L2P offset %s"
+ " in r%ld footer",
+ apr_psprintf(result_pool,
+ "%" APR_UINT64_T_HEX_FMT,
+ (apr_uint64_t)*p2l_offset),
+ apr_psprintf(result_pool,
+ "%" APR_UINT64_T_HEX_FMT,
+ (apr_uint64_t)*l2p_offset),
+ rev);
+
/* Get the P2L checksum. */
str = svn_cstring_tokenize(" ", &last_str);
if (str == NULL)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- _("Invalid revision footer"));
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "Invalid r%ld footer", rev);
SVN_ERR(svn_checksum_parse_hex(p2l_checksum, svn_checksum_md5, str,
result_pool));
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/low_level.h Tue May 26 08:57:33 2015
@@ -67,6 +67,8 @@ svn_fs_fs__unparse_revision_trailer(apr_
* *P2L_OFFSET, respectively. Also, return the expected checksums in
* in *L2P_CHECKSUM and *P2L_CHECKSUM.
*
+ * FOOTER_OFFSET is used for validation.
+ *
* Note that REV is only used to construct nicer error objects that
* mention this revision. Allocate the checksums in RESULT_POOL.
*/
@@ -77,6 +79,7 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
svn_checksum_t **p2l_checksum,
svn_stringbuf_t *footer,
svn_revnum_t rev,
+ apr_off_t footer_offset,
apr_pool_t *result_pool);
/* Given the offset of the L2P index data in L2P_OFFSET, the content
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/recovery.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/recovery.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/recovery.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/recovery.c Tue May 26 08:57:33 2015
@@ -209,8 +209,8 @@ recover_find_max_ids(svn_fs_t *fs,
{
svn_string_t *id_str = svn_fs_fs__id_unparse(noderev->id, pool);
- svn_error_clear(svn_stream_close(stream));
- return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
+ err = svn_error_compose_create(err, svn_stream_close(stream));
+ return svn_error_quick_wrapf(err,
_("malformed representation for node-revision '%s'"),
id_str->data);
}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache-db.sql
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache-db.sql (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache-db.sql Tue May 26 08:57:33 2015
@@ -63,3 +63,6 @@ WHERE revision > ?1
-- STMT_LOCK_REP
BEGIN TRANSACTION;
INSERT INTO rep_cache VALUES ('dummy', 0, 0, 0, 0)
+
+-- STMT_UNLOCK_REP
+ROLLBACK TRANSACTION;
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.c Tue May 26 08:57:33 2015
@@ -374,9 +374,13 @@ svn_fs_fs__del_rep_reference(svn_fs_t *f
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_fs_fs__lock_rep_cache(svn_fs_t *fs,
- apr_pool_t *pool)
+/* Start a transaction to take an SQLite reserved lock that prevents
+ other writes.
+
+ See unlock_rep_cache(). */
+static svn_error_t *
+lock_rep_cache(svn_fs_t *fs,
+ apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
@@ -387,3 +391,31 @@ svn_fs_fs__lock_rep_cache(svn_fs_t *fs,
return SVN_NO_ERROR;
}
+
+/* End the transaction started by lock_rep_cache(). */
+static svn_error_t *
+unlock_rep_cache(svn_fs_t *fs,
+ apr_pool_t *pool)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+
+ SVN_ERR_ASSERT(ffd->rep_cache_db); /* was opened by lock_rep_cache() */
+
+ SVN_ERR(svn_sqlite__exec_statements(ffd->rep_cache_db, STMT_UNLOCK_REP));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__with_rep_cache_lock(svn_fs_t *fs,
+ svn_error_t *(*body)(void *,
+ apr_pool_t *),
+ void *baton,
+ apr_pool_t *pool)
+{
+ svn_error_t *err;
+
+ SVN_ERR(lock_rep_cache(fs, pool));
+ err = body(baton, pool);
+ return svn_error_compose_create(err, unlock_rep_cache(fs, pool));
+}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rep-cache.h Tue May 26 08:57:33 2015
@@ -87,10 +87,14 @@ svn_fs_fs__del_rep_reference(svn_fs_t *f
apr_pool_t *pool);
/* Start a transaction to take an SQLite reserved lock that prevents
- other writes. */
+ other writes, call BODY, end the transaction, and return what BODY returned.
+ */
svn_error_t *
-svn_fs_fs__lock_rep_cache(svn_fs_t *fs,
- apr_pool_t *pool);
+svn_fs_fs__with_rep_cache_lock(svn_fs_t *fs,
+ svn_error_t *(*body)(void *baton,
+ apr_pool_t *pool),
+ void *baton,
+ apr_pool_t *pool);
#ifdef __cplusplus
}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rev_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rev_file.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rev_file.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/rev_file.c Tue May 26 08:57:33 2015
@@ -259,6 +259,7 @@ svn_fs_fs__auto_read_footer(svn_fs_fs__r
SVN_ERR(svn_fs_fs__parse_footer(&file->l2p_offset, &file->l2p_checksum,
&file->p2l_offset, &file->p2l_checksum,
footer, file->start_revision,
+ filesize - footer_length - 1,
file->pool));
file->footer_offset = filesize - footer_length - 1;
}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c Tue May 26 08:57:33 2015
@@ -36,11 +36,6 @@
#include "svn_private_config.h"
-/* Give writing processes 10 seconds to replace an existing revprop
- file with a new one. After that time, we assume that the writing
- process got aborted and that we have re-read revprops. */
-#define REVPROP_CHANGE_TIMEOUT (10 * 1000000)
-
svn_error_t *
svn_fs_fs__upgrade_pack_revprops(svn_fs_t *fs,
svn_fs_upgrade_notify_t notify_func,
@@ -657,17 +652,23 @@ write_non_packed_revprop(const char **fi
apr_hash_t *proplist,
apr_pool_t *pool)
{
+ apr_file_t *file;
svn_stream_t *stream;
*final_path = svn_fs_fs__path_revprops(fs, rev, pool);
/* ### do we have a directory sitting around already? we really shouldn't
### have to get the dirname here. */
- SVN_ERR(svn_stream_open_unique(&stream, tmp_path,
- svn_dirent_dirname(*final_path, pool),
- svn_io_file_del_none, pool, pool));
+ SVN_ERR(svn_io_open_unique_file3(&file, tmp_path,
+ svn_dirent_dirname(*final_path, pool),
+ svn_io_file_del_none, pool, pool));
+ stream = svn_stream_from_aprfile2(file, TRUE, pool);
SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, pool));
SVN_ERR(svn_stream_close(stream));
+ /* Flush temporary file to disk and close it. */
+ SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+ SVN_ERR(svn_io_file_close(file, pool));
+
return SVN_NO_ERROR;
}
@@ -750,7 +751,7 @@ serialize_revprops_header(svn_stream_t *
return SVN_NO_ERROR;
}
-/* Writes the a pack file to FILE_STREAM. It copies the serialized data
+/* Writes the a pack file to FILE. It copies the serialized data
* from REVPROPS for the indexes [START,END) except for index CHANGED_INDEX.
*
* The data for the latter is taken from NEW_SERIALIZED. Note, that
@@ -768,7 +769,7 @@ repack_revprops(svn_fs_t *fs,
int changed_index,
svn_stringbuf_t *new_serialized,
apr_off_t new_total_size,
- svn_stream_t *file_stream,
+ apr_file_t *file,
apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
@@ -816,9 +817,11 @@ repack_revprops(svn_fs_t *fs,
? SVN_DELTA_COMPRESSION_LEVEL_DEFAULT
: SVN_DELTA_COMPRESSION_LEVEL_NONE));
- /* finally, write the content to the target stream and close it */
- SVN_ERR(svn_stream_write(file_stream, compressed->data, &compressed->len));
- SVN_ERR(svn_stream_close(file_stream));
+ /* finally, write the content to the target file, flush and close it */
+ SVN_ERR(svn_io_file_write_full(file, compressed->data, compressed->len,
+ NULL, pool));
+ SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+ SVN_ERR(svn_io_file_close(file, pool));
return SVN_NO_ERROR;
}
@@ -826,23 +829,22 @@ repack_revprops(svn_fs_t *fs,
/* Allocate a new pack file name for revisions
* [REVPROPS->START_REVISION + START, REVPROPS->START_REVISION + END - 1]
* of REVPROPS->MANIFEST. Add the name of old file to FILES_TO_DELETE,
- * auto-create that array if necessary. Return an open file stream to
- * the new file in *STREAM allocated in POOL.
+ * auto-create that array if necessary. Return an open file *FILE that is
+ * allocated in POOL.
*/
static svn_error_t *
-repack_stream_open(svn_stream_t **stream,
- svn_fs_t *fs,
- packed_revprops_t *revprops,
- int start,
- int end,
- apr_array_header_t **files_to_delete,
- apr_pool_t *pool)
+repack_file_open(apr_file_t **file,
+ svn_fs_t *fs,
+ packed_revprops_t *revprops,
+ int start,
+ int end,
+ apr_array_header_t **files_to_delete,
+ apr_pool_t *pool)
{
apr_int64_t tag;
const char *tag_string;
svn_string_t *new_filename;
int i;
- apr_file_t *file;
int manifest_offset
= (int)(revprops->start_revision - revprops->manifest_start);
@@ -874,12 +876,11 @@ repack_stream_open(svn_stream_t **stream
APR_ARRAY_IDX(revprops->manifest, i + manifest_offset, const char*)
= new_filename->data;
- /* create a file stream for the new file */
- SVN_ERR(svn_io_file_open(&file, svn_dirent_join(revprops->folder,
- new_filename->data,
- pool),
+ /* open the file */
+ SVN_ERR(svn_io_file_open(file, svn_dirent_join(revprops->folder,
+ new_filename->data,
+ pool),
APR_WRITE | APR_CREATE, APR_OS_DEFAULT, pool));
- *stream = svn_stream_from_aprfile2(file, FALSE, pool);
return SVN_NO_ERROR;
}
@@ -903,6 +904,7 @@ write_packed_revprop(const char **final_
packed_revprops_t *revprops;
apr_int64_t generation = 0;
svn_stream_t *stream;
+ apr_file_t *file;
svn_stringbuf_t *serialized;
apr_off_t new_total_size;
int changed_index;
@@ -933,11 +935,11 @@ write_packed_revprop(const char **final_
*final_path = svn_dirent_join(revprops->folder, revprops->filename,
pool);
- SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder,
- svn_io_file_del_none, pool, pool));
+ SVN_ERR(svn_io_open_unique_file3(&file, tmp_path, revprops->folder,
+ svn_io_file_del_none, pool, pool));
SVN_ERR(repack_revprops(fs, revprops, 0, revprops->sizes->nelts,
changed_index, serialized, new_total_size,
- stream, pool));
+ file, pool));
}
else
{
@@ -983,50 +985,53 @@ write_packed_revprop(const char **final_
/* write the new, split files */
if (left_count)
{
- SVN_ERR(repack_stream_open(&stream, fs, revprops, 0,
- left_count, files_to_delete, pool));
+ SVN_ERR(repack_file_open(&file, fs, revprops, 0,
+ left_count, files_to_delete, pool));
SVN_ERR(repack_revprops(fs, revprops, 0, left_count,
changed_index, serialized, new_total_size,
- stream, pool));
+ file, pool));
}
if (left_count + right_count < revprops->sizes->nelts)
{
- SVN_ERR(repack_stream_open(&stream, fs, revprops, changed_index,
- changed_index + 1, files_to_delete,
- pool));
+ SVN_ERR(repack_file_open(&file, fs, revprops, changed_index,
+ changed_index + 1, files_to_delete,
+ pool));
SVN_ERR(repack_revprops(fs, revprops, changed_index,
changed_index + 1,
changed_index, serialized, new_total_size,
- stream, pool));
+ file, pool));
}
if (right_count)
{
- SVN_ERR(repack_stream_open(&stream, fs, revprops,
- revprops->sizes->nelts - right_count,
- revprops->sizes->nelts,
- files_to_delete, pool));
+ SVN_ERR(repack_file_open(&file, fs, revprops,
+ revprops->sizes->nelts - right_count,
+ revprops->sizes->nelts,
+ files_to_delete, pool));
SVN_ERR(repack_revprops(fs, revprops,
revprops->sizes->nelts - right_count,
revprops->sizes->nelts, changed_index,
- serialized, new_total_size, stream,
+ serialized, new_total_size, file,
pool));
}
/* write the new manifest */
*final_path = svn_dirent_join(revprops->folder, PATH_MANIFEST, pool);
- SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder,
- svn_io_file_del_none, pool, pool));
+ SVN_ERR(svn_io_open_unique_file3(&file, tmp_path, revprops->folder,
+ svn_io_file_del_none, pool, pool));
for (i = 0; i < revprops->manifest->nelts; ++i)
{
const char *filename = APR_ARRAY_IDX(revprops->manifest, i,
const char*);
- SVN_ERR(svn_stream_printf(stream, pool, "%s\n", filename));
+ SVN_ERR(svn_io_file_write_full(file, filename, strlen(filename),
+ NULL, pool));
+ SVN_ERR(svn_io_file_putc('\n', file, pool));
}
- SVN_ERR(svn_stream_close(stream));
+ SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+ SVN_ERR(svn_io_file_close(file, pool));
}
return SVN_NO_ERROR;
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/structure?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/structure Tue May 26 08:57:33 2015
@@ -525,6 +525,7 @@ A revision file contains a concatenation
* Text and property representations
* Node-revisions
* The changed-path data
+ * Two offsets at the very end (physical addressing only)
* Index data (logical addressing only)
* Revision / pack file footer (logical addressing only)
@@ -757,6 +758,9 @@ Format 7 introduces logical addressing t
to be translated / mapped to physical rev / pack file offsets.
These indexes are appended to the respective rev / pack file.
+The indexes map (revision number, item-index) pairs to absolute file offsets
+and absolute file offsets to (revision number, item-index, item metadata).
+
Details of the binary format used by these index files can be
found in structure-indexes.
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.c Tue May 26 08:57:33 2015
@@ -153,6 +153,10 @@ typedef struct dir_data_t
* (it's int because the directory is an APR array) */
int count;
+ /** Current length of the in-txn in-disk representation of the directory.
+ * SVN_INVALID_FILESIZE if unknown (i.e. committed data). */
+ svn_filesize_t txn_filesize;
+
/* number of unused dir entry buckets in the index */
apr_size_t over_provision;
@@ -198,15 +202,16 @@ serialize_dir_entry(svn_temp_serializer_
svn_temp_serializer__pop(context);
}
-/* Utility function to serialize the ENTRIES into a new serialization
+/* Utility function to serialize the DIR into a new serialization
* context to be returned. Allocation will be made form POOL.
*/
static svn_temp_serializer__context_t *
-serialize_dir(apr_array_header_t *entries, apr_pool_t *pool)
+serialize_dir(svn_fs_fs__dir_data_t *dir, apr_pool_t *pool)
{
dir_data_t dir_data;
int i = 0;
svn_temp_serializer__context_t *context;
+ apr_array_header_t *entries = dir->entries;
/* calculate sizes */
int count = entries->nelts;
@@ -216,6 +221,7 @@ serialize_dir(apr_array_header_t *entrie
/* copy the hash entries to an auxiliary struct of known layout */
dir_data.count = count;
+ dir_data.txn_filesize = dir->txn_filesize;
dir_data.over_provision = over_provision;
dir_data.operations = 0;
dir_data.entries = apr_palloc(pool, entries_len);
@@ -252,24 +258,29 @@ serialize_dir(apr_array_header_t *entrie
return context;
}
-/* Utility function to reconstruct a dir entries array from serialized data
+/* Utility function to reconstruct a dir entries struct from serialized data
* in BUFFER and DIR_DATA. Allocation will be made form POOL.
*/
-static apr_array_header_t *
+static svn_fs_fs__dir_data_t *
deserialize_dir(void *buffer, dir_data_t *dir_data, apr_pool_t *pool)
{
- apr_array_header_t *result
- = apr_array_make(pool, dir_data->count, sizeof(svn_fs_dirent_t *));
+ svn_fs_fs__dir_data_t *result;
apr_size_t i;
apr_size_t count;
svn_fs_dirent_t *entry;
svn_fs_dirent_t **entries;
+ /* Construct empty directory object. */
+ result = apr_pcalloc(pool, sizeof(*result));
+ result->entries
+ = apr_array_make(pool, dir_data->count, sizeof(svn_fs_dirent_t *));
+ result->txn_filesize = dir_data->txn_filesize;
+
/* resolve the reference to the entries array */
svn_temp_deserializer__resolve(buffer, (void **)&dir_data->entries);
entries = dir_data->entries;
- /* fixup the references within each entry and add it to the hash */
+ /* fixup the references within each entry and add it to the RESULT */
for (i = 0, count = dir_data->count; i < count; ++i)
{
svn_temp_deserializer__resolve(entries, (void **)&entries[i]);
@@ -280,7 +291,7 @@ deserialize_dir(void *buffer, dir_data_t
svn_fs_fs__id_deserialize(entry, (svn_fs_id_t **)&entry->id);
/* add the entry to the hash */
- APR_ARRAY_PUSH(result, svn_fs_dirent_t *) = entry;
+ APR_ARRAY_PUSH(result->entries, svn_fs_dirent_t *) = entry;
}
/* return the now complete hash */
@@ -764,7 +775,7 @@ svn_fs_fs__serialize_dir_entries(void **
void *in,
apr_pool_t *pool)
{
- apr_array_header_t *dir = in;
+ svn_fs_fs__dir_data_t *dir = in;
/* serialize the dir content into a new serialization context
* and return the serialized data */
@@ -803,6 +814,20 @@ svn_fs_fs__get_sharded_offset(void **out
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_fs_fs__extract_dir_filesize(void **out,
+ const void *data,
+ apr_size_t data_len,
+ void *baton,
+ apr_pool_t *pool)
+{
+ const dir_data_t *dir_data = data;
+
+ *(svn_filesize_t *)out = dir_data->txn_filesize;
+
+ return SVN_NO_ERROR;
+}
+
/* Utility function that returns the lowest index of the first entry in
* *ENTRIES that points to a dir entry with a name equal or larger than NAME.
* If an exact match has been found, *FOUND will be set to TRUE. COUNT is
@@ -857,7 +882,7 @@ svn_fs_fs__extract_dir_entry(void **out,
apr_pool_t *pool)
{
const dir_data_t *dir_data = data;
- const char* name = baton;
+ const extract_dir_entry_baton_t *entry_baton = baton;
svn_boolean_t found;
/* resolve the reference to the entries array */
@@ -870,13 +895,14 @@ svn_fs_fs__extract_dir_entry(void **out,
/* binary search for the desired entry by name */
apr_size_t pos = find_entry((svn_fs_dirent_t **)entries,
- name,
+ entry_baton->name,
dir_data->count,
&found);
- /* de-serialize that entry or return NULL, if no match has been found */
+ /* de-serialize that entry or return NULL, if no match has been found.
+ * Be sure to check that the directory contents is still up-to-date. */
*out = NULL;
- if (found)
+ if (found && dir_data->txn_filesize == entry_baton->txn_filesize)
{
const svn_fs_dirent_t *source =
svn_temp_deserializer__ptr(entries, (const void *const *)&entries[pos]);
@@ -911,31 +937,34 @@ slowly_replace_dir_entry(void **data,
{
replace_baton_t *replace_baton = (replace_baton_t *)baton;
dir_data_t *dir_data = (dir_data_t *)*data;
- apr_array_header_t *dir;
+ svn_fs_fs__dir_data_t *dir;
int idx = -1;
svn_fs_dirent_t *entry;
+ apr_array_header_t *entries;
SVN_ERR(svn_fs_fs__deserialize_dir_entries((void **)&dir,
*data,
dir_data->len,
pool));
- entry = svn_fs_fs__find_dir_entry(dir, replace_baton->name, &idx);
+ entries = dir->entries;
+ entry = svn_fs_fs__find_dir_entry(entries, replace_baton->name, &idx);
/* Replacement or removal? */
if (replace_baton->new_entry)
{
/* Replace ENTRY with / insert the NEW_ENTRY */
if (entry)
- APR_ARRAY_IDX(dir, idx, svn_fs_dirent_t *) = replace_baton->new_entry;
+ APR_ARRAY_IDX(entries, idx, svn_fs_dirent_t *)
+ = replace_baton->new_entry;
else
- svn_sort__array_insert(dir, &replace_baton->new_entry, idx);
+ svn_sort__array_insert(entries, &replace_baton->new_entry, idx);
}
else
{
/* Remove the old ENTRY. */
if (entry)
- svn_sort__array_delete(dir, idx, 1);
+ svn_sort__array_delete(entries, idx, 1);
}
return svn_fs_fs__serialize_dir_entries(data, data_len, dir, pool);
@@ -957,6 +986,12 @@ svn_fs_fs__replace_dir_entry(void **data
svn_temp_serializer__context_t *context;
+ /* update the cached file length info.
+ * Because we are writing to the cache, it is fair to assume that the
+ * caller made sure that the current contents is consistent with the
+ * previous state of the directory file. */
+ dir_data->txn_filesize = replace_baton->txn_filesize;
+
/* after quite a number of operations, let's re-pack everything.
* This is to limit the number of wasted space as we cannot overwrite
* existing data but must always append. */
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/temp_serializer.h Tue May 26 08:57:33 2015
@@ -192,7 +192,7 @@ svn_fs_fs__deserialize_node_revision(voi
apr_pool_t *pool);
/**
- * Implements #svn_cache__serialize_func_t for a directory contents array
+ * Implements #svn_cache__serialize_func_t for a #svn_fs_fs__dir_data_t
*/
svn_error_t *
svn_fs_fs__serialize_dir_entries(void **data,
@@ -201,7 +201,7 @@ svn_fs_fs__serialize_dir_entries(void **
apr_pool_t *pool);
/**
- * Implements #svn_cache__deserialize_func_t for a directory contents array
+ * Implements #svn_cache__deserialize_func_t for a #svn_fs_fs__dir_data_t
*/
svn_error_t *
svn_fs_fs__deserialize_dir_entries(void **out,
@@ -221,9 +221,38 @@ svn_fs_fs__get_sharded_offset(void **out
apr_pool_t *pool);
/**
+ * Implements #svn_cache__partial_getter_func_t.
+ * Set (svn_filesize_t) @a *out to the filesize info stored with the
+ * serialized directory in @a data of @a data_len. @a baton is unused.
+ */
+svn_error_t *
+svn_fs_fs__extract_dir_filesize(void **out,
+ const void *data,
+ apr_size_t data_len,
+ void *baton,
+ apr_pool_t *pool);
+
+/**
+ * Describes the entry to be found in a directory: Identifies the entry
+ * by @a name and requires the directory file size to be @a filesize.
+ */
+typedef struct extract_dir_entry_baton_t
+{
+ /** name of the directory entry to return */
+ const char *name;
+
+ /** Current length of the in-txn in-disk representation of the directory.
+ * SVN_INVALID_FILESIZE if unknown. */
+ svn_filesize_t txn_filesize;
+} extract_dir_entry_baton_t;
+
+
+/**
* Implements #svn_cache__partial_getter_func_t for a single
* #svn_fs_dirent_t within a serialized directory contents hash,
- * identified by its name (const char @a *baton).
+ * identified by its name (in (extract_dir_entry_baton_t *) @a *baton).
+ * If the filesize specified in the baton does not match the cached
+ * value for this directory, @a *out will be NULL as well.
*/
svn_error_t *
svn_fs_fs__extract_dir_entry(void **out,
@@ -236,7 +265,10 @@ svn_fs_fs__extract_dir_entry(void **out,
* Describes the change to be done to a directory: Set the entry
* identify by @a name to the value @a new_entry. If the latter is
* @c NULL, the entry shall be removed if it exists. Otherwise it
- * will be replaced or automatically added, respectively.
+ * will be replaced or automatically added, respectively. The
+ * @a filesize allows readers to identify stale cache data (e.g.
+ * due to concurrent access to txns); writers use it to update the
+ * cached file size info.
*/
typedef struct replace_baton_t
{
@@ -245,6 +277,10 @@ typedef struct replace_baton_t
/** directory entry to insert instead */
svn_fs_dirent_t *new_entry;
+
+ /** Current length of the in-txn in-disk representation of the directory.
+ * SVN_INVALID_FILESIZE if unknown. */
+ svn_filesize_t txn_filesize;
} replace_baton_t;
/**
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c Tue May 26 08:57:33 2015
@@ -1145,9 +1145,9 @@ get_txn_proplist(apr_hash_t *proplist,
err = svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR, pool);
if (err)
{
- svn_error_clear(svn_stream_close(stream));
- return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
- _("malformed transaction property list in '%s'"),
+ err = svn_error_compose_create(err, svn_stream_close(stream));
+ return svn_error_quick_wrapf(err,
+ _("malformed property list in transaction '%s'"),
path_txn_props(fs, txn_id, pool));
}
@@ -1524,22 +1524,80 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
}
else
{
+ const svn_io_dirent2_t *dirent;
+
/* The directory rep is already mutable, so just open it for append. */
SVN_ERR(svn_io_file_open(&file, filename, APR_WRITE | APR_APPEND,
- APR_OS_DEFAULT, pool));
- out = svn_stream_from_aprfile2(file, TRUE, pool);
+ APR_OS_DEFAULT, subpool));
+ out = svn_stream_from_aprfile2(file, TRUE, subpool);
+
+ /* If the cache contents is stale, drop it.
+ *
+ * Note that the directory file is append-only, i.e. if the size
+ * did not change, the contents didn't either. */
+ if (ffd->txn_dir_cache)
+ {
+ const char *key
+ = svn_fs_fs__id_unparse(parent_noderev->id, subpool)->data;
+ svn_boolean_t found;
+ svn_filesize_t filesize;
+
+ /* Get the file size that corresponds to the cached contents
+ * (if any). */
+ SVN_ERR(svn_cache__get_partial((void **)&filesize, &found,
+ ffd->txn_dir_cache, key,
+ svn_fs_fs__extract_dir_filesize,
+ NULL, subpool));
+
+ /* File size info still matches?
+ * If not, we need to drop the cache entry. */
+ if (found)
+ {
+ SVN_ERR(svn_io_stat_dirent2(&dirent, filename, FALSE, FALSE,
+ subpool, subpool));
+
+ if (filesize != dirent->filesize)
+ SVN_ERR(svn_cache__set(ffd->txn_dir_cache, key, NULL,
+ subpool));
+ }
+ }
+ }
+
+ /* Append an incremental hash entry for the entry change. */
+ if (id)
+ {
+ svn_fs_dirent_t entry;
+ entry.name = name;
+ entry.id = id;
+ entry.kind = kind;
+
+ SVN_ERR(unparse_dir_entry(&entry, out, subpool));
+ }
+ else
+ {
+ SVN_ERR(svn_stream_printf(out, subpool, "D %" APR_SIZE_T_FMT "\n%s\n",
+ strlen(name), name));
}
+ /* Flush APR buffers. */
+ SVN_ERR(svn_io_file_close(file, subpool));
+ svn_pool_clear(subpool);
+
/* if we have a directory cache for this transaction, update it */
if (ffd->txn_dir_cache)
{
- /* build parameters: (name, new entry) pair */
+ /* build parameters: name, new entry, new file size */
const char *key =
svn_fs_fs__id_unparse(parent_noderev->id, subpool)->data;
replace_baton_t baton;
+ const svn_io_dirent2_t *dirent;
+ SVN_ERR(svn_io_stat_dirent2(&dirent, filename, FALSE, FALSE,
+ subpool, subpool));
+
baton.name = name;
baton.new_entry = NULL;
+ baton.txn_filesize = dirent->filesize;
if (id)
{
@@ -1554,25 +1612,7 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
svn_fs_fs__replace_dir_entry, &baton,
subpool));
}
- svn_pool_clear(subpool);
- /* Append an incremental hash entry for the entry change. */
- if (id)
- {
- svn_fs_dirent_t entry;
- entry.name = name;
- entry.id = id;
- entry.kind = kind;
-
- SVN_ERR(unparse_dir_entry(&entry, out, subpool));
- }
- else
- {
- SVN_ERR(svn_stream_printf(out, subpool, "D %" APR_SIZE_T_FMT "\n%s\n",
- strlen(name), name));
- }
-
- SVN_ERR(svn_io_file_close(file, subpool));
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
Propchange: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 26 08:57:33 2015
@@ -90,4 +90,4 @@
/subversion/branches/verify-keep-going/subversion/libsvn_fs_x:1439280-1492639,1546002-1546110
/subversion/branches/wc-collate-path/subversion/libsvn_fs_x:1402685-1480384
/subversion/trunk/subversion/libsvn_fs_fs:1415133-1596500,1596567,1597414,1597989,1598273,1599140,1600872,1601633,1603485-1603487,1603499,1603605,1604128,1604188,1604413-1604414,1604416-1604417,1604421,1604442,1604700,1604717,1604720,1604726,1604755,1604794,1604802,1604824,1604836,1604844,1604902-1604903,1604911,1604925,1604933,1604947,1605059-1605060,1605064-1605065,1605068,1605071-1605073,1605075,1605123,1605188-1605189,1605191,1605197,1605444,1605633,1606132,1606142,1606144,1606514,1606526,1606528,1606551,1606554,1606564,1606598-1606599,1606656,1606658,1606662,1606744,1606840,1607085,1607572,1612407,1612810,1613339,1613872,1614611,1615348,1615351-1615352,1615356,1616338-1616339,1616613,1617586,1617688,1618138,1618151,1618153,1618226,1618641,1618653,1618662,1619068,1619358,1619413,1619769,1619774,1620602,1620909,1620912,1620928,1620930,1621275,1621635,1622931,1622937,1622942,1622946,1622959-1622960,1622963,1622987,1623007,1623368,1623373,1623377,1623379,1623381,1623398,1623402,162
4011,1624265,1624512,1626246,1626871,1626873,1626886,1627497-1627498,1627502,1627947-1627949,1627966,1628083,1628093,1628158-1628159,1628161,1628392-1628393,1628415,1628427,1628676,1628738,1628762,1628764,1629854-1629855,1629857,1629865,1629873,1629875,1629879,1630067,1630070,1631049-1631051,1631075,1631115,1631171,1631180,1631185-1631186,1631196-1631197,1631239-1631240,1631548,1631550,1631563,1631567,1631588,1631598,1632646,1632776,1632849,1632851-1632853,1632856-1632857,1632868,1632908,1632926,1633232,1633617-1633618,1634872,1634875,1634879-1634880,1634920,1636478,1636483,1636629,1636644,1637184,1637186,1637330,1637358,1637363,1637393,1639319,1639322,1639335,1639348,1639352,1639355,1639358,1639414,1639419,1639426,1639430,1639436,1639440,1639549,1640061-1640062,1640197,1640915,1640966,1641013,1643139,1643233,1645567,1646021,1646712,1646716,1647537,1647540-1647541,1647820,1647905,1648230,1648238,1648241-1648243,1648253,1648272,1648532,1648537-1648539,1648542,1648591,1648612,1653608,
1658482
-/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914,1606692-1673179
+/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914,1606692-1681720
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c Tue May 26 08:57:33 2015
@@ -164,9 +164,11 @@ x_freeze_body(void *baton,
SVN_ERR(svn_fs_x__exists_rep_cache(&exists, b->fs, scratch_pool));
if (exists)
- SVN_ERR(svn_fs_x__lock_rep_cache(b->fs, scratch_pool));
-
- SVN_ERR(b->freeze_func(b->freeze_baton, scratch_pool));
+ SVN_ERR(svn_fs_x__with_rep_cache_lock(b->fs,
+ b->freeze_func, b->freeze_baton,
+ scratch_pool));
+ else
+ SVN_ERR(b->freeze_func(b->freeze_baton, scratch_pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache-db.sql
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache-db.sql?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache-db.sql (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache-db.sql Tue May 26 08:57:33 2015
@@ -65,3 +65,6 @@ WHERE revision > ?1
-- STMT_LOCK_REP
BEGIN TRANSACTION;
INSERT INTO rep_cache VALUES ('dummy', 0, 0, 0, 0)
+
+-- STMT_UNLOCK_REP
+ROLLBACK TRANSACTION;
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.c Tue May 26 08:57:33 2015
@@ -369,16 +369,48 @@ svn_fs_x__del_rep_reference(svn_fs_t *fs
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_fs_x__lock_rep_cache(svn_fs_t *fs,
- apr_pool_t *scratch_pool)
+/* Start a transaction to take an SQLite reserved lock that prevents
+ other writes.
+
+ See unlock_rep_cache(). */
+static svn_error_t *
+lock_rep_cache(svn_fs_t *fs,
+ apr_pool_t *pool)
{
svn_fs_x__data_t *ffd = fs->fsap_data;
if (! ffd->rep_cache_db)
- SVN_ERR(svn_fs_x__open_rep_cache(fs, scratch_pool));
+ SVN_ERR(svn_fs_x__open_rep_cache(fs, pool));
SVN_ERR(svn_sqlite__exec_statements(ffd->rep_cache_db, STMT_LOCK_REP));
return SVN_NO_ERROR;
}
+
+/* End the transaction started by lock_rep_cache(). */
+static svn_error_t *
+unlock_rep_cache(svn_fs_t *fs,
+ apr_pool_t *pool)
+{
+ svn_fs_x__data_t *ffd = fs->fsap_data;
+
+ SVN_ERR_ASSERT(ffd->rep_cache_db); /* was opened by lock_rep_cache() */
+
+ SVN_ERR(svn_sqlite__exec_statements(ffd->rep_cache_db, STMT_UNLOCK_REP));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_x__with_rep_cache_lock(svn_fs_t *fs,
+ svn_error_t *(*body)(void *,
+ apr_pool_t *),
+ void *baton,
+ apr_pool_t *pool)
+{
+ svn_error_t *err;
+
+ SVN_ERR(lock_rep_cache(fs, pool));
+ err = body(baton, pool);
+ return svn_error_compose_create(err, unlock_rep_cache(fs, pool));
+}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rep-cache.h Tue May 26 08:57:33 2015
@@ -88,12 +88,16 @@ svn_fs_x__del_rep_reference(svn_fs_t *fs
svn_revnum_t youngest,
apr_pool_t *scratch_pool);
+
/* Start a transaction to take an SQLite reserved lock that prevents
- other writes. */
+ other writes, call BODY, end the transaction, and return what BODY returned.
+ */
svn_error_t *
-svn_fs_x__lock_rep_cache(svn_fs_t *fs,
- apr_pool_t *scratch_pool);
-
+svn_fs_x__with_rep_cache_lock(svn_fs_t *fs,
+ svn_error_t *(*body)(void *baton,
+ apr_pool_t *pool),
+ void *baton,
+ apr_pool_t *pool);
#ifdef __cplusplus
}
#endif /* __cplusplus */