1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

Port from SAMBA tdb: commit 54a51839ea Author: Rusty Russell <rusty@rustcorp.com.au> Date: Sat Jul 18 15:28:58 2009 +0930

Make tdb transaction lock recursive (samba version)

    This patch replaces 6ed27edbcd and
    1a416ff13c, which fixed the bug where traversals
    inside transactions would release the transaction lock early.

    This solution is more general, and solves the more minor symptom that nested
    traversals would also release the transaction lock early.  (It was also suggestd in
    Volker's comment in 6ed27ed).

    This patch also applies to ctdb, if the traverse.c part is removed (ctdb's tdb
    code never received the previous two fixes).

    Tested using the testsuite from ccan (adapted to the samba code).  Thanks to
    Michael Adam for feedback.

    Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
    Signed-off-by: Michael Adam <obnox@samba.org>
commit 760104188d
Author: Rusty Russell <rusty@rustcorp.com.au>
Date:   Tue Jul 21 16:23:35 2009 +0930

    tdb: fix locking error

    54a51839ea "Make tdb transaction lock
    recursive (samba version)" was broken: I "cleaned it up" and prevented
    it from ever unlocking.

    To see the problem:
        $ bin/tdbtorture -s 1248142523
        tdb_brlock failed (fd=3) at offset 8 rw_type=1 lck_type=14 len=1
        tdb_transaction_lock: failed to get transaction lock
        tdb_transaction_start failed: Resource deadlock avoided

    My testcase relied on the *count* being correct, which it was.  Fixing that
    now.

    Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
    Signed-off-by: Michael Adam <obnox@samba.org>

(This used to be ctdb commit ce19658ba13272238058e9b9bc03e62f48b737c0)
This commit is contained in:
Rusty Russell 2009-07-29 14:53:03 +09:30
parent 825391de1d
commit 6aa98fb041
2 changed files with 14 additions and 5 deletions

View File

@ -301,16 +301,21 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
*/
int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
{
if (tdb->have_transaction_lock || tdb->global_lock.count) {
if (tdb->global_lock.count) {
return 0;
}
if (tdb->transaction_lock_count > 0) {
tdb->transaction_lock_count++;
return 0;
}
if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype,
F_SETLKW, 0, 1) == -1) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
tdb->ecode = TDB_ERR_LOCK;
return -1;
}
tdb->have_transaction_lock = 1;
tdb->transaction_lock_count++;
return 0;
}
@ -320,12 +325,16 @@ int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
int tdb_transaction_unlock(struct tdb_context *tdb)
{
int ret;
if (!tdb->have_transaction_lock) {
if (tdb->global_lock.count) {
return 0;
}
if (tdb->transaction_lock_count > 1) {
tdb->transaction_lock_count--;
return 0;
}
ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
if (ret == 0) {
tdb->have_transaction_lock = 0;
tdb->transaction_lock_count = 0;
}
return ret;
}

View File

@ -166,7 +166,7 @@ struct tdb_context {
struct tdb_transaction *transaction;
int page_size;
int max_dead_records;
bool have_transaction_lock;
int transaction_lock_count;
volatile sig_atomic_t *interrupt_sig_ptr;
};