Whamcloud - gitweb
e2fsck: check for invalid quota inode numbers
authorTheodore Ts'o <tytso@mit.edu>
Sat, 22 Jul 2017 20:08:25 +0000 (16:08 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 22 Jul 2017 21:43:17 +0000 (17:43 -0400)
If the superblock has invalid inode numbers for the user, group, or
project quota inodes, e2fsck should notice and offer to fix things by
zeroing out the invalid superblock field.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/e2fsck.h
e2fsck/problem.c
e2fsck/problem.h
e2fsck/quota.c
e2fsck/super.c
tests/f_quota_invalid_inum/expect.1 [new file with mode: 0644]
tests/f_quota_invalid_inum/expect.2 [new file with mode: 0644]
tests/f_quota_invalid_inum/image.gz [new file with mode: 0644]
tests/f_quota_invalid_inum/name [new file with mode: 0644]

index 6ab4f9c..81c09d7 100644 (file)
@@ -505,6 +505,7 @@ extern void set_up_logging(e2fsck_t ctx);
 
 /* quota.c */
 extern void e2fsck_hide_quota(e2fsck_t ctx);
+extern void e2fsck_validate_quota_inodes(e2fsck_t ctx);
 
 /* pass1.c */
 extern errcode_t e2fsck_setup_icount(e2fsck_t ctx, const char *icount_name,
index 5359d6b..c4c5542 100644 (file)
@@ -488,6 +488,11 @@ static struct e2fsck_problem problem_table[] = {
          N_("Bad desired extra isize in @S (%N).  "),
          PROMPT_FIX, 0 },
 
+       /* Invalid quota inode number */
+       { PR_0_INVALID_QUOTA_INO,
+         N_("Invalid %U @q @i %i.  "),
+         PROMPT_FIX, 0 },
+
        /* Pass 1 errors */
 
        /* Pass 1: Checking inodes, blocks, and sizes */
index d291e26..c949547 100644 (file)
@@ -279,6 +279,9 @@ struct problem_context {
 /* Bad desired extra isize in superblock */
 #define PR_0_BAD_WANT_EXTRA_ISIZE              0x00004E
 
+/* Invalid quota inode number */
+#define PR_0_INVALID_QUOTA_INO                 0x00004F
+
 
 /*
  * Pass 1 errors
index 173997e..b0f9af6 100644 (file)
@@ -79,8 +79,39 @@ void e2fsck_hide_quota(e2fsck_t ctx)
                    fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx)) {
                        move_quota_inode(fs, pctx.ino, quota_ino, qtype);
                        *quota_sb_inump(sb, qtype) = quota_ino;
+                       ext2fs_mark_super_dirty(fs);
                }
        }
 
        return;
 }
+
+void e2fsck_validate_quota_inodes(e2fsck_t ctx)
+{
+       struct ext2_super_block *sb = ctx->fs->super;
+       struct problem_context  pctx;
+       ext2_filsys             fs = ctx->fs;
+       enum quota_type qtype;
+       ext2_ino_t quota_ino;
+
+       clear_problem_context(&pctx);
+
+       for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
+               pctx.ino = *quota_sb_inump(sb, qtype);
+               pctx.num = qtype;
+               if (pctx.ino &&
+                   ((pctx.ino == EXT2_BAD_INO) ||
+                    (pctx.ino == EXT2_ROOT_INO) ||
+                    (pctx.ino == EXT2_BOOT_LOADER_INO) ||
+                    (pctx.ino == EXT2_UNDEL_DIR_INO) ||
+                    (pctx.ino == EXT2_RESIZE_INO) ||
+                    (pctx.ino == EXT2_JOURNAL_INO) ||
+                    (pctx.ino == EXT2_EXCLUDE_INO) ||
+                    (pctx.ino == EXT4_REPLICA_INO) ||
+                    (pctx.ino > fs->super->s_inodes_count)) &&
+                   fix_problem(ctx, PR_0_INVALID_QUOTA_INO, &pctx)) {
+                       *quota_sb_inump(sb, qtype) = 0;
+                       ext2fs_mark_super_dirty(fs);
+               }
+       }
+}
index d2fd922..8153f2b 100644 (file)
@@ -910,6 +910,8 @@ void check_super_block(e2fsck_t ctx)
                }
        }
 
+       e2fsck_validate_quota_inodes(ctx);
+
        /*
         * Move the ext3 journal file, if necessary.
         */
diff --git a/tests/f_quota_invalid_inum/expect.1 b/tests/f_quota_invalid_inum/expect.1
new file mode 100644 (file)
index 0000000..a989f16
--- /dev/null
@@ -0,0 +1,15 @@
+Invalid user quota inode 808464432.  Fix? yes
+
+Invalid group quota inode 808464432.  Fix? yes
+
+Invalid group quota inode 808464432.  Fix? yes
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 11/16 files (0.0% non-contiguous), 21/100 blocks
+Exit status is 1
diff --git a/tests/f_quota_invalid_inum/expect.2 b/tests/f_quota_invalid_inum/expect.2
new file mode 100644 (file)
index 0000000..41ceefb
--- /dev/null
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/16 files (0.0% non-contiguous), 21/100 blocks
+Exit status is 0
diff --git a/tests/f_quota_invalid_inum/image.gz b/tests/f_quota_invalid_inum/image.gz
new file mode 100644 (file)
index 0000000..28be80e
Binary files /dev/null and b/tests/f_quota_invalid_inum/image.gz differ
diff --git a/tests/f_quota_invalid_inum/name b/tests/f_quota_invalid_inum/name
new file mode 100644 (file)
index 0000000..a742406
--- /dev/null
@@ -0,0 +1 @@
+invalid quota inode numbers