From dd9d610500dfb12b68dace7ce2dd3c0b96818e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 27 Aug 2012 12:42:48 +0200 Subject: [PATCH] Fixed broken block list introduced in hrev44357. * cache_abort_sub_transaction() was setting the transaction_next pointer to NULL in order to remove a block from a transaction -- however, it forgot to actually remove it from the transaction's block list. * Minor restructuring. --- src/system/kernel/cache/block_cache.cpp | 30 +++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/system/kernel/cache/block_cache.cpp b/src/system/kernel/cache/block_cache.cpp index 49a0296824..8962f33bec 100644 --- a/src/system/kernel/cache/block_cache.cpp +++ b/src/system/kernel/cache/block_cache.cpp @@ -3035,6 +3035,7 @@ cache_abort_sub_transaction(void* _cache, int32 id) // revert all changes back to the version of the parent cached_block* block = transaction->first_block; + cached_block* last = NULL; cached_block* next; for (; block != NULL; block = next) { next = block->transaction_next; @@ -3046,21 +3047,32 @@ cache_abort_sub_transaction(void* _cache, int32 id) ASSERT(block->original_data != NULL); memcpy(block->current_data, block->original_data, cache->block_size); + + if (last != NULL) + last->transaction_next = next; + else + transaction->first_block = next; + block->transaction_next = NULL; block->transaction = NULL; if (block->previous_transaction == NULL) block->is_dirty = false; - } else if (block->parent_data != block->current_data) { - // The block has been changed and must be restored - the block - // is still dirty and part of the transaction - TRACE(("cache_abort_sub_transaction(id = %ld): restored contents " - "of block %Ld\n", transaction->id, block->block_number)); - memcpy(block->current_data, block->parent_data, cache->block_size); - cache->Free(block->parent_data); - // The block stays dirty + } else { + if (block->parent_data != block->current_data) { + // The block has been changed and must be restored - the block + // is still dirty and part of the transaction + TRACE(("cache_abort_sub_transaction(id = %ld): restored " + "contents of block %Ld\n", transaction->id, + block->block_number)); + memcpy(block->current_data, block->parent_data, + cache->block_size); + cache->Free(block->parent_data); + // The block stays dirty + } + block->parent_data = NULL; + last = block; } - block->parent_data = NULL; block->discard = false; }