block cache: convert to BOpenHashTable.

This commit is contained in:
Adrien Destugues
2015-01-13 15:48:56 +01:00
parent be60c04c89
commit 9d1c3b8d4b
+140 -154
View File
@@ -22,7 +22,6 @@
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include <util/khash.h>
#include <vm/vm_page.h> #include <vm/vm_page.h>
#include "kernel_debug_config.h" #include "kernel_debug_config.h"
@@ -104,9 +103,6 @@ struct cached_block {
bool CanBeWritten() const; bool CanBeWritten() const;
int32 LastAccess() const int32 LastAccess() const
{ return system_time() / 1000000L - last_accessed; } { return system_time() / 1000000L - last_accessed; }
static int Compare(void* _cacheEntry, const void* _block);
static uint32 Hash(void* _cacheEntry, const void* _block, uint32 range);
}; };
typedef DoublyLinkedList<cached_block, typedef DoublyLinkedList<cached_block,
@@ -124,15 +120,60 @@ struct cache_notification : DoublyLinkedListLinkImpl<cache_notification> {
typedef DoublyLinkedList<cache_notification> NotificationList; typedef DoublyLinkedList<cache_notification> NotificationList;
struct BlockHash {
typedef off_t KeyType;
typedef cached_block ValueType;
size_t HashKey(KeyType key) const
{
return key;
}
size_t Hash(ValueType* block) const
{
return block->block_number;
}
bool Compare(KeyType key, ValueType* block) const
{
return block->block_number == key;
}
ValueType*& GetLink(ValueType* value) const
{
return value->next;
}
};
typedef BOpenHashTable<BlockHash> BlockTable;
struct TransactionHash {
typedef int32 KeyType;
typedef cache_transaction ValueType;
size_t HashKey(KeyType key) const
{
return key;
}
size_t Hash(ValueType* transaction) const;
bool Compare(KeyType key, ValueType* transaction) const;
ValueType*& GetLink(ValueType* value) const;
};
typedef BOpenHashTable<TransactionHash> TransactionTable;
struct block_cache : DoublyLinkedListLinkImpl<block_cache> { struct block_cache : DoublyLinkedListLinkImpl<block_cache> {
hash_table* hash; BlockTable* hash;
mutex lock; mutex lock;
int fd; int fd;
off_t max_blocks; off_t max_blocks;
size_t block_size; size_t block_size;
int32 next_transaction_id; int32 next_transaction_id;
cache_transaction* last_transaction; cache_transaction* last_transaction;
hash_table* transaction_hash; TransactionTable* transaction_hash;
object_cache* buffer_cache; object_cache* buffer_cache;
block_list unused_blocks; block_list unused_blocks;
@@ -211,12 +252,11 @@ public:
~BlockWriter(); ~BlockWriter();
bool Add(cached_block* block, bool Add(cached_block* block,
hash_iterator* iterator = NULL); cache_transaction* transaction = NULL);
bool Add(cache_transaction* transaction, bool Add(cache_transaction* transaction,
hash_iterator* iterator,
bool& hasLeftOvers); bool& hasLeftOvers);
status_t Write(hash_iterator* iterator = NULL, status_t Write(cache_transaction* transaction = NULL,
bool canUnlock = true); bool canUnlock = true);
bool DeletedTransaction() const bool DeletedTransaction() const
@@ -229,7 +269,7 @@ private:
void* _Data(cached_block* block) const; void* _Data(cached_block* block) const;
status_t _WriteBlock(cached_block* block); status_t _WriteBlock(cached_block* block);
void _BlockDone(cached_block* block, void _BlockDone(cached_block* block,
hash_iterator* iterator); cache_transaction* transaction);
void _UnmarkWriting(cached_block* block); void _UnmarkWriting(cached_block* block);
static int _CompareBlocks(const void* _blockA, static int _CompareBlocks(const void* _blockA,
@@ -943,29 +983,6 @@ cache_transaction::cache_transaction()
} }
static int
transaction_compare(void* _transaction, const void* _id)
{
cache_transaction* transaction = (cache_transaction*)_transaction;
const int32* id = (const int32*)_id;
return transaction->id - *id;
}
static uint32
transaction_hash(void* _transaction, const void* _id, uint32 range)
{
cache_transaction* transaction = (cache_transaction*)_transaction;
const int32* id = (const int32*)_id;
if (transaction != NULL)
return transaction->id % range;
return (uint32)*id % range;
}
static void static void
delete_transaction(block_cache* cache, cache_transaction* transaction) delete_transaction(block_cache* cache, cache_transaction* transaction)
{ {
@@ -980,7 +997,25 @@ delete_transaction(block_cache* cache, cache_transaction* transaction)
static cache_transaction* static cache_transaction*
lookup_transaction(block_cache* cache, int32 id) lookup_transaction(block_cache* cache, int32 id)
{ {
return (cache_transaction*)hash_lookup(cache->transaction_hash, &id); return cache->transaction_hash->Lookup(id);
}
size_t TransactionHash::Hash(cache_transaction* transaction) const
{
return transaction->id;
}
bool TransactionHash::Compare(int32 key, cache_transaction* transaction) const
{
return transaction->id == key;
}
cache_transaction*& TransactionHash::GetLink(cache_transaction* value) const
{
return value->next;
} }
@@ -1017,33 +1052,6 @@ cached_block::CanBeWritten() const
} }
/*static*/ int
cached_block::Compare(void* _cacheEntry, const void* _block)
{
cached_block* cacheEntry = (cached_block*)_cacheEntry;
const off_t* block = (const off_t*)_block;
off_t diff = cacheEntry->block_number - *block;
if (diff > 0)
return 1;
return diff < 0 ? -1 : 0;
}
/*static*/ uint32
cached_block::Hash(void* _cacheEntry, const void* _block, uint32 range)
{
cached_block* cacheEntry = (cached_block*)_cacheEntry;
const off_t* block = (const off_t*)_block;
if (cacheEntry != NULL)
return cacheEntry->block_number % range;
return (uint64)*block % range;
}
// #pragma mark - BlockWriter // #pragma mark - BlockWriter
@@ -1072,7 +1080,7 @@ BlockWriter::~BlockWriter()
be added, false is returned, otherwise true. be added, false is returned, otherwise true.
*/ */
bool bool
BlockWriter::Add(cached_block* block, hash_iterator* iterator) BlockWriter::Add(cached_block* block, cache_transaction* transaction)
{ {
ASSERT(block->CanBeWritten()); ASSERT(block->CanBeWritten());
@@ -1093,7 +1101,7 @@ BlockWriter::Add(cached_block* block, hash_iterator* iterator)
if (newBlocks == NULL) { if (newBlocks == NULL) {
// Allocating a larger array failed - we need to write back what // Allocating a larger array failed - we need to write back what
// we have synchronously now (this will also clear the array) // we have synchronously now (this will also clear the array)
Write(iterator, false); Write(transaction, false);
} else { } else {
if (fBlocks == fBuffer) if (fBlocks == fBuffer)
memcpy(newBlocks, fBuffer, kBufferSize * sizeof(void*)); memcpy(newBlocks, fBuffer, kBufferSize * sizeof(void*));
@@ -1118,8 +1126,7 @@ BlockWriter::Add(cached_block* block, hash_iterator* iterator)
If no more blocks can be added, false is returned, otherwise true. If no more blocks can be added, false is returned, otherwise true.
*/ */
bool bool
BlockWriter::Add(cache_transaction* transaction, hash_iterator* iterator, BlockWriter::Add(cache_transaction* transaction, bool& hasLeftOvers)
bool& hasLeftOvers)
{ {
ASSERT(!transaction->open); ASSERT(!transaction->open);
@@ -1138,7 +1145,7 @@ BlockWriter::Add(cache_transaction* transaction, hash_iterator* iterator,
hasLeftOvers = true; hasLeftOvers = true;
continue; continue;
} }
if (!Add(block, iterator)) if (!Add(block, transaction))
return false; return false;
if (DeletedTransaction()) if (DeletedTransaction())
@@ -1153,7 +1160,7 @@ BlockWriter::Add(cache_transaction* transaction, hash_iterator* iterator,
while the blocks are written back. while the blocks are written back.
*/ */
status_t status_t
BlockWriter::Write(hash_iterator* iterator, bool canUnlock) BlockWriter::Write(cache_transaction* transaction, bool canUnlock)
{ {
if (fCount == 0) if (fCount == 0)
return B_OK; return B_OK;
@@ -1184,7 +1191,7 @@ BlockWriter::Write(hash_iterator* iterator, bool canUnlock)
mutex_lock(&fCache->lock); mutex_lock(&fCache->lock);
for (uint32 i = 0; i < fCount; i++) for (uint32 i = 0; i < fCount; i++)
_BlockDone(fBlocks[i], iterator); _BlockDone(fBlocks[i], transaction);
fCount = 0; fCount = 0;
return fStatus; return fStatus;
@@ -1245,7 +1252,8 @@ BlockWriter::_WriteBlock(cached_block* block)
void void
BlockWriter::_BlockDone(cached_block* block, hash_iterator* iterator) BlockWriter::_BlockDone(cached_block* block,
cache_transaction* transaction)
{ {
if (block == NULL) { if (block == NULL) {
// An error occured when trying to write this block // An error occured when trying to write this block
@@ -1280,10 +1288,14 @@ BlockWriter::_BlockDone(cached_block* block, hash_iterator* iterator)
notify_transaction_listeners(fCache, previous, notify_transaction_listeners(fCache, previous,
TRANSACTION_WRITTEN); TRANSACTION_WRITTEN);
if (iterator != NULL) if (transaction != NULL) {
hash_remove_current(fCache->transaction_hash, iterator); // This function is called while iterating transaction_hash. We
else // use RemoveUnchecked so the iterator is still valid. A regular
hash_remove(fCache->transaction_hash, previous); // Remove can trigger a resize of the hash table which would
// result in the linked items in the table changing order.
fCache->transaction_hash->RemoveUnchecked(transaction);
} else
fCache->transaction_hash->Remove(previous);
delete_transaction(fCache, previous); delete_transaction(fCache, previous);
fDeletedTransaction = true; fDeletedTransaction = true;
@@ -1362,8 +1374,8 @@ block_cache::~block_cache()
{ {
unregister_low_resource_handler(&_LowMemoryHandler, this); unregister_low_resource_handler(&_LowMemoryHandler, this);
hash_uninit(transaction_hash); delete transaction_hash;
hash_uninit(hash); delete hash;
delete_object_cache(buffer_cache); delete_object_cache(buffer_cache);
@@ -1384,16 +1396,12 @@ block_cache::Init()
if (buffer_cache == NULL) if (buffer_cache == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
cached_block dummyBlock; hash = new BlockTable();
hash = hash_init(1024, offset_of_member(dummyBlock, next), if (hash == NULL || hash->Init(1024) != B_OK)
&cached_block::Compare, &cached_block::Hash);
if (hash == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
cache_transaction dummyTransaction; transaction_hash = new(std::nothrow) TransactionTable();
transaction_hash = hash_init(16, offset_of_member(dummyTransaction, next), if (transaction_hash == NULL || transaction_hash->Init(16) != B_OK)
&transaction_compare, &::transaction_hash);
if (transaction_hash == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
return register_low_resource_handler(&_LowMemoryHandler, this, return register_low_resource_handler(&_LowMemoryHandler, this,
@@ -1549,7 +1557,7 @@ block_cache::RemoveUnusedBlocks(int32 count, int32 minSecondsOld)
void void
block_cache::RemoveBlock(cached_block* block) block_cache::RemoveBlock(cached_block* block)
{ {
hash_remove(hash, block); hash->Remove(block);
FreeBlock(block); FreeBlock(block);
} }
@@ -1638,7 +1646,7 @@ block_cache::_GetUnusedBlock()
// remove block from lists // remove block from lists
iterator.Remove(); iterator.Remove();
unused_block_count--; unused_block_count--;
hash_remove(hash, block); hash->Remove(block);
ASSERT(block->original_data == NULL && block->parent_data == NULL); ASSERT(block->original_data == NULL && block->parent_data == NULL);
block->unused = false; block->unused = false;
@@ -1822,7 +1830,7 @@ put_cached_block(block_cache* cache, off_t blockNumber)
blockNumber, cache->max_blocks - 1); blockNumber, cache->max_blocks - 1);
} }
cached_block* block = (cached_block*)hash_lookup(cache->hash, &blockNumber); cached_block* block = cache->hash->Lookup(blockNumber);
if (block != NULL) if (block != NULL)
put_cached_block(cache, block); put_cached_block(cache, block);
else { else {
@@ -1855,8 +1863,7 @@ get_cached_block(block_cache* cache, off_t blockNumber, bool* _allocated,
} }
retry: retry:
cached_block* block = (cached_block*)hash_lookup(cache->hash, cached_block* block = cache->hash->Lookup(blockNumber);
&blockNumber);
*_allocated = false; *_allocated = false;
if (block == NULL) { if (block == NULL) {
@@ -1865,7 +1872,7 @@ retry:
if (block == NULL) if (block == NULL)
return NULL; return NULL;
hash_insert_grow(cache->hash, block); cache->hash->Insert(block);
*_allocated = true; *_allocated = true;
} else if (block->busy_reading) { } else if (block->busy_reading) {
// The block is currently busy_reading - wait and try again later // The block is currently busy_reading - wait and try again later
@@ -2179,8 +2186,7 @@ dump_cache(int argc, char** argv)
off_t blockNumber = -1; off_t blockNumber = -1;
if (i + 1 < argc) { if (i + 1 < argc) {
blockNumber = parse_expression(argv[i + 1]); blockNumber = parse_expression(argv[i + 1]);
cached_block* block = (cached_block*)hash_lookup(cache->hash, cached_block* block = cache->hash->Lookup(blockNumber);
&blockNumber);
if (block != NULL) if (block != NULL)
dump_block_long(block); dump_block_long(block);
else else
@@ -2218,14 +2224,13 @@ dump_cache(int argc, char** argv)
kprintf(" transactions:\n"); kprintf(" transactions:\n");
kprintf("address id state blocks main sub\n"); kprintf("address id state blocks main sub\n");
hash_iterator iterator; TransactionTable::Iterator iterator(cache->transaction_hash);
hash_open(cache->transaction_hash, &iterator);
cache_transaction* transaction; while (iterator.HasNext()) {
while ((transaction = (cache_transaction*)hash_next( cache_transaction* transaction = iterator.Next();
cache->transaction_hash, &iterator)) != NULL) { kprintf("%p %5" B_PRId32 " %-7s %5" B_PRId32 " %5" B_PRId32 " %5"
kprintf("%p %5" B_PRId32 " %-7s %5" B_PRId32 " %5" B_PRId32 " %5" B_PRId32 "\n", B_PRId32 "\n", transaction, transaction->id,
transaction, transaction->id, transaction->open ? "open" : "closed", transaction->open ? "open" : "closed",
transaction->num_blocks, transaction->main_num_blocks, transaction->num_blocks, transaction->main_num_blocks,
transaction->sub_num_blocks); transaction->sub_num_blocks);
} }
@@ -2241,10 +2246,9 @@ dump_cache(int argc, char** argv)
uint32 count = 0; uint32 count = 0;
uint32 dirty = 0; uint32 dirty = 0;
uint32 discarded = 0; uint32 discarded = 0;
hash_iterator iterator; BlockTable::Iterator iterator(cache->hash);
hash_open(cache->hash, &iterator); while (iterator.HasNext()) {
cached_block* block; cached_block* block = iterator.Next();
while ((block = (cached_block*)hash_next(cache->hash, &iterator)) != NULL) {
if (showBlocks) if (showBlocks)
dump_block(block); dump_block(block);
@@ -2257,12 +2261,11 @@ dump_cache(int argc, char** argv)
count++; count++;
} }
kprintf(" %" B_PRIu32 " blocks total, %" B_PRIu32 " dirty, %" B_PRIu32 " discarded" kprintf(" %" B_PRIu32 " blocks total, %" B_PRIu32 " dirty, %" B_PRIu32
", %" B_PRIu32 " referenced, %" B_PRIu32 " busy, %" B_PRIu32 " in unused.\n", " discarded, %" B_PRIu32 " referenced, %" B_PRIu32 " busy, %" B_PRIu32
" in unused.\n",
count, dirty, discarded, referenced, cache->busy_reading_count, count, dirty, discarded, referenced, cache->busy_reading_count,
cache->unused_block_count); cache->unused_block_count);
hash_close(cache->hash, &iterator, false);
return 0; return 0;
} }
@@ -2534,24 +2537,19 @@ block_notifier_and_writer(void* /*data*/)
if (cache->num_dirty_blocks) { if (cache->num_dirty_blocks) {
// This cache is not using transactions, we'll scan the blocks // This cache is not using transactions, we'll scan the blocks
// directly // directly
hash_iterator iterator; BlockTable::Iterator iterator(cache->hash);
hash_open(cache->hash, &iterator);
cached_block* block; while (iterator.HasNext()) {
while ((block = (cached_block*)hash_next(cache->hash, &iterator)) cached_block* block = iterator.Next();
!= NULL) {
if (block->CanBeWritten() && !writer.Add(block)) if (block->CanBeWritten() && !writer.Add(block))
break; break;
} }
hash_close(cache->hash, &iterator, false);
} else { } else {
hash_iterator iterator; TransactionTable::Iterator iterator(cache->transaction_hash);
hash_open(cache->transaction_hash, &iterator);
cache_transaction* transaction; while (iterator.HasNext()) {
while ((transaction = (cache_transaction*)hash_next( cache_transaction* transaction = iterator.Next();
cache->transaction_hash, &iterator)) != NULL) {
if (transaction->open) { if (transaction->open) {
if (system_time() > transaction->last_used if (system_time() > transaction->last_used
+ kTransactionIdleTime) { + kTransactionIdleTime) {
@@ -2564,11 +2562,9 @@ block_notifier_and_writer(void* /*data*/)
bool hasLeftOvers; bool hasLeftOvers;
// we ignore this one // we ignore this one
if (!writer.Add(transaction, &iterator, hasLeftOvers)) if (!writer.Add(transaction, hasLeftOvers))
break; break;
} }
hash_close(cache->transaction_hash, &iterator, false);
} }
writer.Write(); writer.Write();
@@ -2734,7 +2730,7 @@ cache_start_transaction(void* _cache)
TRACE(("cache_start_transaction(): id %" B_PRId32 " started\n", transaction->id)); TRACE(("cache_start_transaction(): id %" B_PRId32 " started\n", transaction->id));
T(Action("start", cache, transaction)); T(Action("start", cache, transaction));
hash_insert_grow(cache->transaction_hash, transaction); cache->transaction_hash->Insert(transaction);
return transaction->id; return transaction->id;
} }
@@ -2753,13 +2749,11 @@ cache_sync_transaction(void* _cache, int32 id)
hadBusy = false; hadBusy = false;
BlockWriter writer(cache); BlockWriter writer(cache);
hash_iterator iterator; TransactionTable::Iterator iterator(cache->transaction_hash);
hash_open(cache->transaction_hash, &iterator);
cache_transaction* transaction; while (iterator.HasNext()) {
while ((transaction = (cache_transaction*)hash_next(
cache->transaction_hash, &iterator)) != NULL) {
// close all earlier transactions which haven't been closed yet // close all earlier transactions which haven't been closed yet
cache_transaction* transaction = iterator.Next();
if (transaction->busy_writing_count != 0) { if (transaction->busy_writing_count != 0) {
hadBusy = true; hadBusy = true;
@@ -2770,7 +2764,7 @@ cache_sync_transaction(void* _cache, int32 id)
T(Action("sync", cache, transaction)); T(Action("sync", cache, transaction));
bool hasLeftOvers; bool hasLeftOvers;
writer.Add(transaction, &iterator, hasLeftOvers); writer.Add(transaction, hasLeftOvers);
if (hasLeftOvers) { if (hasLeftOvers) {
// This transaction contains blocks that a previous // This transaction contains blocks that a previous
@@ -2780,8 +2774,6 @@ cache_sync_transaction(void* _cache, int32 id)
} }
} }
hash_close(cache->transaction_hash, &iterator, false);
status_t status = writer.Write(); status_t status = writer.Write();
if (status != B_OK) if (status != B_OK)
return status; return status;
@@ -2903,7 +2895,7 @@ cache_abort_transaction(void* _cache, int32 id)
block->is_dirty = false; block->is_dirty = false;
} }
hash_remove(cache->transaction_hash, transaction); cache->transaction_hash->Remove(transaction);
delete_transaction(cache, transaction); delete_transaction(cache, transaction);
return B_OK; return B_OK;
} }
@@ -3010,7 +3002,7 @@ cache_detach_sub_transaction(void* _cache, int32 id,
transaction->num_blocks = transaction->main_num_blocks; transaction->num_blocks = transaction->main_num_blocks;
transaction->sub_num_blocks = 0; transaction->sub_num_blocks = 0;
hash_insert_grow(cache->transaction_hash, newTransaction); cache->transaction_hash->Insert(newTransaction);
cache->last_transaction = newTransaction; cache->last_transaction = newTransaction;
return newTransaction->id; return newTransaction->id;
@@ -3326,20 +3318,20 @@ block_cache_delete(void* _cache, bool allowWrites)
// free all blocks // free all blocks
uint32 cookie = 0; cached_block* block = cache->hash->Clear(true);
cached_block* block; while (block != NULL) {
while ((block = (cached_block*)hash_remove_first(cache->hash, cached_block* next = block->next;
&cookie)) != NULL) {
cache->FreeBlock(block); cache->FreeBlock(block);
block = next;
} }
// free all transactions (they will all be aborted) // free all transactions (they will all be aborted)
cookie = 0; cache_transaction* transaction = cache->transaction_hash->Clear(true);
cache_transaction* transaction; while (transaction != NULL) {
while ((transaction = (cache_transaction*)hash_remove_first( cache_transaction* next = transaction->next;
cache->transaction_hash, &cookie)) != NULL) {
delete transaction; delete transaction;
transaction = next;
} }
delete cache; delete cache;
@@ -3377,17 +3369,14 @@ block_cache_sync(void* _cache)
MutexLocker locker(&cache->lock); MutexLocker locker(&cache->lock);
BlockWriter writer(cache); BlockWriter writer(cache);
hash_iterator iterator; BlockTable::Iterator iterator(cache->hash);
hash_open(cache->hash, &iterator);
cached_block* block; while (iterator.HasNext()) {
while ((block = (cached_block*)hash_next(cache->hash, &iterator)) != NULL) { cached_block* block = iterator.Next();
if (block->CanBeWritten()) if (block->CanBeWritten())
writer.Add(block); writer.Add(block);
} }
hash_close(cache->hash, &iterator, false);
status_t status = writer.Write(); status_t status = writer.Write();
locker.Unlock(); locker.Unlock();
@@ -3408,7 +3397,8 @@ block_cache_sync_etc(void* _cache, off_t blockNumber, size_t numBlocks)
// transaction or no transaction only // transaction or no transaction only
if (blockNumber < 0 || blockNumber >= cache->max_blocks) { if (blockNumber < 0 || blockNumber >= cache->max_blocks) {
panic("block_cache_sync_etc: invalid block number %" B_PRIdOFF " (max %" B_PRIdOFF ")", panic("block_cache_sync_etc: invalid block number %" B_PRIdOFF
" (max %" B_PRIdOFF ")",
blockNumber, cache->max_blocks - 1); blockNumber, cache->max_blocks - 1);
return B_BAD_VALUE; return B_BAD_VALUE;
} }
@@ -3417,8 +3407,7 @@ block_cache_sync_etc(void* _cache, off_t blockNumber, size_t numBlocks)
BlockWriter writer(cache); BlockWriter writer(cache);
for (; numBlocks > 0; numBlocks--, blockNumber++) { for (; numBlocks > 0; numBlocks--, blockNumber++) {
cached_block* block = (cached_block*)hash_lookup(cache->hash, cached_block* block = cache->hash->Lookup(blockNumber);
&blockNumber);
if (block == NULL) if (block == NULL)
continue; continue;
@@ -3452,8 +3441,7 @@ block_cache_discard(void* _cache, off_t blockNumber, size_t numBlocks)
BlockWriter writer(cache); BlockWriter writer(cache);
for (size_t i = 0; i < numBlocks; i++, blockNumber++) { for (size_t i = 0; i < numBlocks; i++, blockNumber++) {
cached_block* block = (cached_block*)hash_lookup(cache->hash, cached_block* block = cache->hash->Lookup(blockNumber);
&blockNumber);
if (block != NULL && block->previous_transaction != NULL) if (block != NULL && block->previous_transaction != NULL)
writer.Add(block); writer.Add(block);
} }
@@ -3465,8 +3453,7 @@ block_cache_discard(void* _cache, off_t blockNumber, size_t numBlocks)
// reset blockNumber to its original value // reset blockNumber to its original value
for (size_t i = 0; i < numBlocks; i++, blockNumber++) { for (size_t i = 0; i < numBlocks; i++, blockNumber++) {
cached_block* block = (cached_block*)hash_lookup(cache->hash, cached_block* block = cache->hash->Lookup(blockNumber);
&blockNumber);
if (block == NULL) if (block == NULL)
continue; continue;
@@ -3598,8 +3585,7 @@ block_cache_set_dirty(void* _cache, off_t blockNumber, bool dirty,
block_cache* cache = (block_cache*)_cache; block_cache* cache = (block_cache*)_cache;
MutexLocker locker(&cache->lock); MutexLocker locker(&cache->lock);
cached_block* block = (cached_block*)hash_lookup(cache->hash, cached_block* block = cache->hash->Lookup(blockNumber);
&blockNumber);
if (block == NULL) if (block == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
if (block->is_dirty == dirty) { if (block->is_dirty == dirty) {