Cleanup:
* NewBlock()/FreeBlock() are now symmetrical in that the former no longer inserts the block into the hash table. * delete_transaction() also no longer removes the transaction from the hash table. * cache_transaction_sync() now uses the new hash_remove_current() function. * minor other cleanup (like line breaks). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20374 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1f78f00899
commit
de4145dbb6
197
src/system/kernel/cache/block_cache.cpp
vendored
197
src/system/kernel/cache/block_cache.cpp
vendored
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
* Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -102,7 +102,6 @@ transaction_hash(void *_transaction, const void *_id, uint32 range)
|
|||||||
static void
|
static void
|
||||||
delete_transaction(block_cache *cache, cache_transaction *transaction)
|
delete_transaction(block_cache *cache, cache_transaction *transaction)
|
||||||
{
|
{
|
||||||
hash_remove(cache->transaction_hash, transaction);
|
|
||||||
if (cache->last_transaction == transaction)
|
if (cache->last_transaction == transaction)
|
||||||
cache->last_transaction = NULL;
|
cache->last_transaction = NULL;
|
||||||
|
|
||||||
@ -149,7 +148,8 @@ cached_block::Hash(void *_cacheEntry, const void *_block, uint32 range)
|
|||||||
// #pragma mark - block_cache
|
// #pragma mark - block_cache
|
||||||
|
|
||||||
|
|
||||||
block_cache::block_cache(int _fd, off_t numBlocks, size_t blockSize, bool readOnly)
|
block_cache::block_cache(int _fd, off_t numBlocks, size_t blockSize,
|
||||||
|
bool readOnly)
|
||||||
:
|
:
|
||||||
hash(NULL),
|
hash(NULL),
|
||||||
fd(_fd),
|
fd(_fd),
|
||||||
@ -165,7 +165,8 @@ block_cache::block_cache(int _fd, off_t numBlocks, size_t blockSize, bool readOn
|
|||||||
if (hash == NULL)
|
if (hash == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
transaction_hash = hash_init(16, 0, &transaction_compare, &::transaction_hash);
|
transaction_hash = hash_init(16, 0, &transaction_compare,
|
||||||
|
&::transaction_hash);
|
||||||
if (transaction_hash == NULL)
|
if (transaction_hash == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -281,8 +282,10 @@ block_cache::FreeBlock(cached_block *block)
|
|||||||
ASSERT(range != NULL);
|
ASSERT(range != NULL);
|
||||||
range->Free(this, block);
|
range->Free(this, block);
|
||||||
|
|
||||||
if (block->original_data != NULL || block->parent_data != NULL)
|
if (block->original_data != NULL || block->parent_data != NULL) {
|
||||||
panic("block_cache::FreeBlock(): %p, %p\n", block->original_data, block->parent_data);
|
panic("block_cache::FreeBlock(): %p, %p\n", block->original_data,
|
||||||
|
block->parent_data);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CHANGED
|
#ifdef DEBUG_CHANGED
|
||||||
Free(block->compare);
|
Free(block->compare);
|
||||||
@ -295,6 +298,7 @@ block_cache::FreeBlock(cached_block *block)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Allocates a new block for \a blockNumber, ready for use */
|
||||||
cached_block *
|
cached_block *
|
||||||
block_cache::NewBlock(off_t blockNumber)
|
block_cache::NewBlock(off_t blockNumber)
|
||||||
{
|
{
|
||||||
@ -326,8 +330,6 @@ block_cache::NewBlock(off_t blockNumber)
|
|||||||
block->compare = NULL;
|
block->compare = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hash_insert(hash, block);
|
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,7 +340,8 @@ block_cache::RemoveUnusedBlocks(int32 maxAccessed, int32 count)
|
|||||||
TRACE(("block_cache: remove up to %ld unused blocks\n", count));
|
TRACE(("block_cache: remove up to %ld unused blocks\n", count));
|
||||||
|
|
||||||
cached_block *next = NULL;
|
cached_block *next = NULL;
|
||||||
for (cached_block *block = unused_blocks.First(); block != NULL; block = next) {
|
for (cached_block *block = unused_blocks.First(); block != NULL;
|
||||||
|
block = next) {
|
||||||
next = block->next;
|
next = block->next;
|
||||||
|
|
||||||
if (maxAccessed < block->accessed)
|
if (maxAccessed < block->accessed)
|
||||||
@ -404,14 +407,15 @@ block_cache::LowMemoryHandler(void *data, int32 level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark - private block functions
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_cached_block(block_cache *cache, cached_block *block)
|
put_cached_block(block_cache *cache, cached_block *block)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_CHANGED
|
#ifdef DEBUG_CHANGED
|
||||||
if (!block->is_dirty && block->compare != NULL && memcmp(block->current_data, block->compare, cache->block_size)) {
|
if (!block->is_dirty && block->compare != NULL
|
||||||
|
&& memcmp(block->current_data, block->compare, cache->block_size)) {
|
||||||
dprintf("new block:\n");
|
dprintf("new block:\n");
|
||||||
dump_block((const char *)block->current_data, 256, " ");
|
dump_block((const char *)block->current_data, 256, " ");
|
||||||
dprintf("unchanged block:\n");
|
dprintf("unchanged block:\n");
|
||||||
@ -458,23 +462,40 @@ put_cached_block(block_cache *cache, cached_block *block)
|
|||||||
static void
|
static void
|
||||||
put_cached_block(block_cache *cache, off_t blockNumber)
|
put_cached_block(block_cache *cache, off_t blockNumber)
|
||||||
{
|
{
|
||||||
if (blockNumber < 0 || blockNumber >= cache->max_blocks)
|
if (blockNumber < 0 || blockNumber >= cache->max_blocks) {
|
||||||
panic("put_cached_block: invalid block number %lld (max %lld)", blockNumber, cache->max_blocks - 1);
|
panic("put_cached_block: invalid block number %lld (max %lld)",
|
||||||
|
blockNumber, cache->max_blocks - 1);
|
||||||
|
}
|
||||||
|
|
||||||
cached_block *block = (cached_block *)hash_lookup(cache->hash, &blockNumber);
|
cached_block *block = (cached_block *)hash_lookup(cache->hash, &blockNumber);
|
||||||
if (block != NULL)
|
if (block != NULL)
|
||||||
put_cached_block(cache, block);
|
put_cached_block(cache, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static cached_block *
|
/*!
|
||||||
get_cached_block(block_cache *cache, off_t blockNumber, bool *allocated, bool readBlock = true)
|
Retrieves the block \a blockNumber from the hash table, if it's already
|
||||||
{
|
there, or reads it from the disk.
|
||||||
if (blockNumber < 0 || blockNumber >= cache->max_blocks)
|
|
||||||
panic("get_cached_block: invalid block number %lld (max %lld)", blockNumber, cache->max_blocks - 1);
|
|
||||||
|
|
||||||
cached_block *block = (cached_block *)hash_lookup(cache->hash, &blockNumber);
|
\param _allocated tells you wether or not a new block has been allocated
|
||||||
*allocated = false;
|
to satisfy your request.
|
||||||
|
\param readBlock if \c false, the block will not be read in case it was
|
||||||
|
not already in the cache. The block you retrieve may contain random
|
||||||
|
data.
|
||||||
|
*/
|
||||||
|
static cached_block *
|
||||||
|
get_cached_block(block_cache *cache, off_t blockNumber, bool *_allocated,
|
||||||
|
bool readBlock = true)
|
||||||
|
{
|
||||||
|
if (blockNumber < 0 || blockNumber >= cache->max_blocks) {
|
||||||
|
panic("get_cached_block: invalid block number %lld (max %lld)",
|
||||||
|
blockNumber, cache->max_blocks - 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cached_block *block = (cached_block *)hash_lookup(cache->hash,
|
||||||
|
&blockNumber);
|
||||||
|
*_allocated = false;
|
||||||
|
|
||||||
if (block == NULL) {
|
if (block == NULL) {
|
||||||
// read block into cache
|
// read block into cache
|
||||||
@ -482,8 +503,10 @@ get_cached_block(block_cache *cache, off_t blockNumber, bool *allocated, bool re
|
|||||||
if (block == NULL)
|
if (block == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
*allocated = true;
|
hash_insert(cache->hash, block);
|
||||||
|
*_allocated = true;
|
||||||
} else {
|
} else {
|
||||||
|
// TODO: currently, the data is always mapped in
|
||||||
/*
|
/*
|
||||||
if (block->ref_count == 0 && block->current_data != NULL) {
|
if (block->ref_count == 0 && block->current_data != NULL) {
|
||||||
// see if the old block can be resurrected
|
// see if the old block can be resurrected
|
||||||
@ -496,15 +519,16 @@ get_cached_block(block_cache *cache, off_t blockNumber, bool *allocated, bool re
|
|||||||
if (block->current_data == NULL)
|
if (block->current_data == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
*allocated = true;
|
*_allocated = true;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*allocated && readBlock) {
|
if (*_allocated && readBlock) {
|
||||||
int32 blockSize = cache->block_size;
|
int32 blockSize = cache->block_size;
|
||||||
|
|
||||||
if (read_pos(cache->fd, blockNumber * blockSize, block->current_data, blockSize) < blockSize) {
|
if (read_pos(cache->fd, blockNumber * blockSize, block->current_data,
|
||||||
|
blockSize) < blockSize) {
|
||||||
hash_remove(cache->hash, block);
|
hash_remove(cache->hash, block);
|
||||||
cache->FreeBlock(block);
|
cache->FreeBlock(block);
|
||||||
FATAL(("could not read block %Ld\n", blockNumber));
|
FATAL(("could not read block %Ld\n", blockNumber));
|
||||||
@ -525,24 +549,29 @@ get_cached_block(block_cache *cache, off_t blockNumber, bool *allocated, bool re
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the writable block data for the requested blockNumber.
|
/*!
|
||||||
* If \a cleared is true, the block is not read from disk; an empty block
|
Returns the writable block data for the requested blockNumber.
|
||||||
* is returned.
|
If \a cleared is true, the block is not read from disk; an empty block
|
||||||
* This is the only method to insert a block into a transaction. It makes
|
is returned.
|
||||||
* sure that the previous block contents are preserved in that case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
This is the only method to insert a block into a transaction. It makes
|
||||||
|
sure that the previous block contents are preserved in that case.
|
||||||
|
*/
|
||||||
static void *
|
static void *
|
||||||
get_writable_cached_block(block_cache *cache, off_t blockNumber, off_t base, off_t length,
|
get_writable_cached_block(block_cache *cache, off_t blockNumber, off_t base,
|
||||||
int32 transactionID, bool cleared)
|
off_t length, int32 transactionID, bool cleared)
|
||||||
{
|
{
|
||||||
TRACE(("get_writable_cached_block(blockNumber = %Ld, transaction = %ld)\n", blockNumber, transactionID));
|
TRACE(("get_writable_cached_block(blockNumber = %Ld, transaction = %ld)\n",
|
||||||
|
blockNumber, transactionID));
|
||||||
|
|
||||||
if (blockNumber < 0 || blockNumber >= cache->max_blocks)
|
if (blockNumber < 0 || blockNumber >= cache->max_blocks) {
|
||||||
panic("get_writable_cached_block: invalid block number %lld (max %lld)", blockNumber, cache->max_blocks - 1);
|
panic("get_writable_cached_block: invalid block number %lld (max %lld)",
|
||||||
|
blockNumber, cache->max_blocks - 1);
|
||||||
|
}
|
||||||
|
|
||||||
bool allocated;
|
bool allocated;
|
||||||
cached_block *block = get_cached_block(cache, blockNumber, &allocated, !cleared);
|
cached_block *block = get_cached_block(cache, blockNumber, &allocated,
|
||||||
|
!cleared);
|
||||||
if (block == NULL)
|
if (block == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -568,7 +597,8 @@ get_writable_cached_block(block_cache *cache, off_t blockNumber, off_t base, off
|
|||||||
// get new transaction
|
// get new transaction
|
||||||
cache_transaction *transaction = lookup_transaction(cache, transactionID);
|
cache_transaction *transaction = lookup_transaction(cache, transactionID);
|
||||||
if (transaction == NULL) {
|
if (transaction == NULL) {
|
||||||
panic("get_writable_cached_block(): invalid transaction %ld!\n", transactionID);
|
panic("get_writable_cached_block(): invalid transaction %ld!\n",
|
||||||
|
transactionID);
|
||||||
put_cached_block(cache, block);
|
put_cached_block(cache, block);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -601,7 +631,7 @@ get_writable_cached_block(block_cache *cache, off_t blockNumber, off_t base, off
|
|||||||
// remember any previous contents for the parent transaction
|
// remember any previous contents for the parent transaction
|
||||||
block->parent_data = cache->Allocate();
|
block->parent_data = cache->Allocate();
|
||||||
if (block->parent_data == NULL) {
|
if (block->parent_data == NULL) {
|
||||||
// ToDo: maybe we should just continue the current transaction in this case...
|
// TODO: maybe we should just continue the current transaction in this case...
|
||||||
FATAL(("could not allocate parent\n"));
|
FATAL(("could not allocate parent\n"));
|
||||||
put_cached_block(cache, block);
|
put_cached_block(cache, block);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -621,20 +651,24 @@ get_writable_cached_block(block_cache *cache, off_t blockNumber, off_t base, off
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
write_cached_block(block_cache *cache, cached_block *block, bool deleteTransaction)
|
write_cached_block(block_cache *cache, cached_block *block,
|
||||||
|
bool deleteTransaction)
|
||||||
{
|
{
|
||||||
cache_transaction *previous = block->previous_transaction;
|
cache_transaction *previous = block->previous_transaction;
|
||||||
int32 blockSize = cache->block_size;
|
int32 blockSize = cache->block_size;
|
||||||
|
|
||||||
void *data = previous && block->original_data ? block->original_data : block->current_data;
|
void *data = previous && block->original_data
|
||||||
|
? block->original_data : block->current_data;
|
||||||
// we first need to write back changes from previous transactions
|
// we first need to write back changes from previous transactions
|
||||||
|
|
||||||
TRACE(("write_cached_block(block %Ld)\n", block->block_number));
|
TRACE(("write_cached_block(block %Ld)\n", block->block_number));
|
||||||
|
|
||||||
ssize_t written = write_pos(cache->fd, block->block_number * blockSize, data, blockSize);
|
ssize_t written = write_pos(cache->fd, block->block_number * blockSize,
|
||||||
|
data, blockSize);
|
||||||
|
|
||||||
if (written < blockSize) {
|
if (written < blockSize) {
|
||||||
FATAL(("could not write back block %Ld (%s)\n", block->block_number, strerror(errno)));
|
FATAL(("could not write back block %Ld (%s)\n", block->block_number,
|
||||||
|
strerror(errno)));
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,11 +683,15 @@ write_cached_block(block_cache *cache, cached_block *block, bool deleteTransacti
|
|||||||
if (--previous->num_blocks == 0) {
|
if (--previous->num_blocks == 0) {
|
||||||
TRACE(("cache transaction %ld finished!\n", previous->id));
|
TRACE(("cache transaction %ld finished!\n", previous->id));
|
||||||
|
|
||||||
if (previous->notification_hook != NULL)
|
if (previous->notification_hook != NULL) {
|
||||||
previous->notification_hook(previous->id, previous->notification_data);
|
previous->notification_hook(previous->id,
|
||||||
|
previous->notification_data);
|
||||||
|
}
|
||||||
|
|
||||||
if (deleteTransaction)
|
if (deleteTransaction) {
|
||||||
|
hash_remove(cache->transaction_hash, previous);
|
||||||
delete_transaction(cache, previous);
|
delete_transaction(cache, previous);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,8 +715,10 @@ cache_start_transaction(void *_cache)
|
|||||||
block_cache *cache = (block_cache *)_cache;
|
block_cache *cache = (block_cache *)_cache;
|
||||||
BenaphoreLocker locker(&cache->lock);
|
BenaphoreLocker locker(&cache->lock);
|
||||||
|
|
||||||
if (cache->last_transaction && cache->last_transaction->open)
|
if (cache->last_transaction && cache->last_transaction->open) {
|
||||||
panic("last transaction (%ld) still open!\n", cache->last_transaction->id);
|
panic("last transaction (%ld) still open!\n",
|
||||||
|
cache->last_transaction->id);
|
||||||
|
}
|
||||||
|
|
||||||
cache_transaction *transaction = new(nothrow) cache_transaction;
|
cache_transaction *transaction = new(nothrow) cache_transaction;
|
||||||
if (transaction == NULL)
|
if (transaction == NULL)
|
||||||
@ -706,17 +746,21 @@ cache_sync_transaction(void *_cache, int32 id)
|
|||||||
hash_open(cache->transaction_hash, &iterator);
|
hash_open(cache->transaction_hash, &iterator);
|
||||||
|
|
||||||
cache_transaction *transaction;
|
cache_transaction *transaction;
|
||||||
while ((transaction = (cache_transaction *)hash_next(cache->transaction_hash, &iterator)) != NULL) {
|
while ((transaction = (cache_transaction *)hash_next(
|
||||||
// ToDo: fix hash interface to make this easier
|
cache->transaction_hash, &iterator)) != NULL) {
|
||||||
|
// close all earlier transactions which haven't been closed yet
|
||||||
|
|
||||||
if (transaction->id <= id && !transaction->open) {
|
if (transaction->id <= id && !transaction->open) {
|
||||||
|
// write back all of their remaining dirty blocks
|
||||||
while (transaction->num_blocks > 0) {
|
while (transaction->num_blocks > 0) {
|
||||||
status = write_cached_block(cache, transaction->blocks.Head(), false);
|
status = write_cached_block(cache, transaction->blocks.Head(),
|
||||||
|
false);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hash_remove_current(cache->transaction_hash, &iterator);
|
||||||
delete_transaction(cache, transaction);
|
delete_transaction(cache, transaction);
|
||||||
hash_rewind(cache->transaction_hash, &iterator);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +770,8 @@ cache_sync_transaction(void *_cache, int32 id)
|
|||||||
|
|
||||||
|
|
||||||
extern "C" status_t
|
extern "C" status_t
|
||||||
cache_end_transaction(void *_cache, int32 id, transaction_notification_hook hook, void *data)
|
cache_end_transaction(void *_cache, int32 id,
|
||||||
|
transaction_notification_hook hook, void *data)
|
||||||
{
|
{
|
||||||
block_cache *cache = (block_cache *)_cache;
|
block_cache *cache = (block_cache *)_cache;
|
||||||
BenaphoreLocker locker(&cache->lock);
|
BenaphoreLocker locker(&cache->lock);
|
||||||
@ -814,16 +859,17 @@ cache_abort_transaction(void *_cache, int32 id)
|
|||||||
block->transaction = NULL;
|
block->transaction = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hash_remove(cache->transaction_hash, transaction);
|
||||||
delete_transaction(cache, transaction);
|
delete_transaction(cache, transaction);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Acknowledges the current parent transaction, and starts a new transaction
|
/*!
|
||||||
* from its sub transaction.
|
Acknowledges the current parent transaction, and starts a new transaction
|
||||||
* The new transaction also gets a new transaction ID.
|
from its sub transaction.
|
||||||
*/
|
The new transaction also gets a new transaction ID.
|
||||||
|
*/
|
||||||
extern "C" int32
|
extern "C" int32
|
||||||
cache_detach_sub_transaction(void *_cache, int32 id,
|
cache_detach_sub_transaction(void *_cache, int32 id,
|
||||||
transaction_notification_hook hook, void *data)
|
transaction_notification_hook hook, void *data)
|
||||||
@ -869,7 +915,8 @@ cache_detach_sub_transaction(void *_cache, int32 id,
|
|||||||
cache->Free(block->original_data);
|
cache->Free(block->original_data);
|
||||||
block->original_data = NULL;
|
block->original_data = NULL;
|
||||||
}
|
}
|
||||||
if (block->parent_data != NULL && block->parent_data != block->current_data) {
|
if (block->parent_data != NULL
|
||||||
|
&& block->parent_data != block->current_data) {
|
||||||
// we need to move this block over to the new transaction
|
// we need to move this block over to the new transaction
|
||||||
block->original_data = block->parent_data;
|
block->original_data = block->parent_data;
|
||||||
if (last == NULL)
|
if (last == NULL)
|
||||||
@ -924,7 +971,8 @@ cache_abort_sub_transaction(void *_cache, int32 id)
|
|||||||
if (block->original_data != NULL) {
|
if (block->original_data != NULL) {
|
||||||
// the parent transaction didn't change the block, but the sub
|
// the parent transaction didn't change the block, but the sub
|
||||||
// transaction did - we need to revert from the original data
|
// transaction did - we need to revert from the original data
|
||||||
memcpy(block->current_data, block->original_data, cache->block_size);
|
memcpy(block->current_data, block->original_data,
|
||||||
|
cache->block_size);
|
||||||
}
|
}
|
||||||
} else if (block->parent_data != block->current_data) {
|
} else if (block->parent_data != block->current_data) {
|
||||||
// the block has been changed and must be restored
|
// the block has been changed and must be restored
|
||||||
@ -985,8 +1033,8 @@ cache_start_sub_transaction(void *_cache, int32 id)
|
|||||||
|
|
||||||
|
|
||||||
extern "C" status_t
|
extern "C" status_t
|
||||||
cache_next_block_in_transaction(void *_cache, int32 id, uint32 *_cookie, off_t *_blockNumber,
|
cache_next_block_in_transaction(void *_cache, int32 id, uint32 *_cookie,
|
||||||
void **_data, void **_unchangedData)
|
off_t *_blockNumber, void **_data, void **_unchangedData)
|
||||||
{
|
{
|
||||||
cached_block *block = (cached_block *)*_cookie;
|
cached_block *block = (cached_block *)*_cookie;
|
||||||
block_cache *cache = (block_cache *)_cache;
|
block_cache *cache = (block_cache *)_cache;
|
||||||
@ -1063,7 +1111,8 @@ block_cache_delete(void *_cache, bool allowWrites)
|
|||||||
|
|
||||||
uint32 cookie = 0;
|
uint32 cookie = 0;
|
||||||
cached_block *block;
|
cached_block *block;
|
||||||
while ((block = (cached_block *)hash_remove_first(cache->hash, &cookie)) != NULL) {
|
while ((block = (cached_block *)hash_remove_first(cache->hash,
|
||||||
|
&cookie)) != NULL) {
|
||||||
cache->FreeBlock(block);
|
cache->FreeBlock(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,7 +1120,8 @@ block_cache_delete(void *_cache, bool allowWrites)
|
|||||||
|
|
||||||
cookie = 0;
|
cookie = 0;
|
||||||
cache_transaction *transaction;
|
cache_transaction *transaction;
|
||||||
while ((transaction = (cache_transaction *)hash_remove_first(cache->transaction_hash, &cookie)) != NULL) {
|
while ((transaction = (cache_transaction *)hash_remove_first(
|
||||||
|
cache->transaction_hash, &cookie)) != NULL) {
|
||||||
delete transaction;
|
delete transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1082,7 +1132,8 @@ block_cache_delete(void *_cache, bool allowWrites)
|
|||||||
extern "C" void *
|
extern "C" void *
|
||||||
block_cache_create(int fd, off_t numBlocks, size_t blockSize, bool readOnly)
|
block_cache_create(int fd, off_t numBlocks, size_t blockSize, bool readOnly)
|
||||||
{
|
{
|
||||||
block_cache *cache = new(nothrow) block_cache(fd, numBlocks, blockSize, readOnly);
|
block_cache *cache = new(nothrow) block_cache(fd, numBlocks, blockSize,
|
||||||
|
readOnly);
|
||||||
if (cache == NULL)
|
if (cache == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -1212,12 +1263,20 @@ block_cache_get(void *_cache, off_t blockNumber)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Changes the internal status of a writable block to \a dirty. This can be
|
||||||
|
helpful in case you realize you don't need to change that block anymore
|
||||||
|
for whatever reason.
|
||||||
|
|
||||||
|
Note, you must only use this function on blocks that were acquired
|
||||||
|
writable!
|
||||||
|
*/
|
||||||
extern "C" status_t
|
extern "C" status_t
|
||||||
block_cache_set_dirty(void *_cache, off_t blockNumber, bool isDirty, int32 transaction)
|
block_cache_set_dirty(void *_cache, off_t blockNumber, bool dirty,
|
||||||
|
int32 transaction)
|
||||||
{
|
{
|
||||||
// not yet implemented
|
// TODO: not yet implemented
|
||||||
// Note, you must only use this function on blocks that were acquired writable!
|
if (dirty)
|
||||||
if (isDirty)
|
|
||||||
panic("block_cache_set_dirty(): not yet implemented that way!\n");
|
panic("block_cache_set_dirty(): not yet implemented that way!\n");
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
Loading…
Reference in New Issue
Block a user