|
@@ -135,6 +135,9 @@ struct tdb_transaction {
|
|
|
bool prepared;
|
|
bool prepared;
|
|
|
tdb_off_t magic_offset;
|
|
tdb_off_t magic_offset;
|
|
|
|
|
|
|
|
|
|
+ /* set when the GLOBAL_LOCK has been taken */
|
|
|
|
|
+ bool global_lock_taken;
|
|
|
|
|
+
|
|
|
/* old file size before transaction */
|
|
/* old file size before transaction */
|
|
|
tdb_len_t old_map_size;
|
|
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 */
|
|
/* remove any global lock created during the transaction */
|
|
|
if (tdb->global_lock.count != 0) {
|
|
if (tdb->global_lock.count != 0) {
|
|
|
tdb_brunlock(tdb, tdb->global_lock.ltype,
|
|
tdb_brunlock(tdb, tdb->global_lock.ltype,
|
|
@@ -960,11 +968,12 @@ static int _tdb_transaction_prepare_commit(struct tdb_context *tdb)
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ tdb->transaction->global_lock_taken = true;
|
|
|
|
|
+
|
|
|
if (!(tdb->flags & TDB_NOSYNC)) {
|
|
if (!(tdb->flags & TDB_NOSYNC)) {
|
|
|
/* write the recovery data to the end of the file */
|
|
/* write the recovery data to the end of the file */
|
|
|
if (transaction_setup_recovery(tdb, &tdb->transaction->magic_offset) == -1) {
|
|
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_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);
|
|
_tdb_transaction_cancel(tdb, F_WRLCK);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
@@ -979,7 +988,6 @@ static int _tdb_transaction_prepare_commit(struct tdb_context *tdb)
|
|
|
tdb->transaction->old_map_size) == -1) {
|
|
tdb->transaction->old_map_size) == -1) {
|
|
|
tdb->ecode = TDB_ERR_IO;
|
|
tdb->ecode = TDB_ERR_IO;
|
|
|
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: expansion failed\n"));
|
|
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);
|
|
_tdb_transaction_cancel(tdb, F_WRLCK);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
@@ -1069,7 +1077,6 @@ int tdb_transaction_commit(struct tdb_context *tdb)
|
|
|
tdb_transaction_recover(tdb);
|
|
tdb_transaction_recover(tdb);
|
|
|
|
|
|
|
|
_tdb_transaction_cancel(tdb, F_WRLCK);
|
|
_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"));
|
|
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n"));
|
|
|
return -1;
|
|
return -1;
|
|
@@ -1085,8 +1092,6 @@ int tdb_transaction_commit(struct tdb_context *tdb)
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- tdb_brunlock(tdb, F_WRLCK, GLOBAL_LOCK, 1);
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
TODO: maybe write to some dummy hdr field, or write to magic
|
|
TODO: maybe write to some dummy hdr field, or write to magic
|
|
|
offset without mmap, before the last sync, instead of the
|
|
offset without mmap, before the last sync, instead of the
|