You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2015/05/13 11:47:52 UTC
svn commit: r1679169 - in /subversion/trunk/subversion: libsvn_fs_fs/fs.c
libsvn_fs_fs/rep-cache-db.sql libsvn_fs_fs/rep-cache.c
libsvn_fs_fs/rep-cache.h tests/libsvn_fs/fs-test.c
Author: danielsh
Date: Wed May 13 09:47:51 2015
New Revision: 1679169
URL: http://svn.apache.org/r1679169
Log:
fsfs freeze: Unlock rep-cache.db as part of unfreezing.
Without this, after calling svn_fs_freeze(fs), calling svn_fs_commit_txn() or
svn_fs_freeze() on that svn_fs_t object would fail with an SQLite error:
subversion/tests/libsvn_fs/fs-test.c:124: (apr_err=SVN_ERR_SQLITE_ERROR)
svn_tests: E200030: commit succeeded but something else failed
...
subversion/libsvn_subr/sqlite.c:360: (apr_err=SVN_ERR_SQLITE_ERROR)
svn_tests: E200030: sqlite[S1]: cannot start a transaction within a transaction
* subversion/tests/libsvn_fs/fs-test.c
(freeze_and_commit): New test.
(noop_freeze_func): New helper function.
* subversion/libsvn_fs_fs/rep-cache.h
(svn_fs_fs__lock_rep_cache): Remove declaration.
(svn_fs_fs__with_rep_cache_lock): New declaration.
* subversion/libsvn_fs_fs/rep-cache-db.sql
(STMT_UNLOCK_REP): New statement.
* subversion/libsvn_fs_fs/fs.c
(fs_freeze_body): Unlock the rep cache after calling freeze_func().
* subversion/libsvn_fs_fs/rep-cache.c
(svn_fs_fs__lock_rep_cache): Demote to a static function, renaming to..
(lock_rep_cache): .. this.
(unlock_rep_cache): New static function.
(svn_fs_fs__with_rep_cache_lock): New function.
Modified:
subversion/trunk/subversion/libsvn_fs_fs/fs.c
subversion/trunk/subversion/libsvn_fs_fs/rep-cache-db.sql
subversion/trunk/subversion/libsvn_fs_fs/rep-cache.c
subversion/trunk/subversion/libsvn_fs_fs/rep-cache.h
subversion/trunk/subversion/tests/libsvn_fs/fs-test.c
Modified: subversion/trunk/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs.c?rev=1679169&r1=1679168&r2=1679169&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs.c Wed May 13 09:47:51 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/trunk/subversion/libsvn_fs_fs/rep-cache-db.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1679169&r1=1679168&r2=1679169&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/rep-cache-db.sql (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/rep-cache-db.sql Wed May 13 09:47:51 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/trunk/subversion/libsvn_fs_fs/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/rep-cache.c?rev=1679169&r1=1679168&r2=1679169&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/rep-cache.c Wed May 13 09:47:51 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/trunk/subversion/libsvn_fs_fs/rep-cache.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/rep-cache.h?rev=1679169&r1=1679168&r2=1679169&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/rep-cache.h (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/rep-cache.h Wed May 13 09:47:51 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/trunk/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs/fs-test.c?rev=1679169&r1=1679168&r2=1679169&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs/fs-test.c Wed May 13 09:47:51 2015
@@ -6891,6 +6891,53 @@ test_internal_txn_props(const svn_test_o
return SVN_NO_ERROR;
}
+/* This function implements svn_fs_freeze_func_t. */
+static svn_error_t *
+noop_freeze_func(void *baton, apr_pool_t *pool)
+{
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+freeze_and_commit(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ svn_revnum_t new_rev = 0;
+ apr_pool_t *subpool = svn_pool_create(pool);
+
+ SVN_ERR(svn_test__create_fs(&fs, "test-freeze-and-commit", opts, subpool));
+
+ /* This test used to FAIL with an SQLite error since svn_fs_freeze()
+ * wouldn't unlock rep-cache.db. Therefore, part of the role of creating
+ * the Greek tree is to create a rep-cache.db, in order to test that
+ * svn_fs_freeze() unlocks it. */
+
+ /* r1: Commit the Greek tree. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, new_rev, subpool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
+ SVN_ERR(svn_test__create_greek_tree(txn_root, subpool));
+ SVN_ERR(test_commit_txn(&new_rev, txn, NULL, subpool));
+
+ /* Freeze and unfreeze. */
+ SVN_ERR(svn_fs_freeze(fs, noop_freeze_func, NULL, pool));
+
+ /* And the same once again, for good measure. */
+ SVN_ERR(svn_fs_freeze(fs, noop_freeze_func, NULL, pool));
+
+ /* Make some commit. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, new_rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_change_node_prop(txn_root, "", "temperature",
+ svn_string_create("310.05", pool),
+ pool));
+ SVN_ERR(test_commit_txn(&new_rev, txn, NULL, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* ------------------------------------------------------------------------ */
/* The test table. */
@@ -7023,6 +7070,8 @@ static struct svn_test_descriptor_t test
"test setting and getting internal txn props"),
SVN_TEST_OPTS_PASS(check_txn_related,
"test svn_fs_check_related for transactions"),
+ SVN_TEST_OPTS_PASS(freeze_and_commit,
+ "freeze and commit"),
SVN_TEST_NULL
};