X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb%2Ftransaction.c;h=c5580f205d39c074fbbe52f9f5545659638112c3;hp=742f188f500dbd4bba8dcbe4f6d080a2663ca7ab;hb=176844c84ff5ae6a5f146c5d1b7a3927bd781739;hpb=9d045ca09a0b052d968e11d98540f63a8a0aa412;ds=sidebyside diff --git a/ccan/tdb/transaction.c b/ccan/tdb/transaction.c index 742f188f..c5580f20 100644 --- a/ccan/tdb/transaction.c +++ b/ccan/tdb/transaction.c @@ -135,6 +135,9 @@ struct tdb_transaction { bool prepared; tdb_off_t magic_offset; + /* set when the GLOBAL_LOCK has been taken */ + bool global_lock_taken; + /* old file size before transaction */ tdb_len_t old_map_size; @@ -501,6 +504,11 @@ int _tdb_transaction_cancel(struct tdb_context *tdb, int ltype) } } + if (tdb->transaction->global_lock_taken) { + tdb_brunlock(tdb, F_WRLCK, GLOBAL_LOCK, 1); + tdb->transaction->global_lock_taken = false; + } + /* remove any global lock created during the transaction */ if (tdb->global_lock.count != 0) { tdb_brunlock(tdb, tdb->global_lock.ltype, @@ -960,11 +968,12 @@ static int _tdb_transaction_prepare_commit(struct tdb_context *tdb) return -1; } + tdb->transaction->global_lock_taken = true; + if (!(tdb->flags & TDB_NOSYNC)) { /* write the recovery data to the end of the file */ if (transaction_setup_recovery(tdb, &tdb->transaction->magic_offset) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: failed to setup recovery data\n")); - tdb_brunlock(tdb, F_WRLCK, GLOBAL_LOCK, 1); _tdb_transaction_cancel(tdb, F_WRLCK); return -1; } @@ -979,7 +988,6 @@ static int _tdb_transaction_prepare_commit(struct tdb_context *tdb) tdb->transaction->old_map_size) == -1) { tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: expansion failed\n")); - tdb_brunlock(tdb, F_WRLCK, GLOBAL_LOCK, 1); _tdb_transaction_cancel(tdb, F_WRLCK); return -1; } @@ -1069,7 +1077,6 @@ int tdb_transaction_commit(struct tdb_context *tdb) tdb_transaction_recover(tdb); _tdb_transaction_cancel(tdb, F_WRLCK); - tdb_brunlock(tdb, F_WRLCK, GLOBAL_LOCK, 1); TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); return -1; @@ -1085,8 +1092,6 @@ int tdb_transaction_commit(struct tdb_context *tdb) return -1; } - tdb_brunlock(tdb, F_WRLCK, GLOBAL_LOCK, 1); - /* TODO: maybe write to some dummy hdr field, or write to magic offset without mmap, before the last sync, instead of the