From ea4802bc0975218544cb447df37b704f60ef2fde Mon Sep 17 00:00:00 2001 From: Richard Braun Date: Fri, 3 May 2013 19:56:51 +0200 Subject: Large store support for ext2fs This is a revised version of the large store patch for ext2fs, written by Ognyan Kulev. It provides support for stores larger than 2 GiB. * ext2fs/balloc.c: Use the new disk_cache_block_ref and disk_cache_block_deref functions to access blocks from the disk cache. * ext2fs/ext2fs.c (main): Update initialization call to pokel_init, and call map_hypermetadata instead of get_hypermetadata. * ext2fs/ext2fs.h: Include and . (DISK_CACHE_BLOCKS): New macro. (DC_INCORE): Likewise. (DC_UNTOUCHED): Likewise. (DC_FIXED): Likewise. (DC_DONT_REUSE): Likewise. (DC_NO_BLOCK): Likewise. (DISK_CACHE_LAST_READ_XOR) [!NDEBUG]: Likewise. (struct disk_cache_info): New structure. (disk_cache): New external variable. (disk_cache_size): Likewise. (disk_cache_blocks): Likewise. (disk_cache_bptr): Likewise. (disk_cache_info): Likewise. (disk_cache_lock): Likewise. (disk_cache_reassociation): Likewise. (disk_cache_block_ref): New declaration. (disk_cache_block_ref_ptr): Likewise. (disk_cache_block_deref): Likewise. (disk_cache_block_is_ref): Likewise. (map_hypermetadata): Likewise. (trunc_block): Cast to off_t. (round_block): Likewise. (boffs): Likewise. (bptr_index): New macro. (boffs_ptr): Rewrite as an inline function to make it look up a block from the disk cache. (bptr_offs): Likewise. (dino): Remove function, replaced with ... (dino_ref): ... this one, which adds a reference to the inode block. (dino_deref): New inline function. (record_global_poke): Make sure block is referenced. (record_indir_poke): Likewise. (sync_global_ptr): Remove block reference, and adjust call to pager_sync_some. (sync_global): Add debug call to print wait parameter. * ext2fs/getblk.c: Use the new disk_cache_block_ref and disk_cache_block_deref functions to access blocks from the disk cache. * ext2fs/hyper.c (get_hypermetadata): Read the superblock from the store now that it's not directly mapped in memory. Move the initialization of zeroblock here from ... (map_hypermetadata): ... here. Also, set the superblock pointer. (diskfs_set_hypermetadata): Add a reference to the superblock. (diskfs_readonly_changed): Update call to mprotect. * ext2fs/ialloc.c: Use the new disk_cache_block_ref, disk_cache_block_ref_ptr and disk_cache_block_deref functions to access blocks from the disk cache. * ext2fs/inode.c: Update calls that used the disk image to use the disk cache, and use the new reference handling functions where appropriate. * ext2fs/pager.c: Include and "../libpager/priv.h". (disk_image): Remove global variable. (disk_pager_read_page): Update cache information. (disk_pager_write_page): Likewise. (disk_pager_notify_evict): New function. (pager_notify_evict): Call disk_pager_notify_evict appropriately. (disk_cache): New global variable. (disk_cache_size): Likewise. (disk_cache_blocks): Likewise. (disk_cache_bptr): Likewise. (disk_cache_info): Likewise. (disk_cache_hint): Likewise. (disk_cache_lock): Likewise. (disk_cache_reassociation): Likewise. (disk_cache_init): New function. (disk_cache_return_unused): Likewise. (disk_cache_block_ref): Likewise. (disk_cache_block_ref_ptr): Likewise. (disk_cache_block_deref): Likewise. (disk_cache_block_is_ref): Likewise. (create_disk_pager): Update initialization of the disk pager. * ext2fs/pokel.c (pokel_add): Drop block references with disk_cache_block_deref. (_pokel_exec): Likewise. * ext2fs/truncate.c (trunc_indirect): Use the new disk_cache_block_ref and disk_cache_block_deref functions to access blocks from the disk cache. --- ext2fs/pokel.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'ext2fs/pokel.c') diff --git a/ext2fs/pokel.c b/ext2fs/pokel.c index a8b16c97..3afb32e4 100644 --- a/ext2fs/pokel.c +++ b/ext2fs/pokel.c @@ -67,12 +67,27 @@ pokel_add (struct pokel *pokel, void *loc, vm_size_t length) vm_offset_t p_offs = pl->offset; vm_size_t p_end = p_offs + pl->length; - if (p_offs == offset && p_end == end) - break; + if (p_offs <= offset && end <= p_end) + { + if (pokel->image == disk_cache) + for (vm_offset_t i = offset; i < end; i += block_size) + disk_cache_block_deref (disk_cache + i); + + break; + } else if (p_end >= offset && end >= p_offs) { pl->offset = offset < p_offs ? offset : p_offs; pl->length = (end > p_end ? end : p_end) - pl->offset; + + if (pokel->image == disk_cache) + { + vm_offset_t i_begin = p_offs > offset ? p_offs : offset; + vm_offset_t i_end = p_end < end ? p_end : end; + for (vm_offset_t i = i_begin; i < i_end; i += block_size) + disk_cache_block_deref (disk_cache + i); + } + ext2_debug ("extended 0x%x[%ul] to 0x%x[%ul]", p_offs, p_end - p_offs, pl->offset, pl->length); break; @@ -113,11 +128,21 @@ _pokel_exec (struct pokel *pokel, int sync, int wait) pthread_spin_unlock (&pokel->lock); for (pl = pokes; pl; last = pl, pl = pl->next) - if (sync) - { - ext2_debug ("syncing 0x%x[%ul]", pl->offset, pl->length); - pager_sync_some (pokel->pager, pl->offset, pl->length, wait); - } + { + if (sync) + { + ext2_debug ("syncing 0x%lx[%ul]", pl->offset, pl->length); + pager_sync_some (pokel->pager, pl->offset, pl->length, wait); + } + + if (pokel->image == disk_cache) + { + vm_offset_t begin = trunc_block (pl->offset); + vm_offset_t end = round_block (pl->offset + pl->length); + for (vm_offset_t i = begin; i != end; i += block_size) + disk_cache_block_deref (pokel->image + i); + } + } if (last) { -- cgit v1.2.3