Whamcloud - gitweb
LU-4017 e2fsprogs: always read full inode structure
[tools/e2fsprogs.git] / resize / resize2fs.c
index c672cdb..c1a4446 100644 (file)
@@ -202,7 +202,7 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
        rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
 
        print_resource_track(rfs, &overall_track, fs->io);
-       retval = ext2fs_close(rfs->new_fs);
+       retval = ext2fs_close_free(&rfs->new_fs);
        if (retval)
                goto errout;
 
@@ -436,8 +436,7 @@ retry:
                                            fs->inode_map);
        if (retval) goto errout;
 
-       real_end = (((blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super) *
-                    fs->group_desc_count)) - 1 +
+       real_end = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count) - 1 +
                fs->super->s_first_data_block;
        retval = ext2fs_resize_block_bitmap2(new_size - 1,
                                             real_end, fs->block_map);
@@ -490,6 +489,13 @@ retry:
                fs->super->s_reserved_gdt_blocks = new;
        }
 
+       if ((fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) &&
+           (fs->super->s_first_meta_bg > fs->desc_blocks)) {
+               fs->super->s_feature_incompat &=
+                       ~EXT2_FEATURE_INCOMPAT_META_BG;
+               fs->super->s_first_meta_bg = 0;
+       }
+
        /*
         * Update the location of the backup superblocks if the
         * sparse_super2 feature is enabled.
@@ -999,13 +1005,15 @@ static errcode_t blocks_to_move(ext2_resize_t rfs)
                ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
        }
 
-       if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) {
+       if (old_fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
                old_blocks = old_fs->super->s_first_meta_bg;
+       else
+               old_blocks = old_fs->desc_blocks +
+                       old_fs->super->s_reserved_gdt_blocks;
+       if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
                new_blocks = fs->super->s_first_meta_bg;
-       } else {
-               old_blocks = old_fs->desc_blocks + old_fs->super->s_reserved_gdt_blocks;
+       else
                new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
-       }
 
        retval = reserve_sparse_super2_last_group(rfs, meta_bmap);
        if (retval)
@@ -1576,8 +1584,8 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
        pb.error = 0;
        new_inode = EXT2_FIRST_INODE(rfs->new_fs->super);
        inode_size = EXT2_INODE_SIZE(rfs->new_fs->super);
-       inode = malloc(inode_size);
-       if (!inode) {
+       retval = ext2fs_get_mem(inode_size, &inode);
+       if (retval) {
                retval = ENOMEM;
                goto errout;
        }
@@ -1669,7 +1677,8 @@ errout:
                ext2fs_close_inode_scan(scan);
        if (block_buf)
                ext2fs_free_mem(&block_buf);
-       free(inode);
+       if (inode)
+               ext2fs_free_mem(&inode);
        return retval;
 }
 
@@ -1844,8 +1853,10 @@ static errcode_t move_itables(ext2_resize_t rfs)
                    ext2fs_inode_table_loc(fs, i))
                        to_move++;
 
-       if (to_move == 0)
-               return 0;
+       if (to_move == 0) {
+               retval = 0;
+               goto errout;
+       }
 
        if (rfs->progress) {
                retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS,
@@ -2047,7 +2058,7 @@ static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
                      stderr);
                exit(1);
        }
-       if (old_desc != sb+1) {
+       if (old_desc && old_desc != sb+1) {
                fputs(_("Should never happen!  Unexpected old_desc in "
                        "super_sparse bg?\n"),
                      stderr);
@@ -2318,7 +2329,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
                fs->super->s_free_inodes_count;
        blks_needed = ext2fs_div_ceil(inode_count,
                                      fs->super->s_inodes_per_group) *
-               EXT2_BLOCKS_PER_GROUP(fs->super);
+               (blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super);
        groups = ext2fs_div64_ceil(blks_needed,
                                   EXT2_BLOCKS_PER_GROUP(fs->super));
 #ifdef RESIZE2FS_DEBUG
@@ -2365,7 +2376,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
         * figure out how many data blocks we have given the number of groups
         * we need for our inodes
         */
-       data_blocks = groups * EXT2_BLOCKS_PER_GROUP(fs->super);
+       data_blocks = EXT2_GROUPS_TO_BLOCKS(fs->super, groups);
        last_start = 0;
        for (grp = 0; grp < flex_groups; grp++) {
                overhead = calc_group_overhead(fs, grp, old_desc_blocks);
@@ -2403,7 +2414,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
                extra_grps = ext2fs_div64_ceil(remainder,
                                               EXT2_BLOCKS_PER_GROUP(fs->super));
 
-               data_blocks += extra_grps * EXT2_BLOCKS_PER_GROUP(fs->super);
+               data_blocks += EXT2_GROUPS_TO_BLOCKS(fs->super, extra_grps);
 
                /* ok we have to account for the last group */
                overhead = calc_group_overhead(fs, groups-1, old_desc_blocks);
@@ -2501,7 +2512,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
         * blocks needed to handle the group descriptor metadata+data
         * that we need
         */
-       blks_needed = (groups-1) * EXT2_BLOCKS_PER_GROUP(fs->super);
+       blks_needed = EXT2_GROUPS_TO_BLOCKS(fs->super, groups - 1);
        blks_needed += overhead;
 
        /*