Author: stefan2
Date: Mon Dec 14 13:29:23 2015
New Revision: 1719907

URL: http://svn.apache.org/viewvc?rev=1719907&view=rev
Log:
On the parallel-put branch:
Synchronize meta-data changes when concurrently writing text reps.

Note that propsets are still not synchronized.

* subversion/libsvn_fs_fs/transaction.h
  (svn_fs_fs__with_txn_auto_lock): Declare a new internal API.

* subversion/libsvn_fs_fs/transaction.c
  (svn_fs_fs__with_txn_auto_lock): Implement.

* subversion/libsvn_fs_fs/tree.c
  (fs_apply_textdelta,
   fs_apply_text): Serialize all preparation, i.e. tree the updates
                   and the change list updates.

Modified:
    subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.c
    subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.h
    subversion/branches/parallel-put/subversion/libsvn_fs_fs/tree.c

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.c?rev=1719907&r1=1719906&r2=1719907&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.c 
(original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.c Mon 
Dec 14 13:29:23 2015
@@ -452,6 +452,49 @@ get_writable_proto_rev_body(svn_fs_t *fs
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_fs_fs__with_txn_auto_lock(svn_fs_t *fs,
+                              const svn_fs_fs__id_part_t *txn_id,
+                              svn_error_t *(*body)(void *baton,
+                                                   apr_pool_t *pool),
+                              void *baton,
+                              apr_pool_t *scratch_pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+
+  /* In non-concurrent mode, we only serialize via get_writable_proto_rev
+   * and there shall be no additional locking overhead.  Moreover, that
+   * file lock is being held for a long time and would require us to add
+   * special handling for recursion etc.
+   *
+   * Therefore, we only lock in concurrent mode where locks are blocking
+   * and short-lived.
+   */
+  if (ffd->concurrent_txns)
+    {
+      void *lockcookie;
+
+      struct get_writable_proto_rev_baton b;
+      b.lockcookie = &lockcookie;
+      b.txn_id = *txn_id;
+
+      SVN_ERR(with_txnlist_lock(fs, get_writable_proto_rev_body, &b,
+                                scratch_pool));
+
+      /* Now open the prototype revision file and seek to the end. */
+      SVN_ERR(svn_error_compose_create(body(baton, scratch_pool),
+                                       unlock_proto_rev(fs, txn_id,
+                                                        lockcookie,
+                                                        scratch_pool)));
+    }
+  else
+    {
+      SVN_ERR(body(baton, scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Make sure the length ACTUAL_LENGTH of the proto-revision file PROTO_REV
    of transaction TXN_ID in filesystem FS matches the proto-index file.
    Trim any crash / failure related extra data from the proto-rev file.

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.h?rev=1719907&r1=1719906&r2=1719907&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.h 
(original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_fs/transaction.h Mon 
Dec 14 13:29:23 2015
@@ -30,6 +30,19 @@
 const svn_fs_fs__id_part_t *
 svn_fs_fs__txn_get_id(svn_fs_txn_t *txn);
 
+/* Acquire the necessary locks for transaction TXN_ID in FS, execute BODY
+   with BATON and release the locks.  Use SCRATCH_POOL for allocations.
+
+   Note that this will only take out any locks when we are in concurrent
+   transaction mode where additional access serialization is needed. */
+svn_error_t *
+svn_fs_fs__with_txn_auto_lock(svn_fs_t *fs,
+                              const svn_fs_fs__id_part_t *txn_id,
+                              svn_error_t *(*body)(void *baton,
+                                                   apr_pool_t *pool),
+                              void *baton,
+                              apr_pool_t *scratch_pool);
+
 /* Store NODEREV as the node-revision for the node whose id is ID in
    FS, after setting its is_fresh_txn_root to FRESH_TXN_ROOT.  Do any
    necessary temporary allocation in POOL. */

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_fs/tree.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_fs/tree.c?rev=1719907&r1=1719906&r2=1719907&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_fs/tree.c Mon Dec 14 
13:29:23 2015
@@ -3072,6 +3072,8 @@ fs_apply_textdelta(svn_txdelta_window_ha
                    svn_checksum_t *result_checksum,
                    apr_pool_t *pool)
 {
+  const svn_fs_fs__id_part_t *txn_id = root_txn_id(root);
+
   txdelta_baton_t *tb = apr_pcalloc(pool, sizeof(*tb));
 
   tb->root = root;
@@ -3080,7 +3082,9 @@ fs_apply_textdelta(svn_txdelta_window_ha
   tb->base_checksum = svn_checksum_dup(base_checksum, pool);
   tb->result_checksum = svn_checksum_dup(result_checksum, pool);
 
-  SVN_ERR(apply_textdelta(tb, pool));
+  SVN_ERR(svn_fs_fs__with_txn_auto_lock(root->fs, txn_id,
+                                        apply_textdelta, tb,
+                                        pool));
 
   *contents_p = window_consumer;
   *contents_baton_p = tb;
@@ -3205,6 +3209,8 @@ fs_apply_text(svn_stream_t **contents_p,
               svn_checksum_t *result_checksum,
               apr_pool_t *pool)
 {
+  const svn_fs_fs__id_part_t *txn_id = root_txn_id(root);
+
   struct text_baton_t *tb = apr_pcalloc(pool, sizeof(*tb));
 
   tb->root = root;
@@ -3212,7 +3218,9 @@ fs_apply_text(svn_stream_t **contents_p,
   tb->pool = pool;
   tb->result_checksum = svn_checksum_dup(result_checksum, pool);
 
-  SVN_ERR(apply_text(tb, pool));
+  SVN_ERR(svn_fs_fs__with_txn_auto_lock(root->fs, txn_id,
+                                        apply_text, tb,
+                                        pool));
 
   *contents_p = tb->stream;
   return SVN_NO_ERROR;


Reply via email to