Whamcloud - gitweb
e2fsck: check for invalid bad block inode
authorTheodore Ts'o <tytso@mit.edu>
Wed, 28 Sep 2011 19:12:55 +0000 (15:12 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 28 Sep 2011 22:34:33 +0000 (18:34 -0400)
In some cases the bad block inode gets corrupted.  If it looks insane,
offer to clear it before trying to interpret it does more harm than
good.

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

index f45831f..7ce6697 100644 (file)
@@ -821,6 +821,14 @@ void e2fsck_pass1(e2fsck_t ctx)
                if (ino == EXT2_BAD_INO) {
                        struct process_block_struct pb;
 
+                       if ((inode->i_mode || inode->i_uid || inode->i_gid ||
+                            inode->i_links_count || inode->i_file_acl) &&
+                           fix_problem(ctx, PR_1_INVALID_BAD_INODE, &pctx)) {
+                               memset(inode, 0, sizeof(struct ext2_inode));
+                               e2fsck_write_inode(ctx, ino, inode,
+                                                  "clear bad inode");
+                       }
+
                        pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
                                                          &pb.fs_meta_blocks);
                        if (pctx.errcode) {
@@ -1715,6 +1723,9 @@ void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
         */
        ctx->flags |= restart_flag;
 
+       if (ino == EXT2_BAD_INO)
+               memset(inode, 0, sizeof(struct ext2_inode));
+
        e2fsck_write_inode(ctx, ino, inode, source);
 }
 
index cf4a270..6ee3fa4 100644 (file)
@@ -936,6 +936,11 @@ static struct e2fsck_problem problem_table[] = {
          N_("@q @i is visible to the user.  "),
          PROMPT_CLEAR, PR_PREEN_OK },
 
+       /* Invalid bad inode */
+       { PR_1_INVALID_BAD_INODE,
+         N_("The bad @b @i looks @n.  "),
+         PROMPT_CLEAR, 0 },
+
        /* Pass 1b errors */
 
        /* Pass 1B: Rescan for duplicate/bad blocks */
index 17b0c10..9db29d8 100644 (file)
@@ -547,6 +547,9 @@ struct problem_context {
 /* Quota inode is user visible */
 #define PR_1_QUOTA_INODE_NOT_HIDDEN    0x010064
 
+/* Invalid bad inode */
+#define PR_1_INVALID_BAD_INODE         0x010065
+
 /*
  * Pass 1b errors
  */
diff --git a/tests/f_invalid_bad_inode/expect.1 b/tests/f_invalid_bad_inode/expect.1
new file mode 100644 (file)
index 0000000..5a37cb0
--- /dev/null
@@ -0,0 +1,11 @@
+Pass 1: Checking inodes, blocks, and sizes
+The bad block inode looks invalid.  Clear? yes
+
+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_invalid_bad_inode/expect.2 b/tests/f_invalid_bad_inode/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_invalid_bad_inode/image.gz b/tests/f_invalid_bad_inode/image.gz
new file mode 100644 (file)
index 0000000..5dac147
Binary files /dev/null and b/tests/f_invalid_bad_inode/image.gz differ
diff --git a/tests/f_invalid_bad_inode/name b/tests/f_invalid_bad_inode/name
new file mode 100644 (file)
index 0000000..f981e8d
--- /dev/null
@@ -0,0 +1 @@
+check for bogus bad inode