Whamcloud - gitweb
Add support for the meta_bg feature flag to the resize2fs program.
authorTheodore Ts'o <tytso@mit.edu>
Thu, 31 Oct 2002 04:07:21 +0000 (23:07 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 31 Oct 2002 04:07:21 +0000 (23:07 -0500)
Fix bug in meta_bg support in mke2fs, e2fsck, and dumpe2fs; we were
incorrectly reserving the legacy block groups desriptor blocks.

12 files changed:
e2fsck/ChangeLog
e2fsck/pass1.c
lib/ext2fs/ChangeLog
lib/ext2fs/alloc_tables.c
lib/ext2fs/closefs.c
lib/ext2fs/initialize.c
misc/ChangeLog
misc/dumpe2fs.c
misc/mke2fs.c
resize/ChangeLog
resize/main.c
resize/resize2fs.c

index 9de2cdd..f781678 100644 (file)
@@ -1,3 +1,9 @@
+2002-10-30  Theodore Ts'o  <tytso@mit.edu>
+
+       * pass1.c (mark_table_blocks): Fix bug in meta_bg support; only
+               mark blocks legacy group descriptor blocks up to 
+               s_first_meta_bg.
+
 2002-10-20  Theodore Ts'o  <tytso@valinux.com>
 
        * pass1.c (mark_table_blocks): Add support for the meta_blockgroup
index c685581..f25be76 100644 (file)
@@ -1793,12 +1793,16 @@ static void mark_table_blocks(e2fsck_t ctx)
 {
        ext2_filsys fs = ctx->fs;
        blk_t   block, b;
-       int     i, j, has_super, meta_bg, meta_bg_size;
+       int     i, j, has_super, meta_bg, meta_bg_size, old_desc_blocks;
        struct problem_context pctx;
        
        clear_problem_context(&pctx);
        
        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++) {
                pctx.group = i;
 
@@ -1819,7 +1823,7 @@ static void mark_table_blocks(e2fsck_t ctx)
                                /*
                                 * Mark this group's copy of the descriptors
                                 */
-                               for (j = 0; j < fs->desc_blocks; j++) {
+                               for (j = 0; j < old_desc_blocks; j++) {
                                        ext2fs_mark_block_bitmap(ctx->block_found_map,
                                                         block + j + 1);
                                }
index 079615c..57e1d85 100644 (file)
@@ -1,3 +1,13 @@
+2002-10-30  Theodore Ts'o  <tytso@mit.edu>
+
+       * alloc_tables.c (ext2fs_allocate_group_table): Allocate the inode
+               table so that it buts up against the bitmap blocks, to
+               avoid block fragmentation.
+
+       * closefs.c (write_bgdesc), initalize.c (ext2fs_initialize): Fix
+               bug; only allocate group descriptor blocks up to
+               s_first_meta_bg.
+
 2002-10-25  Theodore Ts'o  <tytso@mit.edu>
 
        * ext2_fs.h: Add a new superblock field, s_mkfs_time, so that we
index ca274cc..0326321 100644 (file)
@@ -41,38 +41,17 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
        if (last_blk >= fs->super->s_blocks_count)
                last_blk = fs->super->s_blocks_count - 1;
 
-       start_blk = group_blk + 3 + fs->desc_blocks;
-       if (start_blk > last_blk)
-               start_blk = group_blk;
-
        if (!bmap)
                bmap = fs->block_map;
        
        /*
-        * Allocate the inode table
-        */
-       if (!fs->group_desc[group].bg_inode_table) {
-               retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-                                               fs->inode_blocks_per_group,
-                                               bmap, &new_blk);
-               if (retval)
-                       return retval;
-               for (j=0, blk = new_blk;
-                    j < fs->inode_blocks_per_group;
-                    j++, blk++)
-                       ext2fs_mark_block_bitmap(bmap, blk);
-               fs->group_desc[group].bg_inode_table = new_blk;
-       }
-
-       /*
         * Allocate the block and inode bitmaps, if necessary
         */
        if (fs->stride) {
-               start_blk += fs->inode_blocks_per_group;
+               start_blk = group_blk + fs->inode_blocks_per_group;
                start_blk += ((fs->stride * group) %
                              (last_blk - start_blk));
                if (start_blk > last_blk)
-                       /* should never happen */
                        start_blk = group_blk;
        } else
                start_blk = group_blk;
@@ -100,6 +79,24 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
                ext2fs_mark_block_bitmap(bmap, new_blk);
                fs->group_desc[group].bg_inode_bitmap = new_blk;
        }
+
+       /*
+        * Allocate the inode table
+        */
+       if (!fs->group_desc[group].bg_inode_table) {
+               retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
+                                               fs->inode_blocks_per_group,
+                                               bmap, &new_blk);
+               if (retval)
+                       return retval;
+               for (j=0, blk = new_blk;
+                    j < fs->inode_blocks_per_group;
+                    j++, blk++)
+                       ext2fs_mark_block_bitmap(bmap, blk);
+               fs->group_desc[group].bg_inode_table = new_blk;
+       }
+
+       
        return 0;
 }
 
