From 8f82ef9860339039b54a324be137fbc09b762358 Mon Sep 17 00:00:00 2001 From: Valerie Aurora Henson Date: Wed, 5 Aug 2009 00:27:10 -0400 Subject: [PATCH] Convert libext2fs to 64-bit bitmap interface (Includes fixes from Nick Dokos) Signed-off-by: Valerie Aurora Henson Signed-off-by: Nick Dokos Signed-off-by: "Theodore Ts'o" --- lib/ext2fs/alloc.c | 20 ++++---- lib/ext2fs/alloc_sb.c | 9 ++-- lib/ext2fs/alloc_stats.c | 10 ++-- lib/ext2fs/alloc_tables.c | 13 ++--- lib/ext2fs/bb_inode.c | 2 +- lib/ext2fs/bitmaps.c | 119 +++++++++++++++++++++++++++++++++++++--------- lib/ext2fs/bmove.c | 8 ++-- lib/ext2fs/check_desc.c | 12 ++--- lib/ext2fs/csum.c | 4 +- lib/ext2fs/ext2_err.et.in | 3 ++ lib/ext2fs/ext2_io.h | 4 ++ lib/ext2fs/ext2fs.h | 47 ++++++++++++++++++ lib/ext2fs/icount.c | 40 ++++++++-------- lib/ext2fs/imager.c | 8 ++-- lib/ext2fs/rw_bitmaps.c | 16 +++---- lib/ext2fs/tst_iscan.c | 42 +++++++++------- 16 files changed, 241 insertions(+), 116 deletions(-) diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c index 3439445..2dbae87 100644 --- a/lib/ext2fs/alloc.c +++ b/lib/ext2fs/alloc.c @@ -30,7 +30,7 @@ * Check for uninit block bitmaps and deal with them appropriately */ static void check_block_uninit(ext2_filsys fs, ext2fs_block_bitmap map, - dgrp_t group) + dgrp_t group) { blk_t i; blk64_t blk, super_blk, old_desc_blk, new_desc_blk; @@ -64,9 +64,9 @@ static void check_block_uninit(ext2_filsys fs, ext2fs_block_bitmap map, (blk >= fs->group_desc[group].bg_inode_table && (blk < fs->group_desc[group].bg_inode_table + fs->inode_blocks_per_group))) - ext2fs_fast_mark_block_bitmap(map, blk); + ext2fs_fast_mark_block_bitmap2(map, blk); else - ext2fs_fast_unmark_block_bitmap(map, blk); + ext2fs_fast_unmark_block_bitmap2(map, blk); } fs->group_desc[group].bg_flags &= ~EXT2_BG_BLOCK_UNINIT; ext2fs_group_desc_csum_set(fs, group); @@ -87,7 +87,7 @@ static void check_inode_uninit(ext2_filsys fs, ext2fs_inode_bitmap map, ino = (group * fs->super->s_inodes_per_group) + 1; for (i=0; i < fs->super->s_inodes_per_group; i++, ino++) - ext2fs_fast_unmark_inode_bitmap(map, ino); + ext2fs_fast_unmark_inode_bitmap2(map, ino); fs->group_desc[group].bg_flags &= ~EXT2_BG_INODE_UNINIT; check_block_uninit(fs, fs->block_map, group); @@ -129,14 +129,14 @@ errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, check_inode_uninit(fs, map, (i - 1) / EXT2_INODES_PER_GROUP(fs->super)); - if (!ext2fs_fast_test_inode_bitmap(map, i)) + if (!ext2fs_fast_test_inode_bitmap2(map, i)) break; i++; if (i > fs->super->s_inodes_count) i = EXT2_FIRST_INODE(fs->super); } while (i != start_inode); - if (ext2fs_test_inode_bitmap(map, i)) + if (ext2fs_test_inode_bitmap2(map, i)) return EXT2_ET_INODE_ALLOC_FAIL; *ret = i; return 0; @@ -170,8 +170,7 @@ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal, (i - fs->super->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(fs->super)); - /* FIXME-64 */ - if (!ext2fs_fast_test_block_bitmap(map, (blk_t) i)) { + if (!ext2fs_fast_test_block_bitmap2(map, i)) { *ret = i; return 0; } @@ -218,7 +217,6 @@ errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal, goto fail; } else { if (!fs->block_map) { - /* FIXME-64 */ retval = ext2fs_read_block_bitmap(fs); if (retval) goto fail; @@ -273,9 +271,7 @@ errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish, do { if (b+num-1 > fs->super->s_blocks_count) b = fs->super->s_first_data_block; - /* FIXME-64 */ - if (ext2fs_fast_test_block_bitmap_range(map, (blk_t) b, - (blk_t) num)) { + if (ext2fs_fast_test_block_bitmap_range2(map, b, num)) { *ret = b; return 0; } diff --git a/lib/ext2fs/alloc_sb.c b/lib/ext2fs/alloc_sb.c index 42c1d94..d9080b6 100644 --- a/lib/ext2fs/alloc_sb.c +++ b/lib/ext2fs/alloc_sb.c @@ -58,21 +58,18 @@ int ext2fs_reserve_super_and_bgd(ext2_filsys fs, fs->desc_blocks + fs->super->s_reserved_gdt_blocks; if (super_blk || (group == 0)) - /* FIXME-64 */ - ext2fs_mark_block_bitmap(bmap, super_blk); + ext2fs_mark_block_bitmap2(bmap, super_blk); if (old_desc_blk) { if (fs->super->s_reserved_gdt_blocks && fs->block_map == bmap) fs->group_desc[group].bg_flags &= ~EXT2_BG_BLOCK_UNINIT; for (j=0; j < old_desc_blocks; j++) if (old_desc_blk + j < fs->super->s_blocks_count) - /* FIXME-64 */ - ext2fs_mark_block_bitmap(bmap, + ext2fs_mark_block_bitmap2(bmap, old_desc_blk + j); } if (new_desc_blk) - /* FIXME-64 */ - ext2fs_mark_block_bitmap(bmap, new_desc_blk); + ext2fs_mark_block_bitmap2(bmap, new_desc_blk); if (group == fs->group_desc_count-1) { num_blocks = (fs->super->s_blocks_count - diff --git a/lib/ext2fs/alloc_stats.c b/lib/ext2fs/alloc_stats.c index 2c99abf..5048787 100644 --- a/lib/ext2fs/alloc_stats.c +++ b/lib/ext2fs/alloc_stats.c @@ -28,9 +28,9 @@ void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino, } #endif if (inuse > 0) - ext2fs_mark_inode_bitmap(fs->inode_map, ino); + ext2fs_mark_inode_bitmap2(fs->inode_map, ino); else - ext2fs_unmark_inode_bitmap(fs->inode_map, ino); + ext2fs_unmark_inode_bitmap2(fs->inode_map, ino); fs->group_desc[group].bg_free_inodes_count -= inuse; if (isdir) fs->group_desc[group].bg_used_dirs_count += inuse; @@ -73,11 +73,9 @@ void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse) } #endif if (inuse > 0) - /* FIXME-64 */ - ext2fs_mark_block_bitmap(fs->block_map, blk); + ext2fs_mark_block_bitmap2(fs->block_map, blk); else - /* FIXME-64 */ - ext2fs_unmark_block_bitmap(fs->block_map, blk); + ext2fs_unmark_block_bitmap2(fs->block_map, blk); fs->group_desc[group].bg_free_blocks_count -= inuse; fs->group_desc[group].bg_flags &= ~EXT2_BG_BLOCK_UNINIT; ext2fs_group_desc_csum_set(fs, group); diff --git a/lib/ext2fs/alloc_tables.c b/lib/ext2fs/alloc_tables.c index 8547ad6..c7d50d0 100644 --- a/lib/ext2fs/alloc_tables.c +++ b/lib/ext2fs/alloc_tables.c @@ -33,7 +33,7 @@ * block number with a correct offset were the bitmaps and inode * tables can be allocated continously and in order. */ -static blk_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk_t start_blk, +static blk_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk, ext2fs_block_bitmap bmap, int offset, int size, int elem_size) { @@ -55,7 +55,7 @@ static blk_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk_t start_blk, * search is still valid. */ if (start_blk && group % flexbg_size) { - if (ext2fs_test_block_bitmap_range(bmap, start_blk + elem_size, + if (ext2fs_test_block_bitmap_range2(bmap, start_blk + elem_size, size)) return start_blk + elem_size; } @@ -119,7 +119,8 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, start_blk = group_blk; if (flexbg_size) { - blk_t prev_block = 0; + blk64_t prev_block = 0; + if (group && fs->group_desc[group-1].bg_block_bitmap) prev_block = fs->group_desc[group-1].bg_block_bitmap; start_blk = flexbg_offset(fs, group, prev_block, bmap, @@ -135,7 +136,7 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, last_blk, 1, bmap, &new_blk); if (retval) return retval; - ext2fs_mark_block_bitmap(bmap, new_blk); + ext2fs_mark_block_bitmap2(bmap, new_blk); fs->group_desc[group].bg_block_bitmap = new_blk; if (flexbg_size) { dgrp_t gr = ext2fs_group_of_blk(fs, new_blk); @@ -163,7 +164,7 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, last_blk, 1, bmap, &new_blk); if (retval) return retval; - ext2fs_mark_block_bitmap(bmap, new_blk); + ext2fs_mark_block_bitmap2(bmap, new_blk); fs->group_desc[group].bg_inode_bitmap = new_blk; if (flexbg_size) { dgrp_t gr = ext2fs_group_of_blk(fs, new_blk); @@ -198,7 +199,7 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, for (j=0, blk = new_blk; j < fs->inode_blocks_per_group; j++, blk++) { - ext2fs_mark_block_bitmap(bmap, blk); + ext2fs_mark_block_bitmap2(bmap, blk); if (flexbg_size) { dgrp_t gr = ext2fs_group_of_blk(fs, blk); fs->group_desc[gr].bg_free_blocks_count--; diff --git a/lib/ext2fs/bb_inode.c b/lib/ext2fs/bb_inode.c index cbeeb98..53122b5 100644 --- a/lib/ext2fs/bb_inode.c +++ b/lib/ext2fs/bb_inode.c @@ -235,7 +235,7 @@ static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr, retry: if (rec->ind_blocks_ptr < rec->ind_blocks_size) { blk = rec->ind_blocks[rec->ind_blocks_ptr++]; - if (ext2fs_test_block_bitmap(fs->block_map, blk)) + if (ext2fs_test_block_bitmap2(fs->block_map, blk)) goto retry; } else { retval = ext2fs_new_block(fs, 0, 0, &blk); diff --git a/lib/ext2fs/bitmaps.c b/lib/ext2fs/bitmaps.c index ea08b3e..8dc8465 100644 --- a/lib/ext2fs/bitmaps.c +++ b/lib/ext2fs/bitmaps.c @@ -26,33 +26,33 @@ #include "ext2_fs.h" #include "ext2fs.h" +#include "ext2fsP.h" void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap) { - ext2fs_free_generic_bitmap(bitmap); + ext2fs_free_generic_bmap(bitmap); } void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap) { - ext2fs_free_generic_bitmap(bitmap); + ext2fs_free_generic_bmap(bitmap); } errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src, ext2fs_generic_bitmap *dest) { - return (ext2fs_copy_generic_bitmap(src, dest)); + return (ext2fs_copy_generic_bmap(src, dest)); } - void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map) { - ext2fs_set_generic_bitmap_padding(map); + ext2fs_set_generic_bmap_padding(map); } errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs, const char *descr, ext2fs_inode_bitmap *ret) { - __u32 start, end, real_end; + __u64 start, end, real_end; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -62,39 +62,66 @@ errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs, end = fs->super->s_inodes_count; real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count); + /* Are we permitted to use new-style bitmaps? */ + if (fs->flags & EXT2_FLAG_64BITS) + return (ext2fs_alloc_generic_bmap(fs, + EXT2_ET_MAGIC_INODE_BITMAP64, + EXT2FS_BMAP64_BITARRAY, + start, end, real_end, descr, ret)); + + /* Otherwise, check to see if the file system is small enough + * to use old-style 32-bit bitmaps */ + if ((end > ~0U) || (real_end > ~0U)) + return EXT2_ET_CANT_USE_LEGACY_BITMAPS; + return (ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_INODE_BITMAP, fs, - start, end, real_end, - descr, 0, ret)); + start, end, real_end, + descr, 0, + (ext2fs_generic_bitmap *) ret)); } errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs, const char *descr, ext2fs_block_bitmap *ret) { - __u32 start, end, real_end; + __u64 start, end, real_end; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); fs->write_bitmaps = ext2fs_write_bitmaps; start = fs->super->s_first_data_block; - end = fs->super->s_blocks_count-1; + end = ext2fs_blocks_count(fs->super)-1; real_end = (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count)-1 + start; + if (fs->flags & EXT2_FLAG_64BITS) + return (ext2fs_alloc_generic_bmap(fs, + EXT2_ET_MAGIC_BLOCK_BITMAP64, + EXT2FS_BMAP64_BITARRAY, + start, end, real_end, descr, ret)); + + if ((end > ~0U) || (real_end > ~0U)) + return EXT2_ET_CANT_USE_LEGACY_BITMAPS; + return (ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, fs, start, end, real_end, - descr, 0, ret)); + descr, 0, + (ext2fs_generic_bitmap *) ret)); } errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap, ext2_ino_t end, ext2_ino_t *oend) { + __u64 tmp_oend; + int retval; - return (ext2fs_fudge_generic_bitmap_end(bitmap, - EXT2_ET_MAGIC_INODE_BITMAP, - EXT2_ET_FUDGE_INODE_BITMAP_END, - end, oend)); + retval = ext2fs_fudge_generic_bmap_end((ext2fs_generic_bitmap) bitmap, + EXT2_ET_FUDGE_INODE_BITMAP_END, + end, &tmp_oend); + if (oend) + *oend = tmp_oend; + return retval; } errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap, @@ -106,14 +133,22 @@ errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap, end, oend)); } +errcode_t ext2fs_fudge_block_bitmap_end2(ext2fs_block_bitmap bitmap, + blk64_t end, blk64_t *oend) +{ + return (ext2fs_fudge_generic_bmap_end(bitmap, + EXT2_ET_FUDGE_BLOCK_BITMAP_END, + end, oend)); +} + void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap) { - ext2fs_clear_generic_bitmap(bitmap); + ext2fs_clear_generic_bmap(bitmap); } void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap) { - ext2fs_clear_generic_bitmap(bitmap); + ext2fs_clear_generic_bmap(bitmap); } errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end, @@ -123,6 +158,12 @@ errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end, new_end, new_real_end, bmap)); } +errcode_t ext2fs_resize_inode_bitmap2(__u64 new_end, __u64 new_real_end, + ext2fs_inode_bitmap bmap) +{ + return (ext2fs_resize_generic_bmap(bmap, new_end, new_real_end)); +} + errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end, ext2fs_block_bitmap bmap) { @@ -130,20 +171,24 @@ errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end, new_end, new_real_end, bmap)); } +errcode_t ext2fs_resize_block_bitmap2(__u64 new_end, __u64 new_real_end, + ext2fs_block_bitmap bmap) +{ + return (ext2fs_resize_generic_bmap(bmap, new_end, new_real_end)); +} + errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1, ext2fs_block_bitmap bm2) { - return (ext2fs_compare_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, - EXT2_ET_NEQ_BLOCK_BITMAP, - bm1, bm2)); + return (ext2fs_compare_generic_bmap(EXT2_ET_NEQ_BLOCK_BITMAP, + bm1, bm2)); } errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1, ext2fs_inode_bitmap bm2) { - return (ext2fs_compare_generic_bitmap(EXT2_ET_MAGIC_INODE_BITMAP, - EXT2_ET_NEQ_INODE_BITMAP, - bm1, bm2)); + return (ext2fs_compare_generic_bmap(EXT2_ET_NEQ_INODE_BITMAP, + bm1, bm2)); } errcode_t ext2fs_set_inode_bitmap_range(ext2fs_inode_bitmap bmap, @@ -155,6 +200,13 @@ errcode_t ext2fs_set_inode_bitmap_range(ext2fs_inode_bitmap bmap, start, num, in)); } +errcode_t ext2fs_set_inode_bitmap_range2(ext2fs_inode_bitmap bmap, + __u64 start, size_t num, + void *in) +{ + return (ext2fs_set_generic_bmap_range(bmap, start, num, in)); +} + errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap, ext2_ino_t start, unsigned int num, void *out) @@ -164,6 +216,13 @@ errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap, start, num, out)); } +errcode_t ext2fs_get_inode_bitmap_range2(ext2fs_inode_bitmap bmap, + __u64 start, size_t num, + void *out) +{ + return (ext2fs_get_generic_bmap_range(bmap, start, num, out)); +} + errcode_t ext2fs_set_block_bitmap_range(ext2fs_block_bitmap bmap, blk_t start, unsigned int num, void *in) @@ -173,6 +232,13 @@ errcode_t ext2fs_set_block_bitmap_range(ext2fs_block_bitmap bmap, start, num, in)); } +errcode_t ext2fs_set_block_bitmap_range2(ext2fs_block_bitmap bmap, + blk64_t start, size_t num, + void *in) +{ + return (ext2fs_set_generic_bmap_range(bmap, start, num, in)); +} + errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap, blk_t start, unsigned int num, void *out) @@ -181,3 +247,10 @@ errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap, EXT2_ET_MAGIC_BLOCK_BITMAP, start, num, out)); } + +errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap, + blk64_t start, size_t num, + void *out) +{ + return (ext2fs_get_generic_bmap_range(bmap, start, num, out)); +} diff --git a/lib/ext2fs/bmove.c b/lib/ext2fs/bmove.c index 019db91..e56411c 100644 --- a/lib/ext2fs/bmove.c +++ b/lib/ext2fs/bmove.c @@ -48,7 +48,7 @@ static int process_block(ext2_filsys fs, blk_t *block_nr, /* * Let's see if this is one which we need to relocate */ - if (ext2fs_test_block_bitmap(pb->reserve, block)) { + if (ext2fs_test_block_bitmap2(pb->reserve, block)) { do { if (++block >= fs->super->s_blocks_count) block = fs->super->s_first_data_block; @@ -56,8 +56,8 @@ static int process_block(ext2_filsys fs, blk_t *block_nr, pb->error = EXT2_ET_BLOCK_ALLOC_FAIL; return BLOCK_ABORT; } - } while (ext2fs_test_block_bitmap(pb->reserve, block) || - ext2fs_test_block_bitmap(pb->alloc_map, block)); + } while (ext2fs_test_block_bitmap2(pb->reserve, block) || + ext2fs_test_block_bitmap2(pb->alloc_map, block)); retval = io_channel_read_blk(fs->io, orig, 1, pb->buf); if (retval) { @@ -70,7 +70,7 @@ static int process_block(ext2_filsys fs, blk_t *block_nr, return BLOCK_ABORT; } *block_nr = block; - ext2fs_mark_block_bitmap(pb->alloc_map, block); + ext2fs_mark_block_bitmap2(pb->alloc_map, block); ret = BLOCK_CHANGED; if (pb->flags & EXT2_BMOVE_DEBUG) printf("ino=%ld, blockcnt=%lld, %u->%u\n", pb->ino, diff --git a/lib/ext2fs/check_desc.c b/lib/ext2fs/check_desc.c index 299cb01..99b1ae4 100644 --- a/lib/ext2fs/check_desc.c +++ b/lib/ext2fs/check_desc.c @@ -62,22 +62,22 @@ errcode_t ext2fs_check_desc(ext2_filsys fs) */ blk = fs->group_desc[i].bg_block_bitmap; if (blk < first_block || blk > last_block || - ext2fs_test_block_bitmap(bmap, blk)) { + ext2fs_test_block_bitmap2(bmap, blk)) { retval = EXT2_ET_GDESC_BAD_BLOCK_MAP; goto errout; } - ext2fs_mark_block_bitmap(bmap, blk); + ext2fs_mark_block_bitmap2(bmap, blk); /* * Check to make sure the inode bitmap for group is sane */ blk = fs->group_desc[i].bg_inode_bitmap; if (blk < first_block || blk > last_block || - ext2fs_test_block_bitmap(bmap, blk)) { + ext2fs_test_block_bitmap2(bmap, blk)) { retval = EXT2_ET_GDESC_BAD_INODE_MAP; goto errout; } - ext2fs_mark_block_bitmap(bmap, blk); + ext2fs_mark_block_bitmap2(bmap, blk); /* * Check to make sure the inode table for group is sane @@ -90,11 +90,11 @@ errcode_t ext2fs_check_desc(ext2_filsys fs) } for (j = 0, b = blk; j < fs->inode_blocks_per_group; j++, b++) { - if (ext2fs_test_block_bitmap(bmap, b)) { + if (ext2fs_test_block_bitmap2(bmap, b)) { retval = EXT2_ET_GDESC_BAD_INODE_TABLE; goto errout; } - ext2fs_mark_block_bitmap(bmap, b); + ext2fs_mark_block_bitmap2(bmap, b); } } errout: diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c index da0aeda..39a99e4 100644 --- a/lib/ext2fs/csum.c +++ b/lib/ext2fs/csum.c @@ -92,7 +92,7 @@ static __u32 find_last_inode_ingrp(ext2fs_inode_bitmap bitmap, end_ino = start_ino + inodes_per_grp - 1; for (i = end_ino; i >= start_ino; i--) { - if (ext2fs_fast_test_inode_bitmap(bitmap, i)) + if (ext2fs_fast_test_inode_bitmap2(bitmap, i)) return i - start_ino + 1; } return inodes_per_grp; @@ -185,7 +185,7 @@ int main(int argc, char **argv) memset(¶m, 0, sizeof(param)); param.s_blocks_count = 32768; - retval = ext2fs_initialize("test fs", 0, ¶m, + retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m, test_io_manager, &fs); if (retval) { com_err("setup", retval, diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in index c73527f..995ddc3 100644 --- a/lib/ext2fs/ext2_err.et.in +++ b/lib/ext2fs/ext2_err.et.in @@ -419,4 +419,7 @@ ec EXT2_ET_IO_CHANNEL_NO_SUPPORT_64, ec EXT2_NO_MTAB_FILE, "Can't check if filesystem is mounted due to missing mtab file" +ec EXT2_ET_CANT_USE_LEGACY_BITMAPS, + "Filesystem too large to use legacy bitmaps" + end diff --git a/lib/ext2fs/ext2_io.h b/lib/ext2fs/ext2_io.h index 2a579e6..a39bd17 100644 --- a/lib/ext2fs/ext2_io.h +++ b/lib/ext2fs/ext2_io.h @@ -126,6 +126,10 @@ extern void (*test_io_cb_read_blk) (unsigned long block, int count, errcode_t err); extern void (*test_io_cb_write_blk) (unsigned long block, int count, errcode_t err); +extern void (*test_io_cb_read_blk64) + (unsigned long long block, int count, errcode_t err); +extern void (*test_io_cb_write_blk64) + (unsigned long long block, int count, errcode_t err); extern void (*test_io_cb_set_blksize) (int blksize, errcode_t err); diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index b6649ba..5c3d17f 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -667,14 +667,22 @@ extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap, ext2_ino_t end, ext2_ino_t *oend); extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap, blk_t end, blk_t *oend); +extern errcode_t ext2fs_fudge_block_bitmap_end2(ext2fs_block_bitmap bitmap, + blk64_t end, blk64_t *oend); extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap); extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap); extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs); extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs); extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end, ext2fs_inode_bitmap bmap); +extern errcode_t ext2fs_resize_inode_bitmap2(__u64 new_end, + __u64 new_real_end, + ext2fs_inode_bitmap bmap); extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end, ext2fs_block_bitmap bmap); +extern errcode_t ext2fs_resize_block_bitmap2(__u64 new_end, + __u64 new_real_end, + ext2fs_block_bitmap bmap); 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, @@ -682,15 +690,27 @@ extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1, 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_set_inode_bitmap_range2(ext2fs_inode_bitmap bmap, + __u64 start, size_t 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_get_inode_bitmap_range2(ext2fs_inode_bitmap bmap, + __u64 start, size_t 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_set_block_bitmap_range2(ext2fs_block_bitmap bmap, + blk64_t start, size_t num, + void *in); extern errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap, blk_t start, unsigned int num, void *out); +extern errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap, + blk64_t start, size_t num, + void *out); /* blknum.c */ extern dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t); @@ -1032,6 +1052,33 @@ extern errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap, __u32 start, __u32 num, void *in); +/* gen_bitmap64.c */ +void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap); +errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic, + int type, __u64 start, __u64 end, + __u64 real_end, + const char *descr, + ext2fs_generic_bitmap *ret); +errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src, + ext2fs_generic_bitmap *dest); +void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap); +errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap, + errcode_t neq, + __u64 end, __u64 *oend); +void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap); +errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap, + __u64 new_end, + __u64 new_real_end); +errcode_t ext2fs_compare_generic_bmap(errcode_t neq, + ext2fs_generic_bitmap bm1, + ext2fs_generic_bitmap bm2); +errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap, + __u64 start, unsigned int num, + void *out); +errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap, + __u64 start, unsigned int num, + void *in); + /* getsize.c */ extern errcode_t ext2fs_get_device_size(const char *file, int blocksize, blk_t *retblocks); diff --git a/lib/ext2fs/icount.c b/lib/ext2fs/icount.c index bec0f5f..5203930 100644 --- a/lib/ext2fs/icount.c +++ b/lib/ext2fs/icount.c @@ -498,12 +498,12 @@ errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino, __u16 *ret) if (!ino || (ino > icount->num_inodes)) return EXT2_ET_INVALID_ARGUMENT; - if (ext2fs_test_inode_bitmap(icount->single, ino)) { + if (ext2fs_test_inode_bitmap2(icount->single, ino)) { *ret = 1; return 0; } if (icount->multiple && - !ext2fs_test_inode_bitmap(icount->multiple, ino)) { + !ext2fs_test_inode_bitmap2(icount->multiple, ino)) { *ret = 0; return 0; } @@ -522,7 +522,7 @@ errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino, if (!ino || (ino > icount->num_inodes)) return EXT2_ET_INVALID_ARGUMENT; - if (ext2fs_test_inode_bitmap(icount->single, ino)) { + if (ext2fs_test_inode_bitmap2(icount->single, ino)) { /* * If the existing count is 1, then we know there is * no entry in the list. @@ -530,14 +530,14 @@ errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino, if (set_inode_count(icount, ino, 2)) return EXT2_ET_NO_MEMORY; curr_value = 2; - ext2fs_unmark_inode_bitmap(icount->single, ino); + ext2fs_unmark_inode_bitmap2(icount->single, ino); } else if (icount->multiple) { /* * The count is either zero or greater than 1; if the * inode is set in icount->multiple, then there should * be an entry in the list, so we need to fix it. */ - if (ext2fs_test_inode_bitmap(icount->multiple, ino)) { + if (ext2fs_test_inode_bitmap2(icount->multiple, ino)) { get_inode_count(icount, ino, &curr_value); curr_value++; if (set_inode_count(icount, ino, curr_value)) @@ -547,7 +547,7 @@ errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino, * The count was zero; mark the single bitmap * and return. */ - ext2fs_mark_inode_bitmap(icount->single, ino); + ext2fs_mark_inode_bitmap2(icount->single, ino); if (ret) *ret = 1; return 0; @@ -563,7 +563,7 @@ errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino, return EXT2_ET_NO_MEMORY; } if (icount->multiple) - ext2fs_mark_inode_bitmap(icount->multiple, ino); + ext2fs_mark_inode_bitmap2(icount->multiple, ino); if (ret) *ret = icount_16_xlate(curr_value); return 0; @@ -579,10 +579,10 @@ errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino, EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT); - if (ext2fs_test_inode_bitmap(icount->single, ino)) { - ext2fs_unmark_inode_bitmap(icount->single, ino); + if (ext2fs_test_inode_bitmap2(icount->single, ino)) { + ext2fs_unmark_inode_bitmap2(icount->single, ino); if (icount->multiple) - ext2fs_unmark_inode_bitmap(icount->multiple, ino); + ext2fs_unmark_inode_bitmap2(icount->multiple, ino); else { set_inode_count(icount, ino, 0); } @@ -592,7 +592,7 @@ errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino, } if (icount->multiple && - !ext2fs_test_inode_bitmap(icount->multiple, ino)) + !ext2fs_test_inode_bitmap2(icount->multiple, ino)) return EXT2_ET_INVALID_ARGUMENT; get_inode_count(icount, ino, &curr_value); @@ -603,9 +603,9 @@ errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino, return EXT2_ET_NO_MEMORY; if (curr_value == 1) - ext2fs_mark_inode_bitmap(icount->single, ino); + ext2fs_mark_inode_bitmap2(icount->single, ino); if ((curr_value == 0) && icount->multiple) - ext2fs_unmark_inode_bitmap(icount->multiple, ino); + ext2fs_unmark_inode_bitmap2(icount->multiple, ino); if (ret) *ret = icount_16_xlate(curr_value); @@ -621,19 +621,19 @@ errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino, EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT); if (count == 1) { - ext2fs_mark_inode_bitmap(icount->single, ino); + ext2fs_mark_inode_bitmap2(icount->single, ino); if (icount->multiple) - ext2fs_unmark_inode_bitmap(icount->multiple, ino); + ext2fs_unmark_inode_bitmap2(icount->multiple, ino); return 0; } if (count == 0) { - ext2fs_unmark_inode_bitmap(icount->single, ino); + ext2fs_unmark_inode_bitmap2(icount->single, ino); if (icount->multiple) { /* * If the icount->multiple bitmap is enabled, * we can just clear both bitmaps and we're done */ - ext2fs_unmark_inode_bitmap(icount->multiple, ino); + ext2fs_unmark_inode_bitmap2(icount->multiple, ino); } else set_inode_count(icount, ino, 0); return 0; @@ -641,9 +641,9 @@ errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino, if (set_inode_count(icount, ino, count)) return EXT2_ET_NO_MEMORY; - ext2fs_unmark_inode_bitmap(icount->single, ino); + ext2fs_unmark_inode_bitmap2(icount->single, ino); if (icount->multiple) - ext2fs_mark_inode_bitmap(icount->multiple, ino); + ext2fs_mark_inode_bitmap2(icount->multiple, ino); return 0; } @@ -746,7 +746,7 @@ static void setup(void) memset(¶m, 0, sizeof(param)); param.s_blocks_count = 12000; - retval = ext2fs_initialize("test fs", 0, ¶m, + retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m, test_io_manager, &test_fs); if (retval) { com_err("setup", retval, diff --git a/lib/ext2fs/imager.c b/lib/ext2fs/imager.c index 0154333..c0c10f0 100644 --- a/lib/ext2fs/imager.c +++ b/lib/ext2fs/imager.c @@ -314,8 +314,8 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags) if (size > (cnt >> 3)) size = (cnt >> 3); - retval = ext2fs_get_generic_bitmap_range(bmap, - err, itr, size << 3, buf); + retval = ext2fs_get_generic_bmap_range(bmap, itr, + size << 3, buf); if (retval) return retval; @@ -396,8 +396,8 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags) if (actual != (int) size) return EXT2_ET_SHORT_READ; - retval = ext2fs_set_generic_bitmap_range(bmap, - err, itr, size << 3, buf); + retval = ext2fs_set_generic_bmap_range(bmap, itr, + size << 3, buf); if (retval) return retval; diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c index 56fcfd6..05f8fed 100644 --- a/lib/ext2fs/rw_bitmaps.c +++ b/lib/ext2fs/rw_bitmaps.c @@ -37,7 +37,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) char *block_buf, *inode_buf; int csum_flag = 0; blk_t blk; - blk_t blk_itr = fs->super->s_first_data_block; + blk64_t blk_itr = fs->super->s_first_data_block; ext2_ino_t ino_itr = 1; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -74,7 +74,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) EXT2_BG_BLOCK_UNINIT) goto skip_this_block_bitmap; - retval = ext2fs_get_block_bitmap_range(fs->block_map, + retval = ext2fs_get_block_bitmap_range2(fs->block_map, blk_itr, block_nbytes << 3, block_buf); if (retval) return retval; @@ -106,7 +106,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) EXT2_BG_INODE_UNINIT) goto skip_this_inode_bitmap; - retval = ext2fs_get_inode_bitmap_range(fs->inode_map, + retval = ext2fs_get_inode_bitmap_range2(fs->inode_map, ino_itr, inode_nbytes << 3, inode_buf); if (retval) return retval; @@ -145,7 +145,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) 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; + blk64_t blk_itr = fs->super->s_first_data_block; blk_t blk_cnt; ext2_ino_t ino_itr = 1; ext2_ino_t ino_cnt; @@ -202,7 +202,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) cnt = fs->blocksize << 3; if (cnt > ino_cnt) cnt = ino_cnt; - retval = ext2fs_set_inode_bitmap_range(fs->inode_map, + retval = ext2fs_set_inode_bitmap_range2(fs->inode_map, ino_itr, cnt, inode_bitmap); if (retval) goto cleanup; @@ -222,7 +222,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) cnt = fs->blocksize << 3; if (cnt > blk_cnt) cnt = blk_cnt; - retval = ext2fs_set_block_bitmap_range(fs->block_map, + retval = ext2fs_set_block_bitmap_range2(fs->block_map, blk_itr, cnt, block_bitmap); if (retval) goto cleanup; @@ -250,7 +250,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) } else memset(block_bitmap, 0, block_nbytes); cnt = block_nbytes << 3; - retval = ext2fs_set_block_bitmap_range(fs->block_map, + retval = ext2fs_set_block_bitmap_range2(fs->block_map, blk_itr, cnt, block_bitmap); if (retval) goto cleanup; @@ -272,7 +272,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) } else memset(inode_bitmap, 0, inode_nbytes); cnt = inode_nbytes << 3; - retval = ext2fs_set_inode_bitmap_range(fs->inode_map, + retval = ext2fs_set_inode_bitmap_range2(fs->inode_map, ino_itr, cnt, inode_bitmap); if (retval) goto cleanup; diff --git a/lib/ext2fs/tst_iscan.c b/lib/ext2fs/tst_iscan.c index b0c7fc3..6c3abb3 100644 --- a/lib/ext2fs/tst_iscan.c +++ b/lib/ext2fs/tst_iscan.c @@ -35,7 +35,7 @@ badblocks_list test_badblocks; int first_no_comma = 1; int failed = 0; -static void test_read_blk(unsigned long block, int count, errcode_t err) +static void iscan_test_read_blk64(unsigned long long block, int count, errcode_t err) { int i; @@ -45,20 +45,25 @@ static void test_read_blk(unsigned long block, int count, errcode_t err) printf(", "); if (count > 1) - printf("%lu-%lu", block, block+count-1); + printf("%llu-%llu", block, block+count-1); else - printf("%lu", block); + printf("%llu", block); for (i=0; i < count; i++, block++) { - if (ext2fs_test_block_bitmap(touched_map, block)) { - printf("\nDuplicate block?!? --- %lu\n", block); + if (ext2fs_test_block_bitmap2(touched_map, block)) { + printf("\nDuplicate block?!? --- %llu\n", block); failed++; first_no_comma = 1; } - ext2fs_mark_block_bitmap(touched_map, block); + ext2fs_mark_block_bitmap2(touched_map, block); } } +static void iscan_test_read_blk(unsigned long block, int count, errcode_t err) +{ + iscan_test_read_blk64(block, count, err); +} + /* * Setup the variables for doing the inode scan test. */ @@ -71,12 +76,13 @@ static void setup(void) initialize_ext2_error_table(); memset(¶m, 0, sizeof(param)); - param.s_blocks_count = 12000; + ext2fs_blocks_count_set(¶m, 12000); - test_io_cb_read_blk = test_read_blk; + test_io_cb_read_blk = iscan_test_read_blk; + test_io_cb_read_blk64 = iscan_test_read_blk64; - retval = ext2fs_initialize("test fs", 0, ¶m, + retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m, test_io_manager, &test_fs); if (retval) { com_err("setup", retval, @@ -123,7 +129,7 @@ static void setup(void) "while adding test vector %d", i); exit(1); } - ext2fs_mark_block_bitmap(bad_block_map, test_vec[i]); + ext2fs_mark_block_bitmap2(bad_block_map, test_vec[i]); } test_fs->badblocks = test_badblocks; } @@ -152,7 +158,7 @@ static void iterate(void) while (ino) { retval = ext2fs_get_next_inode(scan, &ino, &inode); if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) { - ext2fs_mark_inode_bitmap(bad_inode_map, ino); + ext2fs_mark_inode_bitmap2(bad_inode_map, ino); continue; } if (retval) { @@ -171,30 +177,30 @@ static void iterate(void) static void check_map(void) { int i, j, first=1; - unsigned long blk; + blk64_t blk; for (i=0; test_vec[i]; i++) { - if (ext2fs_test_block_bitmap(touched_map, test_vec[i])) { + if (ext2fs_test_block_bitmap2(touched_map, test_vec[i])) { printf("Bad block was touched --- %u\n", test_vec[i]); failed++; first_no_comma = 1; } - ext2fs_mark_block_bitmap(touched_map, test_vec[i]); + ext2fs_mark_block_bitmap2(touched_map, test_vec[i]); } for (i = 0; i < test_fs->group_desc_count; i++) { for (j=0, blk = test_fs->group_desc[i].bg_inode_table; j < test_fs->inode_blocks_per_group; j++, blk++) { - if (!ext2fs_test_block_bitmap(touched_map, blk) && - !ext2fs_test_block_bitmap(bad_block_map, blk)) { - printf("Missing block --- %lu\n", blk); + if (!ext2fs_test_block_bitmap2(touched_map, blk) && + !ext2fs_test_block_bitmap2(bad_block_map, blk)) { + printf("Missing block --- %llu\n", blk); failed++; } } } printf("Bad inodes: "); for (i=1; i <= test_fs->super->s_inodes_count; i++) { - if (ext2fs_test_inode_bitmap(bad_inode_map, i)) { + if (ext2fs_test_inode_bitmap2(bad_inode_map, i)) { if (first) first = 0; else -- 1.8.3.1