summaryrefslogtreecommitdiff
path: root/ext2fs/balloc.c
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2013-05-03 19:56:51 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2013-09-16 01:22:25 +0200
commitea4802bc0975218544cb447df37b704f60ef2fde (patch)
treec129132f171f570bf89760e4bddc14317a440f79 /ext2fs/balloc.c
parent0e847864cef404f555387d7fcc97f7dbe769e1e9 (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.c31
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",