Whamcloud - gitweb
e2fsck: fix problem report typo
[tools/e2fsprogs.git] / e2fsck / pass1.c
index 0a8e23e..631d735 100644 (file)
@@ -102,7 +102,7 @@ struct process_block_struct {
 
 struct process_inode_block {
        ext2_ino_t ino;
-       struct ext2_inode inode;
+       struct ext2_inode_large inode;
 };
 
 struct scan_callback_struct {
@@ -482,6 +482,10 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
                return;
        }
 
+       /* check if there is no place for an EA header */
+       if (inode->i_extra_isize >= max - sizeof(__u32))
+               return;
+
        eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
                        inode->i_extra_isize);
        if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
@@ -950,6 +954,41 @@ out:
        }
 }
 
+/*
+ * Check if the passed ino is one of the used superblock quota inodes.
+ *
+ * Before the quota inodes were journaled, older superblock quota inodes
+ * were just regular files in the filesystem and not reserved inodes.  This
+ * checks if the passed ino is one of the s_*_quota_inum superblock fields,
+ * which may not always be the same as the EXT4_*_QUOTA_INO fields.
+ */
+static int quota_inum_is_super(struct ext2_super_block *sb, ext2_ino_t ino)
+{
+       enum quota_type qtype;
+
+       for (qtype = 0; qtype < MAXQUOTAS; qtype++)
+               if (*quota_sb_inump(sb, qtype) == ino)
+                       return 1;
+
+       return 0;
+}
+
+/*
+ * Check if the passed ino is one of the reserved quota inodes.
+ * This checks if the inode number is one of the reserved EXT4_*_QUOTA_INO
+ * inodes.  These inodes may or may not be in use by the quota feature.
+ */
+static int quota_inum_is_reserved(ext2_filsys fs, ext2_ino_t ino)
+{
+       enum quota_type qtype;
+
+       for (qtype = 0; qtype < MAXQUOTAS; qtype++)
+               if (quota_type2inum(qtype, fs->super) == ino)
+                       return 1;
+
+       return 0;
+}
+
 void e2fsck_pass1(e2fsck_t ctx)
 {
        int     i;
@@ -1166,7 +1205,7 @@ void e2fsck_pass1(e2fsck_t ctx)
                        pass1_readahead(ctx, &ra_group, &ino_threshold);
                ehandler_operation(old_op);
                if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
-                       return;
+                       goto endit;
                if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
                        /*
                         * If badblocks says badblocks is bad, offer to clear
@@ -1498,12 +1537,10 @@ void e2fsck_pass1(e2fsck_t ctx)
                                                        inode_size, "pass1");
                                failed_csum = 0;
                        }
-               } else if ((ino == EXT4_USR_QUOTA_INO) ||
-                          (ino == EXT4_GRP_QUOTA_INO)) {
+               } else if (quota_inum_is_reserved(fs, ino)) {
                        ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
                        if (ext2fs_has_feature_quota(fs->super) &&
-                           ((fs->super->s_usr_quota_inum == ino) ||
-                            (fs->super->s_grp_quota_inum == ino))) {
+                           quota_inum_is_super(fs->super, ino)) {
                                if (!LINUX_S_ISREG(inode->i_mode) &&
                                    fix_problem(ctx, PR_1_QUOTA_BAD_MODE,
                                                        &pctx)) {
@@ -1737,7 +1774,8 @@ void e2fsck_pass1(e2fsck_t ctx)
                     inode->i_block[EXT2_TIND_BLOCK] ||
                     ext2fs_file_acl_block(fs, inode))) {
                        inodes_to_process[process_inode_count].ino = ino;
-                       inodes_to_process[process_inode_count].inode = *inode;
+                       inodes_to_process[process_inode_count].inode =
+                                      *(struct ext2_inode_large *)inode;
                        process_inode_count++;
                } else
                        check_blocks(ctx, &pctx, block_buf);
@@ -1847,6 +1885,8 @@ endit:
 
        if ((ctx->flags & E2F_FLAG_SIGNAL_MASK) == 0)
                print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
+       else
+               ctx->invalid_bitmaps++;
 }
 #undef FINISH_INODE_LOOP
 
@@ -2820,7 +2860,20 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
        ext2_ino_t              ino = pctx->ino;
        errcode_t               retval;
        blk64_t                 eof_lblk;
+       struct ext3_extent_header       *eh;
+
+       /* Check for a proper extent header... */
+       eh = (struct ext3_extent_header *) &inode->i_block[0];
+       retval = ext2fs_extent_header_verify(eh, sizeof(inode->i_block));
+       if (retval) {
+               if (fix_problem(ctx, PR_1_MISSING_EXTENT_HEADER, pctx))
+                       e2fsck_clear_inode(ctx, ino, inode, 0,
+                                          "check_blocks_extents");
+               pctx->errcode = 0;
+               return;
+       }
 
+       /* ...since this function doesn't fail if i_block is zeroed. */
        pctx->errcode = ext2fs_extent_open2(fs, ino, inode, &ehandle);
        if (pctx->errcode) {
                if (fix_problem(ctx, PR_1_READ_EXTENT, pctx))
@@ -3068,7 +3121,8 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                }
        }
 
-       if (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super)) {
+       if (ino != quota_type2inum(PRJQUOTA, fs->super) &&
+           (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super))) {
                quota_data_add(ctx->qctx, inode, ino,
                               pb.num_blocks * fs->blocksize);
                quota_data_inodes(ctx->qctx, inode, ino, +1);