You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/01/22 01:20:00 UTC

svn commit: r1726133 - in /subversion/branches/parallel-put/subversion/libsvn_fs_x: ./ transaction.c

Author: stefan2
Date: Fri Jan 22 00:20:00 2016
New Revision: 1726133

URL: http://svn.apache.org/viewvc?rev=1726133&view=rev
Log:
On the parallel-put branch:
Complete porting the new feature to FSX.  Merge the recent fixes
(revisions 1726073, 1726075, 1726078 and 1726105) from FSFS to FSX
and resolve various text conflicts.

Modified:
    subversion/branches/parallel-put/subversion/libsvn_fs_x/   (props changed)
    subversion/branches/parallel-put/subversion/libsvn_fs_x/transaction.c

Propchange: subversion/branches/parallel-put/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jan 22 00:20:00 2016
@@ -62,7 +62,7 @@
 /subversion/branches/multi-layer-moves/subversion/libsvn_fs_x:1239019-1300930
 /subversion/branches/nfc-nfd-aware-client/subversion/libsvn_fs_x:870276,870376
 /subversion/branches/node_pool/subversion/libsvn_fs_x:1304828-1305388
-/subversion/branches/parallel-put/subversion/libsvn_fs_fs:1719883-1719884,1719892-1719893,1719905,1719907,1719911,1720045,1720299
+/subversion/branches/parallel-put/subversion/libsvn_fs_fs:1719883-1719884,1719892-1719893,1719905,1719907,1719911,1720045,1720299,1726073,1726075,1726078,1726105
 /subversion/branches/patch-exec/subversion/libsvn_fs_x:1692717-1705390
 /subversion/branches/performance/subversion/libsvn_fs_x:979193,980118,981087,981090,981189,981194,981287,981684,981827,982043,982355,983398,983406,983430,983474,983488,983490,983760,983764,983766,983770,984927,984973,984984,985014,985037,985046,985472,985477,985482,985487-985488,985493,985497,985500,985514,985601,985603,985606,985669,985673,985695,985697,986453,986465,986485,986491-986492,986517,986521,986605,986608,986817,986832,987865,987868-987869,987872,987886-987888,987893,988319,988898,990330,990533,990535-990537,990541,990568,990572,990574-990575,990600,990759,992899,992904,992911,993127,993141,994956,995478,995507,995603,998012,998858,999098,1001413,1001417,1004291,1022668,1022670,1022676,1022715,1022719,1025660,1025672,1027193,1027203,1027206,1027214,1027227,1028077,1028092,1028094,1028104,1028107,1028111,1028354,1029038,1029042-1029043,1029054-1029055,1029062-1029063,1029078,1029080,1029090,1029092-1029093,1029111,1029151,1029158,1029229-1029230,1029232,1029335-1029336,102
 9339-1029340,1029342,1029344,1030763,1030827,1031203,1031235,1032285,1032333,1033040,1033057,1033294,1035869,1035882,1039511,1043705,1053735,1056015,1066452,1067683,1067697-1078365
 /subversion/branches/pin-externals/subversion/libsvn_fs_x:1643757-1659392

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/transaction.c?rev=1726133&r1=1726132&r2=1726133&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/transaction.c Fri Jan 22 00:20:00 2016
@@ -83,23 +83,51 @@ svn_fs_x__txn_get_id(svn_fs_txn_t *txn)
 
 /* Functions for working with shared transaction data. */
 
-/* Set *TXN_P to the transaction object for transaction TXN_ID from the
-   transaction list of filesystem FS (which must already be locked via the
-   txn_list_lock mutex).  If the transaction does not exist in the list,
-   then create a new transaction object and return it (if CREATE_NEW is
-   true) or return NULL (otherwise). */
+/* Obtain a lock on the transaction list of filesystem FS, call BODY
+   with FS, BATON, and POOL, and then unlock the transaction list.
+   Return what BODY returned. */
 static svn_error_t *
