* You can now create the block cache in read-only mode (using an additional
parameter during construction). * Doing so will now result in a kernel panic whenever your file system tries to write to a block. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18719 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -31,7 +31,7 @@ extern int32 cache_blocks_in_sub_transaction(void *_cache, int32 id);
|
|||||||
|
|
||||||
/* block cache */
|
/* block cache */
|
||||||
extern void block_cache_delete(void *_cache, bool allowWrites);
|
extern void block_cache_delete(void *_cache, bool allowWrites);
|
||||||
extern void *block_cache_create(int fd, off_t numBlocks, size_t blockSize);
|
extern void *block_cache_create(int fd, off_t numBlocks, size_t blockSize, bool readOnly);
|
||||||
extern status_t block_cache_sync(void *_cache);
|
extern status_t block_cache_sync(void *_cache);
|
||||||
|
|
||||||
extern status_t block_cache_make_writable(void *_cache, off_t blockNumber, int32 transaction);
|
extern status_t block_cache_make_writable(void *_cache, off_t blockNumber, int32 transaction);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ DeviceOpener::Open(const char *device, int mode)
|
|||||||
void *
|
void *
|
||||||
DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
|
DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
|
||||||
{
|
{
|
||||||
return block_cache_create(fDevice, numBlocks, blockSize);
|
return block_cache_create(fDevice, numBlocks, blockSize, fMode == O_RDONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ DeviceOpener::GetSize(off_t *_size, uint32 *_blockSize)
|
|||||||
|
|
||||||
if (_size) {
|
if (_size) {
|
||||||
*_size = 1LL * geometry.head_count * geometry.cylinder_count
|
*_size = 1LL * geometry.head_count * geometry.cylinder_count
|
||||||
* geometry.sectors_per_track * geometry.bytes_per_sector;
|
* geometry.sectors_per_track * geometry.bytes_per_sector;
|
||||||
}
|
}
|
||||||
if (_blockSize)
|
if (_blockSize)
|
||||||
*_blockSize = geometry.bytes_per_sector;
|
*_blockSize = geometry.bytes_per_sector;
|
||||||
|
|||||||
@@ -436,7 +436,8 @@ static status_t mount_fat_disk(const char *path, mount_id nsid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// initialize block cache
|
// initialize block cache
|
||||||
vol->fBlockCache = block_cache_create(vol->fd, vol->total_sectors, vol->bytes_per_sector);
|
vol->fBlockCache = block_cache_create(vol->fd, vol->total_sectors,
|
||||||
|
vol->bytes_per_sector, (vol->flags & B_FS_IS_READONLY) != 0);
|
||||||
if (vol->fBlockCache == NULL) {
|
if (vol->fBlockCache == NULL) {
|
||||||
dprintf("error initializing block cache\n");
|
dprintf("error initializing block cache\n");
|
||||||
goto error;
|
goto error;
|
||||||
|
|||||||
@@ -267,7 +267,8 @@ ISOMount(const char *path, const int flags, nspace **newVol, bool allow_joliet)
|
|||||||
|
|
||||||
/* Initialize access to the cache so that we can do cached i/o */
|
/* Initialize access to the cache so that we can do cached i/o */
|
||||||
TRACE(("ISO9660: cache init: dev %d, max blocks %Ld\n", vol->fd, maxBlocks));
|
TRACE(("ISO9660: cache init: dev %d, max blocks %Ld\n", vol->fd, maxBlocks));
|
||||||
vol->fBlockCache = block_cache_create(vol->fd, maxBlocks, vol->logicalBlkSize[FS_DATA_FORMAT]);
|
vol->fBlockCache = block_cache_create(vol->fd, maxBlocks,
|
||||||
|
vol->logicalBlkSize[FS_DATA_FORMAT], true);
|
||||||
is_iso = true;
|
is_iso = true;
|
||||||
} else if ((*buffer == 0x02) && is_iso && allow_joliet) {
|
} else if ((*buffer == 0x02) && is_iso && allow_joliet) {
|
||||||
// ISO_VD_SUPPLEMENTARY
|
// ISO_VD_SUPPLEMENTARY
|
||||||
@@ -287,7 +288,6 @@ ISOMount(const char *path, const int flags, nspace **newVol, bool allow_joliet)
|
|||||||
// update root directory record.
|
// update root directory record.
|
||||||
if (vol->joliet_level > 0)
|
if (vol->joliet_level > 0)
|
||||||
InitNode(&(vol->rootDirRec), &buffer[156], NULL, 0);
|
InitNode(&(vol->rootDirRec), &buffer[156], NULL, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (*(unsigned char *)buffer == 0xff) {
|
} else if (*(unsigned char *)buffer == 0xff) {
|
||||||
// ISO_VD_END
|
// ISO_VD_END
|
||||||
|
|||||||
+12
-4
@@ -149,7 +149,7 @@ 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)
|
block_cache::block_cache(int _fd, off_t numBlocks, size_t blockSize, bool readOnly)
|
||||||
:
|
:
|
||||||
hash(NULL),
|
hash(NULL),
|
||||||
fd(_fd),
|
fd(_fd),
|
||||||
@@ -158,7 +158,8 @@ block_cache::block_cache(int _fd, off_t numBlocks, size_t blockSize)
|
|||||||
next_transaction_id(1),
|
next_transaction_id(1),
|
||||||
last_transaction(NULL),
|
last_transaction(NULL),
|
||||||
transaction_hash(NULL),
|
transaction_hash(NULL),
|
||||||
ranges_hash(NULL)
|
ranges_hash(NULL),
|
||||||
|
read_only(readOnly)
|
||||||
{
|
{
|
||||||
hash = hash_init(32, 0, &cached_block::Compare, &cached_block::Hash);
|
hash = hash_init(32, 0, &cached_block::Compare, &cached_block::Hash);
|
||||||
if (hash == NULL)
|
if (hash == NULL)
|
||||||
@@ -1078,9 +1079,9 @@ block_cache_delete(void *_cache, bool allowWrites)
|
|||||||
|
|
||||||
|
|
||||||
extern "C" void *
|
extern "C" void *
|
||||||
block_cache_create(int fd, off_t numBlocks, size_t blockSize)
|
block_cache_create(int fd, off_t numBlocks, size_t blockSize, bool readOnly)
|
||||||
{
|
{
|
||||||
block_cache *cache = new block_cache(fd, numBlocks, blockSize);
|
block_cache *cache = new block_cache(fd, numBlocks, blockSize, readOnly);
|
||||||
if (cache == NULL)
|
if (cache == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -1126,6 +1127,9 @@ block_cache_make_writable(void *_cache, off_t blockNumber, int32 transaction)
|
|||||||
block_cache *cache = (block_cache *)_cache;
|
block_cache *cache = (block_cache *)_cache;
|
||||||
BenaphoreLocker locker(&cache->lock);
|
BenaphoreLocker locker(&cache->lock);
|
||||||
|
|
||||||
|
if (cache->read_only)
|
||||||
|
panic("tried to make block writable on a read-only cache!");
|
||||||
|
|
||||||
// ToDo: this can be done better!
|
// ToDo: this can be done better!
|
||||||
void *block = get_writable_cached_block(cache, blockNumber,
|
void *block = get_writable_cached_block(cache, blockNumber,
|
||||||
blockNumber, 1, transaction, false);
|
blockNumber, 1, transaction, false);
|
||||||
@@ -1147,6 +1151,8 @@ block_cache_get_writable_etc(void *_cache, off_t blockNumber, off_t base,
|
|||||||
|
|
||||||
TRACE(("block_cache_get_writable_etc(block = %Ld, transaction = %ld)\n",
|
TRACE(("block_cache_get_writable_etc(block = %Ld, transaction = %ld)\n",
|
||||||
blockNumber, transaction));
|
blockNumber, transaction));
|
||||||
|
if (cache->read_only)
|
||||||
|
panic("tried to get writable block on a read-only cache!");
|
||||||
|
|
||||||
return get_writable_cached_block(cache, blockNumber, base, length,
|
return get_writable_cached_block(cache, blockNumber, base, length,
|
||||||
transaction, false);
|
transaction, false);
|
||||||
@@ -1169,6 +1175,8 @@ block_cache_get_empty(void *_cache, off_t blockNumber, int32 transaction)
|
|||||||
|
|
||||||
TRACE(("block_cache_get_empty(block = %Ld, transaction = %ld)\n",
|
TRACE(("block_cache_get_empty(block = %Ld, transaction = %ld)\n",
|
||||||
blockNumber, transaction));
|
blockNumber, transaction));
|
||||||
|
if (cache->read_only)
|
||||||
|
panic("tried to get empty writable block on a read-only cache!");
|
||||||
|
|
||||||
return get_writable_cached_block((block_cache *)_cache, blockNumber,
|
return get_writable_cached_block((block_cache *)_cache, blockNumber,
|
||||||
blockNumber, 1, transaction, true);
|
blockNumber, 1, transaction, true);
|
||||||
|
|||||||
+3
-1
@@ -116,7 +116,9 @@ struct block_cache {
|
|||||||
block_list unmapped_blocks;
|
block_list unmapped_blocks;
|
||||||
block_list unused_blocks;
|
block_list unused_blocks;
|
||||||
|
|
||||||
block_cache(int fd, off_t numBlocks, size_t blockSize);
|
bool read_only;
|
||||||
|
|
||||||
|
block_cache(int fd, off_t numBlocks, size_t blockSize, bool readOnly);
|
||||||
~block_cache();
|
~block_cache();
|
||||||
|
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|||||||
Reference in New Issue
Block a user