Branko Čibej wrote on Wed, Mar 27, 2013 at 12:57:13 +0100:
> On 27.03.2013 07:54, Daniel Shahaf wrote:
> > Branko Čibej wrote on Wed, Mar 27, 2013 at 05:14:51 +0100:
> >> On 26.03.2013 23:11, Daniel Shahaf wrote:
> >>> [[[
> >>> Run the per-revision verify code on a transaction just before it becomes
> >>> a revision. The intent is to catch corruption bugs as early as possible.
> >>>
> >>> * subversion/libsvn_fs/fs-loader.c
> >>> (svn_fs_commit_txn): As above.
> >>> ]]]
> >>>
> >>> Maybe this should be optional behaviour in release mode, too?
And here's the new one. (I haven't colored the section name bikeshed
yet, nor moved the new macros to svn_fs.h.)
I wonder whether doing a verify of a revision root as the very last
thing before incrementing db/current -- specifically, in commit_body()
immediately before the sole call to write_final_current() --- would be
better. Thoughts?
[[[
Index: subversion/libsvn_fs/fs-loader.c
===================================================================
--- subversion/libsvn_fs/fs-loader.c (revision 1461743)
+++ subversion/libsvn_fs/fs-loader.c (working copy)
@@ -1,3 +1,6 @@
+#define SVN_FS_CONFIG_SECTION_FOO "foo"
+#define SVN_FS_CONFIG_OPTION_VERIFY_AT_COMMIT "verify-at-commit"
+
/*
* fs_loader.c: Front-end to the various FS back ends
*
@@ -32,6 +35,7 @@
#include "svn_hash.h"
#include "svn_ctype.h"
+#include "svn_config.h"
#include "svn_types.h"
#include "svn_dso.h"
#include "svn_version.h"
@@ -57,6 +61,7 @@
#endif
#define FS_TYPE_FILENAME "fs-type"
+#define CONFIG_FILENAME "fs.conf"
/* A pool common to all FS objects. See the documentation on the
open/create functions in fs-loader.h and for svn_fs_initialize(). */
@@ -338,6 +343,26 @@ write_fs_type(const char *path, const char *fs_typ
return svn_error_trace(svn_io_file_close(file, pool));
}
+static svn_error_t *
+write_config(const char *path, apr_pool_t *pool)
+{
+ static const char * const fs_conf_contents =
+#define NL APR_EOL_STR
+"### This file controls backend-independent filesystem configuration." NL
+"" NL
+"[" SVN_FS_CONFIG_SECTION_FOO "]" NL
+"### When set, Subversion will run the equivalent of 'svnadmin verify -r'" NL
+"### on each transaction (commit-in-progress) just before it becomes" NL
+"### a revision. This may slow down commits, since the cost of" NL
+"### verification is proportional to the size of the commit (e.g., number" NL
+"### of files 'svn log -q -v -r N' shows)." NL
+"# " SVN_FS_CONFIG_OPTION_VERIFY_AT_COMMIT " = false" NL
+;
+#undef NL
+ SVN_ERR(svn_io_file_create(svn_dirent_join(path, CONFIG_FILENAME, pool),
+ fs_conf_contents, pool));
+ return SVN_NO_ERROR;
+}
/* --- Functions for operating on filesystems by pathname --- */
@@ -414,6 +439,11 @@ fs_new(apr_hash_t *fs_config, apr_pool_t *pool)
fs->vtable = NULL;
fs->fsap_data = NULL;
fs->uuid = NULL;
+#ifdef SVN_DEBUG
+ fs->verify_at_commit = TRUE;
+#else
+ fs->verify_at_commit = FALSE;
+#endif
return fs;
}
@@ -445,6 +475,7 @@ svn_fs_create(svn_fs_t **fs_p, const char *path, a
/* Create the FS directory and write out the fsap-name file. */
SVN_ERR(svn_io_dir_make_sgid(path, APR_OS_DEFAULT, pool));
SVN_ERR(write_fs_type(path, fs_type, pool));
+ SVN_ERR(write_config(path, pool));
/* Perform the actual creation. */
*fs_p = fs_new(fs_config, pool);
@@ -459,9 +490,20 @@ svn_fs_open(svn_fs_t **fs_p, const char *path, apr
apr_pool_t *pool)
{
fs_library_vtable_t *vtable;
+ svn_config_t *config;
SVN_ERR(fs_library_vtable(&vtable, path, pool));
*fs_p = fs_new(fs_config, pool);
+
+ SVN_ERR(svn_config_read2(&config,
+ svn_dirent_join(path, CONFIG_FILENAME, pool),
+ FALSE /* must_exist */, TRUE /* case-sensitive */,
+ pool));
+ SVN_ERR(svn_config_get_bool(config, &(*fs_p)->verify_at_commit,
+ SVN_FS_CONFIG_SECTION_FOO,
+ SVN_FS_CONFIG_OPTION_VERIFY_AT_COMMIT,
+ (*fs_p)->verify_at_commit));
+
SVN_MUTEX__WITH_LOCK(common_pool_lock,
vtable->open_fs(*fs_p, path, pool, common_pool));
return SVN_NO_ERROR;
@@ -750,22 +792,18 @@ svn_fs_commit_txn(const char **conflict_p, svn_rev
svn_fs_txn_t *txn, apr_pool_t *pool)
{
svn_error_t *err;
-#if defined(PACK_AFTER_EVERY_COMMIT) || defined(SVN_DEBUG)
- svn_fs_root_t *txn_root;
-#endif
+ svn_fs_t *fs = txn->fs;
*new_rev = SVN_INVALID_REVNUM;
-#if defined(PACK_AFTER_EVERY_COMMIT) || defined(SVN_DEBUG)
- SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-#endif
+ if (fs->verify_at_commit)
+ {
+ /* ### TODO: should this run just before incrementing 'current'? */
+ svn_fs_root_t *txn_root;
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_verify_root(txn_root, pool));
+ }
-#ifdef SVN_DEBUG
- /* ### TODO: add db/fs.conf with a knob to enable this in release builds */
- /* ### TODO: should this run just before incrementing 'current'? */
- SVN_ERR(svn_fs_verify_root(txn_root, pool));
-#endif
-
err = txn->vtable->commit(conflict_p, new_rev, txn, pool);
#ifdef SVN_DEBUG
@@ -784,7 +822,6 @@ svn_fs_commit_txn(const char **conflict_p, svn_rev
#ifdef PACK_AFTER_EVERY_COMMIT
{
- svn_fs_t *fs = svn_fs_root_fs(txn_root);
const char *fs_path = svn_fs_path(fs, pool);
err = svn_fs_pack(fs_path, NULL, NULL, NULL, NULL, pool);
if (err && err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)
Index: subversion/libsvn_fs/fs-loader.h
===================================================================
--- subversion/libsvn_fs/fs-loader.h (revision 1461737)
+++ subversion/libsvn_fs/fs-loader.h (working copy)
@@ -407,6 +407,9 @@ struct svn_fs_t
/* UUID, stored by open(), create(), and set_uuid(). */
const char *uuid;
+
+ /* Parsed contents of fs.conf */
+ svn_boolean_t verify_at_commit;
};
]]]
Received on 2013-03-27 22:32:08 CET