-get_shared_txn(svn_fs_x__shared_txn_data_t **txn_p,
-               svn_fs_t *fs,
-               svn_fs_x__txn_id_t txn_id,
-               svn_boolean_t create_new)
+with_txnlist_lock(svn_fs_t *fs,
+                  svn_error_t *(*body)(svn_fs_t *fs,
+                                       const void *baton,
+                                       apr_pool_t *pool),
+                  const void *baton,
+                  apr_pool_t *pool)
+{
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+  svn_fs_x__shared_data_t *ffsd = ffd->shared;
+
+  SVN_MUTEX__WITH_LOCK(ffsd->txn_list_lock,
+                       body(fs, baton, pool));
+
+  return SVN_NO_ERROR;
+}
+
+
+/* Baton type to be used with get_shared_txn_body. It simply provides all
+   parameters passed to get_shared_txn that with_txnlist_lock does not
+   pass through. */
+typedef struct get_shared_txn_baton_t
+{
+  svn_fs_x__shared_txn_data_t **txn_p;
+  svn_fs_x__txn_id_t txn_id;
+  svn_boolean_t create_new;
+} get_shared_txn_baton_t;
+
+/* Implements with_txnlist_lock::body and provides the functionality
+   of get_shared_txn.  To be executed with the txn list mutex held. */
+static svn_error_t *
+get_shared_txn_body(svn_fs_t *fs,
+                    const void *baton,
+                    apr_pool_t *pool)
 {
+  const get_shared_txn_baton_t *b = baton;
   svn_fs_x__data_t *ffd = fs->fsap_data;
   svn_fs_x__shared_data_t *ffsd = ffd->shared;
   svn_fs_x__shared_txn_data_t *txn;
 
   for (txn = ffsd->txns; txn; txn = txn->next)
-    if (txn->txn_id == txn_id)
+    if (txn->txn_id == b->txn_id)
       break;
 
   if (txn)
@@ -121,20 +149,20 @@ get_shared_txn(svn_fs_x__shared_txn_data
          return svn_error_createf(SVN_ERR_FS_TXN_CONCURRENCY_MISMATCH, NULL,
                                   _("Cannot reopen transaction '%s' "
                                     "without concurrent write support"),
-                                  svn_fs_x__txn_name(txn_id, fs->pool));
+                                  svn_fs_x__txn_name(b->txn_id, fs->pool));
        else if (!txn->is_concurrent && ffd->concurrent_txns)
          return svn_error_createf(SVN_ERR_FS_TXN_CONCURRENCY_MISMATCH, NULL,
                                   _("Cannot reopen transaction '%s' "
                                     "with concurrent write support"),
-                                  svn_fs_x__txn_name(txn_id, fs->pool));
+                                  svn_fs_x__txn_name(b->txn_id, fs->pool));
 
-      *txn_p = txn;
+      *b->txn_p = txn;
       return SVN_NO_ERROR;
     }
  
-  if (!create_new)
+  if (!b->create_new)
     {
-      *txn_p = NULL;
+      *b->txn_p = NULL;
       return SVN_NO_ERROR;
     }
 
@@ -165,7 +193,7 @@ get_shared_txn(svn_fs_x__shared_txn_data
       SVN_ERR(svn_mutex__init(&txn->lock, txn->is_concurrent, txn->pool));
     }
 
-  txn->txn_id = txn_id;
+  txn->txn_id = b->txn_id;
   txn->being_written = FALSE;
 
   /* Link this transaction into the head of the list.  We will typically
@@ -176,11 +204,30 @@ get_shared_txn(svn_fs_x__shared_txn_data
   ffsd->txns = txn;
 
   /* Done. */
-  *txn_p = txn;
+  *b->txn_p = txn;
 
   return SVN_NO_ERROR;
 }
 