index dcf244b..c96b7ab 100644 (file)
@@ -122,18 +122,21 @@ static errcode_t write_bgdesc(ext2_filsys fs, dgrp_t group, blk_t group_block,
 {
        errcode_t       retval;
        char            *group_ptr = (char *) group_shadow;
-       int             j;
+       int             j, old_desc_blocks;
        int             has_super = ext2fs_bg_has_super(fs, group);
        dgrp_t          meta_bg_size, meta_bg;
-       blk_t           blk;
 
        meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc));
        meta_bg = group / meta_bg_size;
+       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;
        if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
            (meta_bg < fs->super->s_first_meta_bg)) {
                if (!has_super)
                        return 0;
-               for (j=0; j < fs->desc_blocks; j++) {
+               for (j=0; j < old_desc_blocks; j++) {
                        retval = io_channel_write_blk(fs->io,
                                                      group_block+1+j, 1,
                                                      group_ptr);
@@ -180,7 +183,6 @@ errcode_t ext2fs_flush(ext2_filsys fs)
        dgrp_t          i,j,maxgroup;
        blk_t           group_block;
        errcode_t       retval;
-       char            *group_ptr;
        unsigned long   fs_state;
        struct ext2_super_block *super_shadow = 0;
        struct ext2_group_desc *group_shadow = 0;
@@ -277,7 +279,6 @@ errcode_t ext2fs_flush(ext2_filsys fs)
                                                   group_shadow)))
                                goto errout;
                }
-       next_group:
                group_block += EXT2_BLOCKS_PER_GROUP(fs->super);
        }
        fs->super->s_block_group_nr = 0;
