diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2010-02-17 15:42:15 +1030 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-02-17 15:42:15 +1030 |
commit | fca1621965c547e2d076eca2a2599e9629f91266 (patch) | |
tree | 94abacb92dfa97c70e2137e9a2a6b63f2c73938c /lib/tdb/common/transaction.c | |
parent | caaf5c6baa1a4f340c1f38edd99b3a8b56621b8b (diff) | |
download | samba-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.c | 12 |
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; } |