+/* Set *TXN_P to the transaction object for transaction TXN_ID from the
+   transaction list of filesystem FS.  If the transaction does not exist
+   in the list, then create a new transaction object and return it (if
+   CREATE_NEW is true) or return NULL (otherwise). */
+static svn_error_t *
+get_shared_txn(svn_fs_x__shared_txn_data_t **txn_p,
+               svn_fs_t *fs,
+               svn_fs_x__txn_id_t txn_id,
+               svn_boolean_t create_new,
+               apr_pool_t *pool)
+{
+  get_shared_txn_baton_t baton;
+  baton.txn_p = txn_p;
+  baton.txn_id = txn_id;
+  baton.create_new = create_new;
+
+  return with_txnlist_lock(fs, get_shared_txn_body, &baton, pool);
+}
+
 /* Free the transaction object for transaction TXN_ID, and remove it
    from the transaction list of filesystem FS (which must already be
    locked via the txn_list_lock mutex).  Do nothing if the transaction
@@ -214,27 +261,6 @@ free_shared_txn(svn_fs_t *fs, svn_fs_x__
 }
 
 
-/* Obtain a lock on the transaction list of filesystem FS, call BODY
-   with FS, BATON, and POOL, and then unlock the transaction list.
-   Return what BODY returned. */
-static svn_error_t *
-with_txnlist_lock(svn_fs_t *fs,
-                  svn_error_t *(*body)(svn_fs_t *fs,
-                                       const void *baton,
-                                       apr_pool_t *pool),
-                  const void *baton,
-                  apr_pool_t *pool)
-{
-  svn_fs_x__data_t *ffd = fs->fsap_data;
-  svn_fs_x__shared_data_t *ffsd = ffd->shared;
-
-  SVN_MUTEX__WITH_LOCK(ffsd->txn_list_lock,
-                       body(fs, baton, pool));
-
-  return SVN_NO_ERROR;
-}
-
-
 /* Get a lock on empty file LOCK_FILENAME, creating it in RESULT_POOL. */
 static svn_error_t *
 get_lock_on_filesystem(const char *lock_filename,
@@ -555,48 +581,44 @@ svn_fs_x__with_all_locks(svn_fs_t *fs,
 }
 
 
-/* A structure used by unlock_proto_rev() and unlock_proto_rev_body(),
-   which see. */
-typedef struct unlock_proto_rev_baton_t
-{
-  svn_fs_x__txn_id_t txn_id;
-  void *lockcookie;
-} unlock_proto_rev_baton_t;
+/* Unlock the prototype revision file for transaction TXN_ID in filesystem
+   FS using cookie LOCKCOOKIE.  The original prototype revision file must
+   have been closed _before_ calling this function.
 
-/* Callback used in the implementation of unlock_proto_rev(). */
+   Perform temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
-unlock_proto_rev_body(svn_fs_t *fs,
-                      const void *baton,
-                      apr_pool_t *scratch_pool)
+unlock_proto_rev(svn_fs_t *fs,
+                 svn_fs_x__txn_id_t txn_id,
+                 void *lockcookie,
+                 apr_pool_t *scratch_pool)
 {
-  const unlock_proto_rev_baton_t *b = baton;
-  apr_file_t *lockfile = b->lockcookie;
+  apr_file_t *lockfile = lockcookie;
   apr_status_t apr_err;
   svn_fs_x__shared_txn_data_t *txn;
 
-  SVN_ERR(get_shared_txn(&txn, fs, b->txn_id, FALSE));
+  SVN_ERR(get_shared_txn(&txn, fs, txn_id, FALSE, scratch_pool));
 
   if (!txn)
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Can't unlock unknown transaction '%s'"),
-                             svn_fs_x__txn_name(b->txn_id, scratch_pool));
+                             svn_fs_x__txn_name(txn_id, scratch_pool));
   if (!txn->being_written)
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Can't unlock nonlocked transaction '%s'"),
-                             svn_fs_x__txn_name(b->txn_id, scratch_pool));
+                             svn_fs_x__txn_name(txn_id, scratch_pool));
 
   apr_err = apr_file_unlock(lockfile);
   if (apr_err)
     return svn_error_wrap_apr
       (apr_err,
        _("Can't unlock prototype revision lockfile for transaction '%s'"),
-       svn_fs_x__txn_name(b->txn_id, scratch_pool));
+       svn_fs_x__txn_name(txn_id, scratch_pool));
   apr_err = apr_file_close(lockfile);
   if (apr_err)
     return svn_error_wrap_apr
       (apr_err,
        _("Can't close prototype revision lockfile for transaction '%s'"),
-       svn_fs_x__txn_name(b->txn_id, scratch_pool));
+       svn_fs_x__txn_name(txn_id, scratch_pool));
 
   txn->being_written = FALSE;
 