index ecb27d7..f5552e6 100644 (file)
@@ -67,7 +67,7 @@ errcode_t ext2fs_initialize(const char *name, int flags,
        int             i, j;
        blk_t           numblocks;
        char            *buf;
-       int             meta_bg_size, meta_bg, has_super;
+       int             meta_bg_size, meta_bg, has_super, old_desc_blocks;
 
        if (!param || !param->s_blocks_count)
                return EXT2_ET_INVALID_ARGUMENT;
@@ -293,6 +293,10 @@ retry:
         */
        group_block = super->s_first_data_block;
        super->s_free_blocks_count = 0;
+       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 (i == fs->group_desc_count-1) {
                        numblocks = (fs->super->s_blocks_count -
@@ -317,10 +321,10 @@ retry:
                      EXT2_FEATURE_INCOMPAT_META_BG) ||
                    (meta_bg < fs->super->s_first_meta_bg)) {
                        if (has_super) {
-                               for (j=0; j < fs->desc_blocks; j++)
+                               for (j=0; j < old_desc_blocks; j++)
                                        ext2fs_mark_block_bitmap(fs->block_map,
                                                         group_block + j + 1);
-                               numblocks -= fs->desc_blocks;
+                               numblocks -= old_desc_blocks;
                        }
                } else {
                        if (has_super)
@@ -357,6 +361,3 @@ cleanup:
        ext2fs_free(fs);
        return retval;
 }
-       
-
-
index 6f6d29f..57e6bc1 100644 (file)
@@ -1,3 +1,12 @@
+2002-10-30  Theodore Ts'o  <tytso@mit.edu>
+
+       * dumpe2fs.c (list_desc): Fix bug in algorithm which determined
+               which blocks are used as backup superblock and block group
+               descriptors.
+
+       * mke2fs.c (PRS): Fix bug which checked the tmp pointer
+               erreoneously (and needlessly).
+
 2002-10-28    <tytso@snap.thunk.org>
 
        * fsck.c (main): Fix bug reported by Gregory Mutt.  Multiple
index d1308ef..073238e 100644 (file)
@@ -87,8 +87,7 @@ static void list_desc (ext2_filsys fs)
        long diff;
        blk_t   group_blk, next_blk;
        char *block_bitmap=NULL, *inode_bitmap=NULL;
-       int inode_blocks_per_group;
-       int group_desc_blocks;
+       int inode_blocks_per_group, old_desc_blocks;
        int meta_bg, meta_bg_size, has_super;
 
        if (fs->block_map)
@@ -100,15 +99,12 @@ static void list_desc (ext2_filsys fs)
                                   EXT2_INODE_SIZE(fs->super)) +
                                  EXT2_BLOCK_SIZE(fs->super) - 1) /
                                 EXT2_BLOCK_SIZE(fs->super);
-       group_desc_blocks = ((fs->super->s_blocks_count -
-                             fs->super->s_first_data_block +
-                             EXT2_BLOCKS_PER_GROUP(fs->super) - 1) /
-                            EXT2_BLOCKS_PER_GROUP(fs->super) +
-                            EXT2_DESC_PER_BLOCK(fs->super) - 1) /
-                           EXT2_DESC_PER_BLOCK(fs->super);
-
        fputc('\n', stdout);
        group_blk = 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++) {
                next_blk = group_blk + fs->super->s_blocks_per_group;
                if (next_blk > fs->super->s_blocks_count)
@@ -128,11 +124,12 @@ static void list_desc (ext2_filsys fs)
                if (!(fs->super->s_feature_incompat &
                      EXT2_FEATURE_INCOMPAT_META_BG) ||
                    (meta_bg < fs->super->s_first_meta_bg)) {
-                       fputc(has_super ? ',' : ' ', stdout);
-                       printf(_(" Group descriptors at "));
-                       printf(range_format, group_blk+1,
-                              group_blk + group_desc_blocks);
-                       fputc('\n', stdout);
+                       if (has_super) {
+                               printf(_(", Group descriptors at "));
+                               printf(range_format, group_blk+1,
+                                      group_blk + old_desc_blocks);
+                               fputc('\n', stdout);
+                       }
                } else {
                        if (has_super)
                                has_super = 1;
index 1c83d9f..0371c37 100644 (file)
@@ -1175,7 +1175,7 @@ static void PRS(int argc, char *argv[])
 
        if (param.s_blocks_per_group) {
                if (param.s_blocks_per_group < 256 ||
-                   param.s_blocks_per_group > group_blk_max || *tmp) {
+                   param.s_blocks_per_group > group_blk_max) {
                        com_err(program_name, 0,
                                _("blocks per group count out of range"));
                        exit(1);
index 5c6f663..54f0ae9 100644 (file)
@@ -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.
index 7808b1d..841f4bd 100644 (file)
@@ -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);
index 4dd2b33..cc2fda4 100644 (file)
@@ -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)