/* when inside a transaction we need to keep track of any
nested tdb_transaction_start() calls, as these are allowed,
but don't create a new transaction */
- int nesting;
+ unsigned int nesting;
/* set when a prepare has already occurred */
bool prepared;
/* cope with nested tdb_transaction_start() calls */
if (tdb->transaction != NULL) {
- return tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO,
- TDB_LOG_USE_ERROR,
- "tdb_transaction_start:"
- " already inside"
- " transaction");
+ if (!(tdb->flags & TDB_ALLOW_NESTING)) {
+ return tdb->last_error
+ = tdb_logerr(tdb, TDB_ERR_IO,
+ TDB_LOG_USE_ERROR,
+ "tdb_transaction_start:"
+ " already inside transaction");
+ }
+ tdb->transaction->nesting++;
+ return 0;
}
if (tdb_has_hash_locks(tdb)) {
us an area that is being currently used (as of the start of
the transaction) */
if (recovery_head != 0) {
- add_stat(tdb, frees, 1);
+ tdb->stats.frees++;
ecode = add_free_record(tdb, recovery_head,
sizeof(rec) + rec.max_len);
if (ecode != TDB_SUCCESS) {
if (tdb->transaction->nesting != 0) {
- tdb->transaction->nesting--;
return TDB_SUCCESS;
}
/* upgrade the main transaction lock region to a write lock */
ecode = tdb_allrecord_upgrade(tdb);
if (ecode != TDB_SUCCESS) {
- tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
- "tdb_transaction_prepare_commit:"
- " failed to upgrade hash locks");
- _tdb_transaction_cancel(tdb);
return ecode;
}
during the commit */
ecode = tdb_lock_open(tdb, TDB_LOCK_WAIT|TDB_LOCK_NOCHECK);
if (ecode != TDB_SUCCESS) {
- tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
- "tdb_transaction_prepare_commit:"
- " failed to get open lock");
- _tdb_transaction_cancel(tdb);
return ecode;
}
&tdb->transaction
->magic_offset);
if (ecode != TDB_SUCCESS) {
- tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
- "tdb_transaction_prepare_commit:"
- " failed to setup recovery data");
- _tdb_transaction_cancel(tdb);
return ecode;
}
}
tdb->file->map_size = tdb->transaction->old_map_size;
ecode = methods->expand_file(tdb, add);
if (ecode != TDB_SUCCESS) {
- tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
- "tdb_transaction_prepare_commit:"
- " expansion failed");
- _tdb_transaction_cancel(tdb);
return ecode;
}
}
if (!tdb->transaction->prepared) {
ecode = _tdb_transaction_prepare_commit(tdb);
- if (ecode != TDB_SUCCESS)
+ if (ecode != TDB_SUCCESS) {
+ _tdb_transaction_cancel(tdb);
return tdb->last_error = ecode;
+ }
}
methods = tdb->transaction->io_methods;
ecode = methods->twrite(tdb, offset,
tdb->transaction->blocks[i], length);
if (ecode != TDB_SUCCESS) {
- tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
- "tdb_transaction_commit:"
- " write failed during commit");
-
/* we've overwritten part of the data and
possibly expanded the file, so we need to
run the crash recovery code */