From f1f115a78f5ea599fc5f8815a741d43fedd5840d Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 23 Jul 2007 04:32:48 -0400 Subject: [PATCH] libext2fs: 32-bit bitmap refactorization, part 3 Create new functions ext2fs_{set,get}_{inode,block}_bitmap_range() which allow programs like e2fsck, dumpe2fs, etc. to get and set chunks of the bitmap at a time. Move the representation details of the 32-bit old-style bitmaps into gen_bitmap.c. Change calls in dumpe2fs, mke2s, et. al to use the new abstractions. Signed-off-by: "Theodore Ts'o" --- e2fsck/pass5.c | 2 +- lib/ext2fs/bitmaps.c | 37 ++++++++++- lib/ext2fs/ext2fs.h | 33 ++++++---- lib/ext2fs/gen_bitmap.c | 45 +++++++++++++- lib/ext2fs/imager.c | 133 +++++++++++++++++++++++----------------- lib/ext2fs/rw_bitmaps.c | 123 +++++++++++++++++++++++++++---------- misc/dumpe2fs.c | 18 ++++-- 7 files changed, 282 insertions(+), 109 deletions(-) diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c index 56619c3a..deb558a8 100644 --- a/e2fsck/pass5.c +++ b/e2fsck/pass5.c @@ -563,7 +563,7 @@ static void check_block_end(e2fsck_t ctx) clear_problem_context(&pctx); - end = fs->block_map->start + + end = ext2fs_get_block_bitmap_start(fs->block_map) + (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1; pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end, &save_blocks_count); diff --git a/lib/ext2fs/bitmaps.c b/lib/ext2fs/bitmaps.c index 7d14cfff..b033fa36 100644 --- a/lib/ext2fs/bitmaps.c +++ b/lib/ext2fs/bitmaps.c @@ -52,7 +52,6 @@ errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs, const char *descr, ext2fs_inode_bitmap *ret) { - errcode_t retval; __u32 start, end, real_end; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -72,7 +71,6 @@ errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs, const char *descr, ext2fs_block_bitmap *ret) { - errcode_t retval; __u32 start, end, real_end; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -148,3 +146,38 @@ errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1, bm1, bm2)); } +errcode_t ext2fs_set_inode_bitmap_range(ext2fs_inode_bitmap bmap, + ext2_ino_t start, unsigned int num, + void *in) +{ + return (ext2fs_set_generic_bitmap_range(bmap, + EXT2_ET_MAGIC_INODE_BITMAP, + start, num, in)); +} + +errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap, + ext2_ino_t start, unsigned int num, + void *out) +{ + return (ext2fs_get_generic_bitmap_range(bmap, + EXT2_ET_MAGIC_INODE_BITMAP, + start, num, out)); +} + +errcode_t ext2fs_set_block_bitmap_range(ext2fs_block_bitmap bmap, + blk_t start, unsigned int num, + void *in) +{ + return (ext2fs_set_generic_bitmap_range(bmap, + EXT2_ET_MAGIC_BLOCK_BITMAP, + start, num, in)); +} + +errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap, + blk_t start, unsigned int num, + void *out) +{ + return (ext2fs_get_generic_bitmap_range(bmap, + EXT2_ET_MAGIC_BLOCK_BITMAP, + start, num, out)); +} diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 5ce018d5..20c63c02 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -100,17 +100,6 @@ typedef __u32 ext2_dirhash_t; typedef struct struct_ext2_filsys *ext2_filsys; -struct ext2fs_struct_generic_bitmap { - errcode_t magic; - ext2_filsys fs; - __u32 start, end; - __u32 real_end; - char * description; - char * bitmap; - errcode_t base_error_code; - __u32 reserved[7]; -}; - #define EXT2FS_MARK_ERROR 0 #define EXT2FS_UNMARK_ERROR 1 #define EXT2FS_TEST_ERROR 2 @@ -553,6 +542,8 @@ extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs, /* bitmaps.c */ extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap); extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap); +extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src, + ext2fs_generic_bitmap *dest); extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs); extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs); extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs); @@ -579,6 +570,18 @@ extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1, ext2fs_block_bitmap bm2); extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1, ext2fs_inode_bitmap bm2); +extern errcode_t ext2fs_set_inode_bitmap_range(ext2fs_inode_bitmap bmap, + ext2_ino_t start, unsigned int num, + void *in); +extern errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap, + ext2_ino_t start, unsigned int num, + void *out); +extern errcode_t ext2fs_set_block_bitmap_range(ext2fs_block_bitmap bmap, + blk_t start, unsigned int num, + void *in); +extern errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap, + blk_t start, unsigned int num, + void *out); /* block.c */ @@ -782,6 +785,14 @@ extern errcode_t ext2fs_resize_generic_bitmap(errcode_t magic, extern errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq, ext2fs_generic_bitmap bm1, ext2fs_generic_bitmap bm2); +extern errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap, + errcode_t magic, + __u32 start, __u32 num, + void *out); +extern errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap, + errcode_t magic, + __u32 start, __u32 num, + void *in); /* getsize.c */ extern errcode_t ext2fs_get_device_size(const char *file, int blocksize, diff --git a/lib/ext2fs/gen_bitmap.c b/lib/ext2fs/gen_bitmap.c index 5de81984..66172e5d 100644 --- a/lib/ext2fs/gen_bitmap.c +++ b/lib/ext2fs/gen_bitmap.c @@ -27,6 +27,17 @@ #include "ext2_fs.h" #include "ext2fs.h" +struct ext2fs_struct_generic_bitmap { + errcode_t magic; + ext2_filsys fs; + __u32 start, end; + __u32 real_end; + char * description; + char * bitmap; + errcode_t base_error_code; + __u32 reserved[7]; +}; + /* * Used by previously inlined function, so we have to export this and * not change the function signature @@ -284,14 +295,44 @@ void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map) i <= map->real_end && i > map->end; i++, j++) ext2fs_set_bit(j, map->bitmap); -} +} + +errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap, + errcode_t magic, + __u32 start, __u32 num, + void *out) +{ + if (!bmap || (bmap->magic != magic)) + return magic; + + if ((start < bmap->start) || (start+num-1 > bmap->real_end)) + return EXT2_ET_INVALID_ARGUMENT; + + memcpy(out, bmap->bitmap + (start >> 3), (num+7) >> 3); + return 0; +} + +errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap, + errcode_t magic, + __u32 start, __u32 num, + void *in) +{ + if (!bmap || (bmap->magic != magic)) + return magic; + + if ((start < bmap->start) || (start+num-1 > bmap->real_end)) + return EXT2_ET_INVALID_ARGUMENT; + + memcpy(bmap->bitmap + (start >> 3), in, (num+7) >> 3); + return 0; +} int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap, blk_t block, int num) { int i; - if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { + if ((block < bitmap->start) || (block+num-1 > bitmap->real_end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, block, bitmap->description); return 0; diff --git a/lib/ext2fs/imager.c b/lib/ext2fs/imager.c index ac8309cf..9f7534ab 100644 --- a/lib/ext2fs/imager.c +++ b/lib/ext2fs/imager.c @@ -277,11 +277,12 @@ errout: */ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags) { - char *ptr; - int c, size; - char zero_buf[1024]; - ssize_t actual; - errcode_t retval; + ext2fs_generic_bitmap bmap; + errcode_t err, retval; + ssize_t actual; + __u32 itr, cnt, size; + int c, total_size; + char buf[1024]; if (flags & IMAGER_FLAG_INODEMAP) { if (!fs->inode_map) { @@ -289,7 +290,10 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags) if (retval) return retval; } - ptr = fs->inode_map->bitmap; + bmap = fs->inode_map; + err = EXT2_ET_MAGIC_INODE_BITMAP; + itr = 1; + cnt = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count; size = (EXT2_INODES_PER_GROUP(fs->super) / 8); } else { if (!fs->block_map) { @@ -297,43 +301,51 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags) if (retval) return retval; } - ptr = fs->block_map->bitmap; + bmap = fs->block_map; + err = EXT2_ET_MAGIC_BLOCK_BITMAP; + itr = fs->super->s_first_data_block; + cnt = EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count; size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; } - size = size * fs->group_desc_count; + total_size = size * fs->group_desc_count; - actual = write(fd, ptr, size); - if (actual == -1) { - retval = errno; - goto errout; + while (cnt > 0) { + size = sizeof(buf); + if (size > (cnt >> 3)) + size = (cnt >> 3); + + retval = ext2fs_get_generic_bitmap_range(bmap, + err, itr, size << 3, buf); + if (retval) + return retval; + + actual = write(fd, buf, size); + if (actual == -1) + return errno; + if (actual != (int) size) + return EXT2_ET_SHORT_READ; + + itr += size << 3; + cnt -= size << 3; } - if (actual != size) { - retval = EXT2_ET_SHORT_WRITE; - goto errout; - } - size = size % fs->blocksize; - memset(zero_buf, 0, sizeof(zero_buf)); + + size = total_size % fs->blocksize; + memset(buf, 0, sizeof(buf)); if (size) { size = fs->blocksize - size; while (size) { c = size; - if (c > (int) sizeof(zero_buf)) - c = sizeof(zero_buf); - actual = write(fd, zero_buf, c); - if (actual == -1) { - retval = errno; - goto errout; - } - if (actual != c) { - retval = EXT2_ET_SHORT_WRITE; - goto errout; - } + if (c > (int) sizeof(buf)) + c = sizeof(buf); + actual = write(fd, buf, c); + if (actual == -1) + return errno; + if (actual != c) + return EXT2_ET_SHORT_WRITE; size -= c; } } - retval = 0; -errout: - return (retval); + return 0; } @@ -342,10 +354,12 @@ errout: */ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags) { - char *ptr, *buf = 0; - int size; - ssize_t actual; - errcode_t retval; + ext2fs_generic_bitmap bmap; + errcode_t err, retval; + __u32 itr, cnt; + char buf[1024]; + unsigned int size; + ssize_t actual; if (flags & IMAGER_FLAG_INODEMAP) { if (!fs->inode_map) { @@ -353,7 +367,10 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags) if (retval) return retval; } - ptr = fs->inode_map->bitmap; + bmap = fs->inode_map; + err = EXT2_ET_MAGIC_INODE_BITMAP; + itr = 1; + cnt = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count; size = (EXT2_INODES_PER_GROUP(fs->super) / 8); } else { if (!fs->block_map) { @@ -361,29 +378,31 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags) if (retval) return retval; } - ptr = fs->block_map->bitmap; + bmap = fs->block_map; + err = EXT2_ET_MAGIC_BLOCK_BITMAP; + itr = fs->super->s_first_data_block; + cnt = EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count; size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; } - size = size * fs->group_desc_count; - buf = malloc(size); - if (!buf) - return ENOMEM; + while (cnt > 0) { + size = sizeof(buf); + if (size > (cnt >> 3)) + size = (cnt >> 3); - actual = read(fd, buf, size); - if (actual == -1) { - retval = errno; - goto errout; + actual = read(fd, buf, size); + if (actual == -1) + return errno; + if (actual != (int) size) + return EXT2_ET_SHORT_READ; + + retval = ext2fs_set_generic_bitmap_range(bmap, + err, itr, size << 3, buf); + if (retval) + return retval; + + itr += size << 3; + cnt -= size << 3; } - if (actual != size) { - retval = EXT2_ET_SHORT_WRITE; - goto errout; - } - memcpy(ptr, buf, size); - - retval = 0; -errout: - if (buf) - free(buf); - return (retval); + return 0; } diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c index cb470b8e..603b590d 100644 --- a/lib/ext2fs/rw_bitmaps.c +++ b/lib/ext2fs/rw_bitmaps.c @@ -58,10 +58,11 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) int block_nbytes, inode_nbytes; unsigned int nbits; errcode_t retval; - char *block_bitmap, *inode_bitmap; char *block_buf, *inode_buf; int lazy_flag = 0; blk_t blk; + blk_t blk_itr = fs->super->s_first_data_block; + ext2_ino_t ino_itr = 1; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -71,9 +72,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) EXT2_FEATURE_COMPAT_LAZY_BG)) lazy_flag = 1; inode_nbytes = block_nbytes = 0; - block_bitmap = inode_bitmap = 0; if (do_block) { - block_bitmap = fs->block_map->bitmap; block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; retval = ext2fs_get_mem(fs->blocksize, &block_buf); if (retval) @@ -81,7 +80,6 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) memset(block_buf, 0xff, fs->blocksize); } if (do_inode) { - inode_bitmap = fs->inode_map->bitmap; inode_nbytes = (size_t) ((EXT2_INODES_PER_GROUP(fs->super)+7) / 8); retval = ext2fs_get_mem(fs->blocksize, &inode_buf); @@ -91,14 +89,18 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) } for (i = 0; i < fs->group_desc_count; i++) { - if (!block_bitmap || !do_block) + if (!do_block) goto skip_block_bitmap; if (lazy_flag && fs->group_desc[i].bg_flags & EXT2_BG_BLOCK_UNINIT) goto skip_this_block_bitmap; - memcpy(block_buf, block_bitmap, block_nbytes); + retval = ext2fs_get_block_bitmap_range(fs->block_map, + blk_itr, block_nbytes << 3, block_buf); + if (retval) + return retval; + if (i == fs->group_desc_count - 1) { /* Force bitmap padding for the last group */ nbits = ((fs->super->s_blocks_count @@ -122,17 +124,21 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) return EXT2_ET_BLOCK_BITMAP_WRITE; } skip_this_block_bitmap: - block_bitmap += block_nbytes; + blk_itr += block_nbytes << 3; skip_block_bitmap: - if (!inode_bitmap || !do_inode) + if (!do_inode) continue; if (lazy_flag && fs->group_desc[i].bg_flags & EXT2_BG_INODE_UNINIT) goto skip_this_inode_bitmap; - memcpy(inode_buf, inode_bitmap, inode_nbytes); + retval = ext2fs_get_inode_bitmap_range(fs->inode_map, + ino_itr, inode_nbytes << 3, inode_buf); + if (retval) + return retval; + blk = fs->group_desc[i].bg_inode_bitmap; if (blk) { #ifdef EXT2_BIG_ENDIAN_BITMAPS @@ -147,7 +153,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) return EXT2_ET_INODE_BITMAP_WRITE; } skip_this_inode_bitmap: - inode_bitmap += inode_nbytes; + ino_itr += inode_nbytes << 3; } if (do_block) { @@ -167,10 +173,16 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) char *block_bitmap = 0, *inode_bitmap = 0; char *buf; errcode_t retval; - int block_nbytes = (int) EXT2_BLOCKS_PER_GROUP(fs->super) / 8; - int inode_nbytes = (int) EXT2_INODES_PER_GROUP(fs->super) / 8; + unsigned int block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; + unsigned inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8; int lazy_flag = 0; + int do_image = fs->flags & EXT2_FLAG_IMAGE_FILE; + unsigned int cnt; blk_t blk; + blk_t blk_itr = fs->super->s_first_data_block; + blk_t blk_cnt; + ext2_ino_t ino_itr = 1; + ext2_ino_t ino_cnt; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -190,8 +202,12 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map); if (retval) goto cleanup; - block_bitmap = fs->block_map->bitmap; - } + retval = ext2fs_get_mem(do_image ? fs->blocksize : + block_nbytes, &block_bitmap); + if (retval) + goto cleanup; + } else + block_nbytes = 0; if (do_inode) { if (fs->inode_map) ext2fs_free_inode_bitmap(fs->inode_map); @@ -199,30 +215,54 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map); if (retval) goto cleanup; - inode_bitmap = fs->inode_map->bitmap; - } + retval = ext2fs_get_mem(do_image ? fs->blocksize : + inode_nbytes, &inode_bitmap); + if (retval) + goto cleanup; + } else + inode_nbytes = 0; ext2fs_free_mem(&buf); if (fs->flags & EXT2_FLAG_IMAGE_FILE) { - if (inode_bitmap) { - blk = (fs->image_header->offset_inodemap / - fs->blocksize); - retval = io_channel_read_blk(fs->image_io, blk, - -(inode_nbytes * fs->group_desc_count), - inode_bitmap); + blk = (fs->image_header->offset_inodemap / fs->blocksize); + ino_cnt = fs->super->s_inodes_count; + while (inode_nbytes > 0) { + retval = io_channel_read_blk(fs->image_io, blk++, + 1, inode_bitmap); if (retval) goto cleanup; - } - if (block_bitmap) { - blk = (fs->image_header->offset_blockmap / - fs->blocksize); - retval = io_channel_read_blk(fs->image_io, blk, - -(block_nbytes * fs->group_desc_count), - block_bitmap); + cnt = fs->blocksize << 3; + if (cnt > ino_cnt) + cnt = ino_cnt; + retval = ext2fs_set_inode_bitmap_range(fs->inode_map, + ino_itr, cnt, inode_bitmap); if (retval) goto cleanup; + ino_itr += fs->blocksize << 3; + ino_cnt -= fs->blocksize << 3; + inode_nbytes -= fs->blocksize; } - return 0; + blk = (fs->image_header->offset_blockmap / + fs->blocksize); + blk_cnt = EXT2_BLOCKS_PER_GROUP(fs->super) * + fs->group_desc_count; + while (block_nbytes > 0) { + retval = io_channel_read_blk(fs->image_io, blk++, + 1, block_bitmap); + if (retval) + goto cleanup; + cnt = fs->blocksize << 3; + if (cnt > blk_cnt) + cnt = blk_cnt; + retval = ext2fs_set_block_bitmap_range(fs->block_map, + blk_itr, cnt, block_bitmap); + if (retval) + goto cleanup; + blk_itr += fs->blocksize << 3; + blk_cnt -= fs->blocksize << 3; + block_nbytes -= fs->blocksize; + } + goto success_cleanup; } for (i = 0; i < fs->group_desc_count; i++) { @@ -245,7 +285,12 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) #endif } else memset(block_bitmap, 0xff, block_nbytes); - block_bitmap += block_nbytes; + cnt = block_nbytes << 3; + retval = ext2fs_set_block_bitmap_range(fs->block_map, + blk_itr, cnt, block_bitmap); + if (retval) + goto cleanup; + blk_itr += block_nbytes << 3; } if (inode_bitmap) { blk = fs->group_desc[i].bg_inode_bitmap; @@ -266,9 +311,19 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) #endif } else memset(inode_bitmap, 0xff, inode_nbytes); - inode_bitmap += inode_nbytes; + cnt = inode_nbytes << 3; + retval = ext2fs_set_inode_bitmap_range(fs->inode_map, + ino_itr, cnt, inode_bitmap); + if (retval) + goto cleanup; + ino_itr += inode_nbytes << 3; } } +success_cleanup: + if (inode_bitmap) + ext2fs_free_mem(&inode_bitmap); + if (block_bitmap) + ext2fs_free_mem(&block_bitmap); return 0; cleanup: @@ -280,6 +335,10 @@ cleanup: ext2fs_free_mem(&fs->inode_map); fs->inode_map = 0; } + if (inode_bitmap) + ext2fs_free_mem(&inode_bitmap); + if (block_bitmap) + ext2fs_free_mem(&block_bitmap); if (buf) ext2fs_free_mem(&buf); return retval; diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index fcae0f09..b1dc607f 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -134,12 +134,18 @@ static void list_desc (ext2_filsys fs) blk_t super_blk, old_desc_blk, new_desc_blk; char *block_bitmap=NULL, *inode_bitmap=NULL; int inode_blocks_per_group, old_desc_blocks, reserved_gdt; + int block_nbytes, inode_nbytes; int has_super; + blk_t blk_itr = fs->super->s_first_data_block; + ext2_ino_t ino_itr = 1; + + block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; + inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8; if (fs->block_map) - block_bitmap = fs->block_map->bitmap; + block_bitmap = malloc(block_nbytes); if (fs->inode_map) - inode_bitmap = fs->inode_map->bitmap; + inode_bitmap = malloc(inode_nbytes); inode_blocks_per_group = ((fs->super->s_inodes_per_group * EXT2_INODE_SIZE(fs->super)) + @@ -211,18 +217,22 @@ static void list_desc (ext2_filsys fs) fs->group_desc[i].bg_used_dirs_count); if (block_bitmap) { fputs(_(" Free blocks: "), stdout); + ext2fs_get_block_bitmap_range(fs->block_map, + blk_itr, block_nbytes << 3, block_bitmap); print_free (i, block_bitmap, fs->super->s_blocks_per_group, fs->super->s_first_data_block); fputc('\n', stdout); - block_bitmap += fs->super->s_blocks_per_group / 8; + blk_itr += fs->super->s_blocks_per_group; } if (inode_bitmap) { fputs(_(" Free inodes: "), stdout); + ext2fs_get_inode_bitmap_range(fs->inode_map, + ino_itr, inode_nbytes << 3, inode_bitmap); print_free (i, inode_bitmap, fs->super->s_inodes_per_group, 1); fputc('\n', stdout); - inode_bitmap += fs->super->s_inodes_per_group / 8; + ino_itr += fs->super->s_inodes_per_group; } } }