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. */