Author: axeld Date: 2010-02-03 14:16:22 +0100 (Wed, 03 Feb 2010) New Revision: 35390 Changeset: http://dev.haiku-os.org/changeset/35390/haiku Ticket: http://dev.haiku-os.org/ticket/5340 Modified: haiku/trunk/src/system/kernel/cache/block_cache.cpp Log: * Use the is_writing flag to determine whether or not we may write back a block that does not have a transaction. * This should fix #5340. Modified: haiku/trunk/src/system/kernel/cache/block_cache.cpp =================================================================== --- haiku/trunk/src/system/kernel/cache/block_cache.cpp 2010-02-02 17:56:52 UTC (rev 35389) +++ haiku/trunk/src/system/kernel/cache/block_cache.cpp 2010-02-03 13:16:22 UTC (rev 35390) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Copyright 2004-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * Distributed under the terms of the MIT License. */ @@ -71,6 +71,8 @@ int32 accessed; bool busy : 1; bool is_writing : 1; + // Block has been checked out for writing without transactions, and + // cannot be written back if set bool is_dirty : 1; bool unused : 1; bool discard : 1; @@ -1316,6 +1318,8 @@ if (--block->ref_count == 0 && block->transaction == NULL && block->previous_transaction == NULL) { // This block is not used anymore, and not part of any transaction + block->is_writing = false; + if (block->discard) { cache->RemoveBlock(block); } else { @@ -1484,6 +1488,8 @@ mark_block_unbusy(cache, block); } + block->is_writing = true; + if (!block->is_dirty) { cache->num_dirty_blocks++; block->is_dirty = true; @@ -2915,7 +2921,7 @@ { block_cache* cache = (block_cache*)_cache; - // we will sync all dirty blocks to disk that have a completed + // We will sync all dirty blocks to disk that have a completed // transaction or no transaction only MutexLocker locker(&cache->lock); @@ -2925,7 +2931,8 @@ cached_block* block; while ((block = (cached_block*)hash_next(cache->hash, &iterator)) != NULL) { if (block->previous_transaction != NULL - || (block->transaction == NULL && block->is_dirty)) { + || (block->transaction == NULL && block->is_dirty + && !block->is_writing)) { status_t status = write_cached_block(cache, block); if (status != B_OK) return status; @@ -2947,7 +2954,7 @@ { block_cache* cache = (block_cache*)_cache; - // we will sync all dirty blocks to disk that have a completed + // We will sync all dirty blocks to disk that have a completed // transaction or no transaction only if (blockNumber < 0 || blockNumber >= cache->max_blocks) { @@ -2965,7 +2972,8 @@ continue; if (block->previous_transaction != NULL - || (block->transaction == NULL && block->is_dirty)) { + || (block->transaction == NULL && block->is_dirty + && !block->is_writing)) { status_t status = write_cached_block(cache, block); if (status != B_OK) return status;