* 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.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35390 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2010-02-03 13:16:22 +00:00
parent 029f4e9317
commit 22991e1d53

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2004-2010, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@ -71,6 +71,8 @@ struct cached_block {
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 @@ put_cached_block(block_cache* cache, cached_block* block)
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 @@ get_writable_cached_block(block_cache* cache, off_t blockNumber, off_t base,
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_sync(void* _cache)
{
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 @@ block_cache_sync(void* _cache)
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_sync_etc(void* _cache, off_t blockNumber, size_t numBlocks)
{
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 @@ block_cache_sync_etc(void* _cache, off_t blockNumber, size_t numBlocks)
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;