@@ -605,32 +627,6 @@ unlock_proto_rev_body(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
-/* Unlock the prototype revision file for transaction TXN_ID in filesystem
-   FS using cookie LOCKCOOKIE.  The original prototype revision file must
-   have been closed _before_ calling this function.
-
-   Perform temporary allocations in SCRATCH_POOL. */
-static svn_error_t *
-unlock_proto_rev(svn_fs_t *fs,
-                 svn_fs_x__txn_id_t txn_id,
-                 void *lockcookie,
-                 apr_pool_t *scratch_pool)
-{
-  unlock_proto_rev_baton_t b;
-
-  b.txn_id = txn_id;
-  b.lockcookie = lockcookie;
-  return with_txnlist_lock(fs, unlock_proto_rev_body, &b, scratch_pool);
-}
-
-/* A structure used by get_writable_proto_rev() and
-   get_writable_proto_rev_body(), which see. */
-typedef struct get_writable_proto_rev_baton_t
-{
-  void **lockcookie;
-  svn_fs_x__txn_id_t txn_id;
-} get_writable_proto_rev_baton_t;
-
 /* Acquire the proto-rev lock for TXN in FS and set *LOCKCOOKIE to cookie. 
  * Use POOL for all allocations. */
 static svn_error_t *
@@ -707,19 +703,25 @@ lock_proto_rev_body(void **lockcookie,
   return SVN_NO_ERROR;
 }
 
-/* Callback used in the implementation of get_writable_proto_rev(). */
+/* Lock the proto-rev file for transaction TXN_ID in FS.  This is
+ * basically taking out the per-transaction mutex.  Must be paired
+ * with unlock_proto_rev().  Sets *LOCKCOOKIE to some opaque cookie
+ * that will be consumed by the unlock function.
+ * Uses POOL for allocations. */
 static svn_error_t *
-get_writable_proto_rev_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)
+lock_proto_rev(void **lockcookie,
+               svn_fs_t *fs,
+               svn_fs_x__txn_id_t txn_id,
+               apr_pool_t *pool)
 {
-  const get_writable_proto_rev_baton_t *b = baton;
   svn_fs_x__shared_txn_data_t *txn;
   svn_error_t *err;
 
-  SVN_ERR(get_shared_txn(&txn, fs, b->txn_id, TRUE));
+  SVN_ERR(get_shared_txn(&txn, fs, txn_id, TRUE, pool));
 
   /* Lock mutex (if even enabled) and file. */
   SVN_ERR(svn_mutex__lock(txn->lock));
-  err = lock_proto_rev_body(b->lockcookie, fs, txn, pool);
+  err = lock_proto_rev_body(lockcookie, fs, txn, pool);
   if (err)
     return svn_mutex__unlock(txn->lock, err);
 
@@ -746,20 +748,16 @@ svn_fs_x__with_txn_auto_lock(svn_fs_t *f
    */
   if (ffd->concurrent_txns)
     {
+      svn_error_t *err1, *err2;
       void *lockcookie;
 
-      get_writable_proto_rev_baton_t 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)));
+      SVN_ERR(lock_proto_rev(&lockcookie, fs, txn_id, scratch_pool));
+
+      /* Be sure to always unlock the transaction, regardless of BODY's
+         return value. */
+      err1 = body(baton, scratch_pool);
+      err2 = unlock_proto_rev(fs, txn_id, lockcookie, scratch_pool);
+      SVN_ERR(svn_error_compose_create(err1, err2));
     }
   else
     {
@@ -827,14 +825,10 @@ get_writable_proto_rev(apr_file_t **file
                        svn_fs_x__txn_id_t txn_id,
                        apr_pool_t *pool)
 {
-  get_writable_proto_rev_baton_t b;
   svn_error_t *err;
   apr_off_t end_offset = 0;
 
-  b.lockcookie = lockcookie;
-  b.txn_id = txn_id;
-
-  SVN_ERR(with_txnlist_lock(fs, get_writable_proto_rev_body, &b, pool));
+  SVN_ERR(lock_proto_rev(lockcookie, fs, txn_id, pool));
 
   /* Now open the prototype revision file and seek to the end. */
   err = svn_io_file_open(file,
@@ -3756,7 +3750,6 @@ get_writable_final_rev(apr_file_t **file
                        svn_fs_x__batch_fsync_t *batch,
                        apr_pool_t *scratch_pool)
 {
-  get_writable_proto_rev_baton_t baton;
   apr_off_t end_offset = 0;
   void *lockcookie;
 
@@ -3766,11 +3759,7 @@ get_writable_final_rev(apr_file_t **file
     = svn_fs_x__path_rev(fs, revision, scratch_pool);
 
   /* Acquire exclusive access to the proto-rev file. */
-  baton.lockcookie = &lockcookie;
-  baton.txn_id = txn_id;
-
-  SVN_ERR(with_txnlist_lock(fs, get_writable_proto_rev_body, &baton,
-                            scratch_pool));
+  SVN_ERR(lock_proto_rev(&lockcookie, fs, txn_id, scratch_pool));
 
   /* Move the proto-rev file to its final location as revision data file.
      After that, we don't need to protect it anymore and can unlock it. */