Oops, forgot to implement cache_abort_transaction(); every failing transaction

could have destroyed the BFS integrity... (just happened to me, that's how I
noticed it)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12867 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-05-28 15:11:18 +00:00
parent 8380e999e7
commit b3ef4fb41a

View File

@ -393,18 +393,18 @@ get_writable_cached_block(block_cache *cache, off_t blockNumber, off_t base, off
if (block->transaction != NULL && block->transaction->id != transactionID) {
// ToDo: we have to wait here until the other transaction is done.
// Maybe we should even panic, since we can't prevent any deadlocks.
panic("block_cache_get_writable(): asked to get busy writable block\n");
panic("get_writable_cached_block(): asked to get busy writable block (transaction %ld)\n", block->transaction->id);
return NULL;
}
if (block->transaction == NULL && transactionID != -1) {
// get new transaction
cache_transaction *transaction = lookup_transaction(cache, transactionID);
if (transaction == NULL) {
panic("block_cache_get_writable(): invalid transaction %ld!\n", transactionID);
panic("get_writable_cached_block(): invalid transaction %ld!\n", transactionID);
return NULL;
}
if (!transaction->open) {
panic("block_cache_get_writable(): transaction already done!\n");
panic("get_writable_cached_block(): transaction already done!\n");
return NULL;
}
@ -554,11 +554,11 @@ cache_end_transaction(void *_cache, int32 id, transaction_notification_hook hook
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(cache);
TRACE(("cache_transaction_end(id = %ld)\n", id));
TRACE(("cache_end_transaction(id = %ld)\n", id));
cache_transaction *transaction = lookup_transaction(cache, id);
if (transaction == NULL) {
panic("cache_transaction_end(): invalid transaction ID\n");
panic("cache_end_transaction(): invalid transaction ID\n");
return B_BAD_VALUE;
}
@ -601,6 +601,33 @@ cache_abort_transaction(void *_cache, int32 id)
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(cache);
TRACE(("cache_abort_transaction(id = %ld)\n", id));
cache_transaction *transaction = lookup_transaction(cache, id);
if (transaction == NULL) {
panic("cache_abort_transaction(): invalid transaction ID\n");
return B_BAD_VALUE;
}
// iterate through all blocks and restore their original contents
cached_block *block = transaction->first_block, *next;
for (; block != NULL; block = next) {
next = block->transaction_next;
if (block->original != NULL) {
TRACE(("cache_abort_transaction(id = %ld): restored contents of block %Ld\n",
transaction->id, block->block_number));
memcpy(block->data, block->original, cache->block_size);
cache->allocator->Put(block->data);
block->original = NULL;
}
block->transaction_next = NULL;
block->transaction = NULL;
}
delete_transaction(cache, transaction);
return B_OK;
}