diff options
author | Richard Braun <rbraun@sceen.net> | 2013-05-03 19:56:51 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-09-16 01:22:25 +0200 |
commit | ea4802bc0975218544cb447df37b704f60ef2fde (patch) | |
tree | c129132f171f570bf89760e4bddc14317a440f79 /ext2fs/balloc.c | |
parent | 0e847864cef404f555387d7fcc97f7dbe769e1e9 (diff) |
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 <hurd/store.h> and <hurd/ihash.h>.
(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 <unistd.h> 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.
Diffstat (limited to 'ext2fs/balloc.c')
-rw-r--r-- | ext2fs/balloc.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/ext2fs/balloc.c b/ext2fs/balloc.c index b2d2eab9..efef8ae4 100644 --- a/ext2fs/balloc.c +++ b/ext2fs/balloc.c @@ -92,7 +92,7 @@ ext2_free_blocks (block_t block, unsigned long count) block, count); } gdp = group_desc (block_group); - bh = bptr (gdp->bg_block_bitmap); + bh = disk_cache_block_ref (gdp->bg_block_bitmap); if (in_range (gdp->bg_block_bitmap, block, gcount) || in_range (gdp->bg_inode_bitmap, block, gcount) || @@ -114,6 +114,7 @@ ext2_free_blocks (block_t block, unsigned long count) } record_global_poke (bh); + disk_cache_block_ref_ptr (gdp); record_global_poke (gdp); block += gcount; @@ -139,7 +140,7 @@ ext2_new_block (block_t goal, block_t prealloc_goal, block_t *prealloc_count, block_t *prealloc_block) { - char *bh; + char *bh = NULL; char *p, *r; int i, j, k, tmp; unsigned long lmap; @@ -165,6 +166,7 @@ ext2_new_block (block_t goal, ext2_debug ("goal=%u", goal); repeat: + assert (bh == NULL); /* * First, test whether the goal block is free. */ @@ -179,7 +181,7 @@ repeat: if (j) goal_attempts++; #endif - bh = bptr (gdp->bg_block_bitmap); + bh = disk_cache_block_ref (gdp->bg_block_bitmap); ext2_debug ("goal is at %d:%d", i, j); @@ -245,6 +247,9 @@ repeat: j = k; goto got_block; } + + disk_cache_block_deref (bh); + bh = NULL; } ext2_debug ("bit not found in block group %d", i); @@ -267,7 +272,8 @@ repeat: pthread_spin_unlock (&global_lock); return 0; } - bh = bptr (gdp->bg_block_bitmap); + assert (bh == NULL); + bh = disk_cache_block_ref (gdp->bg_block_bitmap); r = memscan (bh, 0, sblock->s_blocks_per_group >> 3); j = (r - bh) << 3; if (j < sblock->s_blocks_per_group) @@ -277,12 +283,15 @@ repeat: sblock->s_blocks_per_group); if (j >= sblock->s_blocks_per_group) { + disk_cache_block_deref (bh); + bh = NULL; ext2_error ("free blocks count corrupted for block group %d", i); pthread_spin_unlock (&global_lock); return 0; } search_back: + assert (bh != NULL); /* * We have succeeded in finding a free byte in the block * bitmap. Now search backwards up to 7 bits to find the @@ -291,6 +300,7 @@ search_back: for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh); k++, j--); got_block: + assert (bh != NULL); ext2_debug ("using block group %d (%d)", i, gdp->bg_free_blocks_count); @@ -304,6 +314,8 @@ got_block: if (set_bit (j, bh)) { ext2_warning ("bit already set for block %d", j); + disk_cache_block_deref (bh); + bh = NULL; goto repeat; } @@ -351,6 +363,7 @@ got_block: j = tmp; record_global_poke (bh); + bh = NULL; if (j >= sblock->s_blocks_count) { @@ -363,12 +376,14 @@ got_block: j, goal_hits, goal_attempts); gdp->bg_free_blocks_count--; + disk_cache_block_ref_ptr (gdp); record_global_poke (gdp); sblock->s_free_blocks_count--; sblock_dirty = 1; sync_out: + assert (bh == NULL); pthread_spin_unlock (&global_lock); alloc_sync (0); @@ -390,9 +405,12 @@ ext2_count_free_blocks () gdp = NULL; for (i = 0; i < groups_count; i++) { + void *bh; gdp = group_desc (i); desc_count += gdp->bg_free_blocks_count; - x = count_free (bptr (gdp->bg_block_bitmap), block_size); + bh = disk_cache_block_ref (gdp->bg_block_bitmap); + x = count_free (bh, block_size); + disk_cache_block_deref (bh); printf ("group %d: stored = %d, counted = %lu", i, gdp->bg_free_blocks_count, x); bitmap_count += x; @@ -453,7 +471,7 @@ ext2_check_blocks_bitmap () gdp = group_desc (i); desc_count += gdp->bg_free_blocks_count; - bh = bptr (gdp->bg_block_bitmap); + bh = disk_cache_block_ref (gdp->bg_block_bitmap); if (!EXT2_HAS_RO_COMPAT_FEATURE (sblock, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) @@ -479,6 +497,7 @@ ext2_check_blocks_bitmap () ext2_error ("block #%d of the inode table in group %d is marked free", j, i); x = count_free (bh, block_size); + disk_cache_block_deref (bh); if (gdp->bg_free_blocks_count != x) ext2_error ("wrong free blocks count for group %d," " stored = %d, counted = %lu", |