diff options
author | Theodore Ts'o <tytso@mit.edu> | 2002-10-30 23:07:21 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2002-10-30 23:07:21 -0500 |
commit | 76dd5e5c2842fb1a7b858aad3e68b5e9c16890c9 (patch) | |
tree | ac821fe02a3bb0ff42ed8a8fbb4bc24f6fbeceee /resize | |
parent | 1d4c7945ff3213bd928b8722a7f057535836db24 (diff) | |
download | e2fsprogs-76dd5e5c2842fb1a7b858aad3e68b5e9c16890c9.tar.gz |
Add support for the meta_bg feature flag to the resize2fs program.
Fix bug in meta_bg support in mke2fs, e2fsck, and dumpe2fs; we were
incorrectly reserving the legacy block groups desriptor blocks.
Diffstat (limited to 'resize')
-rw-r--r-- | resize/ChangeLog | 10 | ||||
-rw-r--r-- | resize/main.c | 3 | ||||
-rw-r--r-- | resize/resize2fs.c | 173 |
3 files changed, 138 insertions, 48 deletions
diff --git a/resize/ChangeLog b/resize/ChangeLog index 5c6f663b..54f0ae9c 100644 --- a/resize/ChangeLog +++ b/resize/ChangeLog @@ -1,3 +1,13 @@ +2002-10-30 Theodore Ts'o <tytso@mit.edu> + + * resize2fs.c (adjust_superblock, mark_table_blocks, + blocks_to_move): Add support for resizing filesystems that + use the meta block group layout. + + * main.c (main): Fixed bug that erroneously (and + needlessly) checked the incompat feature flag field + against the supported ro_compat feature set. + 2002-10-03 Theodore Ts'o <tytso@mit.edu> * resize2fs.8.in: Fix typo in man page. diff --git a/resize/main.c b/resize/main.c index 7808b1d4..841f4bd2 100644 --- a/resize/main.c +++ b/resize/main.c @@ -204,8 +204,7 @@ int main (int argc, char ** argv) * Check for compatibility with the feature sets. We need to * be more stringent than ext2fs_open(). */ - if ((fs->super->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) || - (fs->super->s_feature_incompat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)) { + if (fs->super->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) { com_err(program_name, EXT2_ET_UNSUPP_FEATURE, "(%s)", device_name); exit(1); diff --git a/resize/resize2fs.c b/resize/resize2fs.c index 4dd2b33f..cc2fda49 100644 --- a/resize/resize2fs.c +++ b/resize/resize2fs.c @@ -179,6 +179,7 @@ static errcode_t adjust_superblock(ext2_resize_t rfs, blk_t new_size) blk_t blk, group_block; unsigned long i, j; int old_numblocks, numblocks, adjblocks; + int has_super, meta_bg, meta_bg_size, old_desc_blocks; unsigned long max_group; fs = rfs->new_fs; @@ -341,6 +342,10 @@ retry: if (retval) goto errout; } + if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) + old_desc_blocks = fs->super->s_first_meta_bg; + else + old_desc_blocks = fs->desc_blocks; for (i = rfs->old_fs->group_desc_count; i < fs->group_desc_count; i++) { memset(&fs->group_desc[i], 0, @@ -356,12 +361,33 @@ retry: } else numblocks = fs->super->s_blocks_per_group; - if (ext2fs_bg_has_super(fs, i)) { - for (j=0; j < fs->desc_blocks+1; j++) + has_super = ext2fs_bg_has_super(fs, i); + if (has_super) { + ext2fs_mark_block_bitmap(fs->block_map, group_block); + adjblocks++; + } + meta_bg_size = (fs->blocksize / + sizeof (struct ext2_group_desc)); + meta_bg = i / meta_bg_size; + if (!(fs->super->s_feature_incompat & + EXT2_FEATURE_INCOMPAT_META_BG) || + (meta_bg < fs->super->s_first_meta_bg)) { + if (has_super) { + for (j=0; j < old_desc_blocks; j++) + ext2fs_mark_block_bitmap(fs->block_map, + group_block + 1 + j); + adjblocks += old_desc_blocks; + } + } else { + if (has_super) + has_super = 1; + if (((i % meta_bg_size) == 0) || + ((i % meta_bg_size) == 1) || + ((i % meta_bg_size) == (meta_bg_size-1))) ext2fs_mark_block_bitmap(fs->block_map, - group_block + j); - adjblocks = 1 + fs->desc_blocks; + group_block + has_super); } + adjblocks += 2 + fs->inode_blocks_per_group; numblocks -= adjblocks; @@ -421,7 +447,8 @@ static errcode_t mark_table_blocks(ext2_filsys fs, ext2fs_block_bitmap *ret_bmap) { blk_t block, b; - int i,j; + int i,j, has_super, meta_bg, meta_bg_size; + int old_desc_blocks; ext2fs_block_bitmap bmap; errcode_t retval; @@ -430,21 +457,43 @@ static errcode_t mark_table_blocks(ext2_filsys fs, if (retval) return retval; + meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc)); block = fs->super->s_first_data_block; + if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) + old_desc_blocks = fs->super->s_first_meta_bg; + else + old_desc_blocks = fs->desc_blocks; for (i = 0; i < fs->group_desc_count; i++) { - if (ext2fs_bg_has_super(fs, i)) { + has_super = ext2fs_bg_has_super(fs, i); + if (has_super) /* * Mark this group's copy of the superblock */ ext2fs_mark_block_bitmap(bmap, block); - /* - * Mark this group's copy of the descriptors - */ - for (j = 0; j < fs->desc_blocks; j++) - ext2fs_mark_block_bitmap(bmap, block + j + 1); - } + meta_bg = i / meta_bg_size; + if (!(fs->super->s_feature_incompat & + EXT2_FEATURE_INCOMPAT_META_BG) || + (meta_bg < fs->super->s_first_meta_bg)) { + if (has_super) { + /* + * Mark this group's copy of the descriptors + */ + for (j = 0; j < old_desc_blocks; j++) + ext2fs_mark_block_bitmap(bmap, + block + j + 1); + } + } else { + if (has_super) + has_super = 1; + if (((i % meta_bg_size) == 0) || + ((i % meta_bg_size) == 1) || + ((i % meta_bg_size) == (meta_bg_size-1))) + ext2fs_mark_block_bitmap(bmap, + block + has_super); + } + /* * Mark the blocks used for the inode table */ @@ -470,13 +519,49 @@ static errcode_t mark_table_blocks(ext2_filsys fs, } /* + * This function checks to see if a particular block (either a + * superblock or a block group descriptor) overlaps with an inode or + * block bitmap block, or with the inode table. + */ +static void mark_fs_metablock(ext2_resize_t rfs, + ext2fs_block_bitmap meta_bmap, + int group, blk_t blk) +{ + ext2_filsys fs = rfs->new_fs; + + ext2fs_mark_block_bitmap(rfs->reserve_blocks, blk); + ext2fs_mark_block_bitmap(fs->block_map, blk); + + /* + * Check to see if we overlap with the inode or block bitmap, + * or the inode tables. If not, and the block is in use, then + * mark it as a block to be moved. + */ + if (IS_BLOCK_BM(fs, group, blk)) { + FS_BLOCK_BM(fs, group) = 0; + rfs->needed_blocks++; + } else if (IS_INODE_BM(fs, group, blk)) { + FS_INODE_BM(fs, group) = 0; + rfs->needed_blocks++; + } else if (IS_INODE_TB(fs, group, blk)) { + FS_INODE_TB(fs, group) = 0; + rfs->needed_blocks++; + } else if (ext2fs_test_block_bitmap(rfs->old_fs->block_map, blk) && + !ext2fs_test_block_bitmap(meta_bmap, blk)) { + ext2fs_mark_block_bitmap(rfs->move_blocks, blk); + rfs->needed_blocks++; + } +} + + +/* * This routine marks and unmarks reserved blocks in the new block * bitmap. It also determines which blocks need to be moved and * places this information into the move_blocks bitmap. */ static errcode_t blocks_to_move(ext2_resize_t rfs) { - int i, j, max_groups; + int i, j, max_groups, has_super, meta_bg, meta_bg_size; blk_t blk, group_blk; unsigned long old_blocks, new_blocks; errcode_t retval; @@ -518,9 +603,14 @@ static errcode_t blocks_to_move(ext2_resize_t rfs) ext2fs_mark_block_bitmap(rfs->reserve_blocks, blk); } - old_blocks = old_fs->desc_blocks; - new_blocks = fs->desc_blocks; - + if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) { + old_blocks = old_fs->super->s_first_meta_bg; + new_blocks = fs->super->s_first_meta_bg; + } else { + old_blocks = old_fs->desc_blocks; + new_blocks = fs->desc_blocks; + } + if (old_blocks == new_blocks) { retval = 0; goto errout; @@ -556,38 +646,29 @@ static errcode_t blocks_to_move(ext2_resize_t rfs) * If we're increasing the number of descriptor blocks, life * gets interesting.... */ + meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc)); for (i = 0; i < max_groups; i++) { - if (!ext2fs_bg_has_super(fs, i)) - goto next_group; - - for (blk = group_blk; - blk < group_blk + 1 + new_blocks; blk++) { - ext2fs_mark_block_bitmap(rfs->reserve_blocks, blk); - ext2fs_mark_block_bitmap(fs->block_map, blk); - - /* - * Check to see if we overlap with the inode - * or block bitmap, or the inode tables. If - * not, and the block is in use, then mark it - * as a block to be moved. - */ - if (IS_BLOCK_BM(fs, i, blk)) { - FS_BLOCK_BM(fs, i) = 0; - rfs->needed_blocks++; - } else if (IS_INODE_BM(fs, i, blk)) { - FS_INODE_BM(fs, i) = 0; - rfs->needed_blocks++; - } else if (IS_INODE_TB(fs, i, blk)) { - FS_INODE_TB(fs, i) = 0; - rfs->needed_blocks++; - } else if (ext2fs_test_block_bitmap(old_fs->block_map, - blk) && - !ext2fs_test_block_bitmap(meta_bmap, blk)) { - ext2fs_mark_block_bitmap(rfs->move_blocks, - blk); - rfs->needed_blocks++; - } + has_super = ext2fs_bg_has_super(fs, i); + if (has_super) + mark_fs_metablock(rfs, meta_bmap, i, group_blk); + + meta_bg = i / meta_bg_size; + if (!(fs->super->s_feature_incompat & + EXT2_FEATURE_INCOMPAT_META_BG) || + (meta_bg < fs->super->s_first_meta_bg)) { + for (blk = group_blk+1; + blk < group_blk + 1 + new_blocks; blk++) + mark_fs_metablock(rfs, meta_bmap, i, blk); + } else { + if (has_super) + has_super = 1; + if (((i % meta_bg_size) == 0) || + ((i % meta_bg_size) == 1) || + ((i % meta_bg_size) == (meta_bg_size-1))) + mark_fs_metablock(rfs, meta_bmap, i, + group_blk + has_super); } + if (fs->group_desc[i].bg_inode_table && fs->group_desc[i].bg_inode_bitmap && fs->group_desc[i].bg_block_bitmap) |