OSDN Git Service

e2fsck: check for zero length extent
authorTheodore Ts'o <tytso@mit.edu>
Sun, 11 Mar 2012 20:19:10 +0000 (16:19 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 12 Mar 2012 03:31:38 +0000 (23:31 -0400)
If an extent has e_len set to zero, the kernel will oops with a
BUG_ON.  Unfortunately, e2fsck wasn't catching this case.  The kernel
needs to be fixed to notice this case and call ext4_error() instead of
failing an assertion check, but e2fsck should catch this case and
repair it (by deleting the errant extent).

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

index 5faa093..9f4142b 100644 (file)
@@ -1778,6 +1778,8 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
                        problem = PR_1_EXTENT_BAD_START_BLK;
                else if (extent.e_lblk < start_block)
                        problem = PR_1_OUT_OF_ORDER_EXTENTS;
+               else if (extent.e_len == 0)
+                       problem = PR_1_EXTENT_LENGTH_ZERO;
                else if (is_leaf &&
                         (extent.e_pblk + extent.e_len) >
                         ext2fs_blocks_count(ctx->fs->super))
index 579c838..b951eb7 100644 (file)
@@ -936,6 +936,11 @@ static struct e2fsck_problem problem_table[] = {
          N_("The bad @b @i looks @n.  "),
          PROMPT_CLEAR, 0 },
 
+       /* Extent has zero length */
+       { PR_1_EXTENT_LENGTH_ZERO,
+         N_("@i %i has zero length extent\n\t(@n logical @b %c, physical @b %b)\n"),
+         PROMPT_CLEAR, 0 },
+
        /* Pass 1b errors */
 
        /* Pass 1B: Rescan for duplicate/bad blocks */
index 3fabc90..f2bd414 100644 (file)
@@ -550,6 +550,9 @@ struct problem_context {
 /* Invalid bad inode */
 #define PR_1_INVALID_BAD_INODE         0x010065
 
+/* Extent has zero length */
+#define PR_1_EXTENT_LENGTH_ZERO                0x010066
+
 /*
  * Pass 1b errors
  */
diff --git a/tests/f_ext_zero_len/expect.1 b/tests/f_ext_zero_len/expect.1
new file mode 100644 (file)
index 0000000..40109b3
--- /dev/null
@@ -0,0 +1,13 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 12 has zero length extent
+       (invalid logical block 0, physical block 37)
+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: 12/16 files (0.0% non-contiguous), 21/100 blocks
+Exit status is 1
diff --git a/tests/f_ext_zero_len/expect.2 b/tests/f_ext_zero_len/expect.2
new file mode 100644 (file)
index 0000000..4ee5d96
--- /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: 12/16 files (0.0% non-contiguous), 21/100 blocks
+Exit status is 0
diff --git a/tests/f_ext_zero_len/image.gz b/tests/f_ext_zero_len/image.gz
new file mode 100644 (file)
index 0000000..a03e5fd
Binary files /dev/null and b/tests/f_ext_zero_len/image.gz differ
diff --git a/tests/f_ext_zero_len/name b/tests/f_ext_zero_len/name
new file mode 100644 (file)
index 0000000..ada4a72
--- /dev/null
@@ -0,0 +1 @@
+extent with zero length