summaryrefslogtreecommitdiff
path: root/lib/tdb/common/transaction.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2010-02-17 15:42:15 +1030
committerRusty Russell <rusty@rustcorp.com.au>2010-02-17 15:42:15 +1030
commitfca1621965c547e2d076eca2a2599e9629f91266 (patch)
tree94abacb92dfa97c70e2137e9a2a6b63f2c73938c /lib/tdb/common/transaction.c
parentcaaf5c6baa1a4f340c1f38edd99b3a8b56621b8b (diff)
downloadsamba-fca1621965c547e2d076eca2a2599e9629f91266.tar.gz
samba-fca1621965c547e2d076eca2a2599e9629f91266.tar.bz2
samba-fca1621965c547e2d076eca2a2599e9629f91266.zip
tdb: tdb_allrecord_lock/tdb_allrecord_unlock/tdb_allrecord_upgrade
Centralize locking of all chains of the tdb; rename _tdb_lockall to tdb_allrecord_lock and _tdb_unlockall to tdb_allrecord_unlock, and tdb_brlock_upgrade to tdb_allrecord_upgrade. Then we use this in the transaction code. Unfortunately, if the transaction code records that it has grabbed the allrecord lock read-only, write locks will fail, so we treat this upgradable lock as a write lock, and mark it as upgradable using the otherwise-unused offset field. One subtlety: now the transaction code is using the allrecord_lock, the tdb_release_extra_locks() function drops it for us, so we no longer need to do it manually in _tdb_transaction_cancel. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'lib/tdb/common/transaction.c')
-rw-r--r--lib/tdb/common/transaction.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/lib/tdb/common/transaction.c b/lib/tdb/common/transaction.c
index 69a622dae0..c9718a59b3 100644
--- a/lib/tdb/common/transaction.c
+++ b/lib/tdb/common/transaction.c
@@ -502,10 +502,9 @@ int tdb_transaction_start(struct tdb_context *tdb)
/* get a read lock from the freelist to the end of file. This
is upgraded to a write lock during the commit */
- if (tdb_brlock(tdb, F_RDLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT) == -1) {
+ if (tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, true) == -1) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n"));
- tdb->ecode = TDB_ERR_LOCK;
- goto fail;
+ goto fail_allrecord_lock;
}
/* setup a copy of the hash table heads so the hash scan in
@@ -538,7 +537,8 @@ int tdb_transaction_start(struct tdb_context *tdb)
return 0;
fail:
- tdb_brunlock(tdb, F_RDLCK, FREELIST_TOP, 0);
+ tdb_allrecord_unlock(tdb, F_RDLCK, false);
+fail_allrecord_lock:
tdb_transaction_unlock(tdb, F_WRLCK);
SAFE_FREE(tdb->transaction->blocks);
SAFE_FREE(tdb->transaction->hash_heads);
@@ -621,7 +621,6 @@ static int _tdb_transaction_cancel(struct tdb_context *tdb, int ltype)
/* restore the normal io methods */
tdb->methods = tdb->transaction->io_methods;
- tdb_brunlock(tdb, ltype, FREELIST_TOP, 0);
tdb_transaction_unlock(tdb, F_WRLCK);
SAFE_FREE(tdb->transaction->hash_heads);
SAFE_FREE(tdb->transaction);
@@ -938,9 +937,8 @@ static int _tdb_transaction_prepare_commit(struct tdb_context *tdb)
}
/* upgrade the main transaction lock region to a write lock */
- if (tdb_brlock_upgrade(tdb, FREELIST_TOP, 0) == -1) {
+ if (tdb_allrecord_upgrade(tdb) == -1) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: failed to upgrade hash locks\n"));
- tdb->ecode = TDB_ERR_LOCK;
_tdb_transaction_cancel(tdb, F_RDLCK);
return -1;
}