Whamcloud - gitweb
build: quiet build warnings for "gcc -Wall"
[tools/e2fsprogs.git] / e2fsck / super.c
index 14251ab..6f1ce3d 100644 (file)
@@ -9,6 +9,7 @@
  * %End-Header%
  */
 
+#include "config.h"
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -142,6 +143,7 @@ static int release_inode_block(ext2_filsys fs,
        }
 
        ext2fs_block_alloc_stats2(fs, blk, -1);
+       ctx->free_blocks++;
        return retval;
 }
 
@@ -159,7 +161,7 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
        errcode_t                       retval;
        __u32                           count;
 
-       if (!ext2fs_inode_has_valid_blocks(inode))
+       if (!ext2fs_inode_has_valid_blocks2(fs, inode))
                return 0;
 
        pb.buf = block_buf + 3 * ctx->fs->blocksize;
@@ -196,9 +198,10 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
        if (pb.truncated_blocks)
                ext2fs_iblk_sub_blocks(fs, inode, pb.truncated_blocks);
 
-       if (ext2fs_file_acl_block(inode)) {
-               retval = ext2fs_adjust_ea_refcount2(fs, ext2fs_file_acl_block(inode),
-                                                  block_buf, -1, &count);
+       if (ext2fs_file_acl_block(fs, inode)) {
+               retval = ext2fs_adjust_ea_refcount3(fs,
+                               ext2fs_file_acl_block(fs, inode),
+                               block_buf, -1, &count, ino);
                if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
                        retval = 0;
                        count = 1;
@@ -209,11 +212,12 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
                                ino);
                        return 1;
                }
-               if (count == 0)
+               if (count == 0) {
                        ext2fs_block_alloc_stats2(fs,
-                                                ext2fs_file_acl_block(inode),
-                                                -1);
-               ext2fs_file_acl_block_set(inode, 0);
+                                       ext2fs_file_acl_block(fs, inode), -1);
+                       ctx->free_blocks++;
+               }
+               ext2fs_file_acl_block_set(fs, inode, 0);
        }
        return 0;
 }
@@ -285,6 +289,7 @@ static int release_orphan_inodes(e2fsck_t ctx)
                if (!inode.i_links_count) {
                        ext2fs_inode_alloc_stats2(fs, ino, -1,
                                                  LINUX_S_ISDIR(inode.i_mode));
+                       ctx->free_inodes++;
                        inode.i_dtime = ctx->now;
                } else {
                        inode.i_dtime = 0;
@@ -312,7 +317,8 @@ void check_resize_inode(e2fsck_t ctx)
        struct problem_context  pctx;
        int             i, gdt_off, ind_off;
        dgrp_t          j;
-       blk64_t         blk, pblk, expect;
+       blk64_t         blk, pblk;
+       blk_t           expect; /* for resize inode, which is 32-bit only */
        __u32           *dind_buf = 0, *ind_buf;
        errcode_t       retval;
 
@@ -576,14 +582,26 @@ void check_super_block(e2fsck_t ctx)
                }
        }
 
+       /* Are metadata_csum and uninit_bg both set? */
+       if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+                                      EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
+           EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+                                      EXT4_FEATURE_RO_COMPAT_GDT_CSUM) &&
+           fix_problem(ctx, PR_0_META_AND_GDT_CSUM_SET, &pctx)) {
+               fs->super->s_feature_ro_compat &=
+                       ~EXT4_FEATURE_RO_COMPAT_GDT_CSUM;
+               ext2fs_mark_super_dirty(fs);
+               for (i = 0; i < fs->group_desc_count; i++)
+                       ext2fs_group_desc_csum_set(fs, i);
+       }
+
        /*
         * Verify the group descriptors....
         */
        first_block = sb->s_first_data_block;
        last_block = ext2fs_blocks_count(sb)-1;
 
-       csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-                                              EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
+       csum_flag = ext2fs_has_group_desc_csum(fs);
        for (i = 0; i < fs->group_desc_count; i++) {
                pctx.group = i;
 
@@ -634,6 +652,8 @@ void check_super_block(e2fsck_t ctx)
 
                should_be = 0;
                if (!ext2fs_group_desc_csum_verify(fs, i)) {
+                       pctx.csum1 = ext2fs_bg_checksum(fs, i);
+                       pctx.csum2 = ext2fs_group_desc_csum(fs, i);
                        if (fix_problem(ctx, PR_0_GDT_CSUM, &pctx)) {
                                ext2fs_bg_flags_clear(fs, i, EXT2_BG_BLOCK_UNINIT);
                                ext2fs_bg_flags_clear(fs, i, EXT2_BG_INODE_UNINIT);
@@ -665,15 +685,6 @@ void check_super_block(e2fsck_t ctx)
                        ext2fs_unmark_valid(fs);
                }
 
-               if (ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
-                   !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) {
-                       if (fix_problem(ctx, PR_0_BB_UNINIT_IB_INIT, &pctx)) {
-                               ext2fs_bg_flags_clear(fs, i, EXT2_BG_BLOCK_UNINIT);
-                               should_be = 1;
-                       }
-                       ext2fs_unmark_valid(fs);
-               }
-
                if (csum_flag &&
                    (ext2fs_bg_itable_unused(fs, i) > ext2fs_bg_free_inodes_count(fs, i) ||
                     ext2fs_bg_itable_unused(fs, i) > sb->s_inodes_per_group)) {
@@ -718,7 +729,8 @@ void check_super_block(e2fsck_t ctx)
        if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
                if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
                        uuid_generate(sb->s_uuid);
-                       ext2fs_mark_super_dirty(fs);
+                       ext2fs_init_csum_seed(fs);
+                       fs->flags |= EXT2_FLAG_DIRTY;
                        fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
                }
        }
@@ -736,7 +748,7 @@ void check_super_block(e2fsck_t ctx)
            (fs_proc_check("ext4") || check_for_modules("ext4"))) {
                if (fix_problem(ctx, PR_0_CLEAR_TESTFS_FLAG, &pctx)) {
                        fs->super->s_flags &= ~EXT2_FLAGS_TEST_FILESYS;
-                       ext2fs_mark_super_dirty(fs);
+                       fs->flags |= EXT2_FLAG_DIRTY;
                        fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
                }
        }
@@ -825,7 +837,7 @@ void check_super_block(e2fsck_t ctx)
                        problem = PR_0_FUTURE_SB_LAST_MOUNT_FUDGED;
                if (fix_problem(ctx, problem, &pctx)) {
                        fs->super->s_mtime = ctx->now;
-                       ext2fs_mark_super_dirty(fs);
+                       fs->flags |= EXT2_FLAG_DIRTY;
                }
        }
        if (!broken_system_clock &&
@@ -837,7 +849,7 @@ void check_super_block(e2fsck_t ctx)
                        problem = PR_0_FUTURE_SB_LAST_WRITE_FUDGED;
                if (fix_problem(ctx, problem, &pctx)) {
                        fs->super->s_wtime = ctx->now;
-                       ext2fs_mark_super_dirty(fs);
+                       fs->flags |= EXT2_FLAG_DIRTY;
                }
        }
 
@@ -916,8 +928,7 @@ int check_backup_super_block(e2fsck_t ctx)
                if (!ext2fs_bg_has_super(fs, g))
                        continue;
 
-               sb = fs->super->s_first_data_block +
-                       (g * fs->super->s_blocks_per_group);
+               sb = ext2fs_group_first_block2(fs, g);
 
                retval = io_channel_read_blk(fs->io, sb, -SUPERBLOCK_SIZE,
                                             buf);