Whamcloud - gitweb
e2fsck: always submit logical block 0 of a directory for pass 2
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 25 Jul 2014 12:39:45 +0000 (08:39 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 25 Jul 2014 12:39:45 +0000 (08:39 -0400)
Always iterate logical block 0 in a directory, even if no physical
block has been allocated.  Pass 2 will notice the lack of mapping and
offer to allocate a new directory block; this enables us to link the
directory into lost+found.

Previously, if there were no logical blocks mapped, we would fail to
pick up even block 0 of the directory for processing in pass 2.  This
meant that e2fsck never allocated a block 0 and therefore wouldn't fix
the missing . and .. entries for the directory; subsequent e2fsck runs
would complain about (yet never fix) the problem.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/pass1.c
tests/f_emptydir/expect.1 [new file with mode: 0644]
tests/f_emptydir/expect.2 [new file with mode: 0644]
tests/f_emptydir/image.gz [new file with mode: 0644]
tests/f_emptydir/name [new file with mode: 0644]

index 87e6d34..d056314 100644 (file)
@@ -2377,6 +2377,21 @@ static int process_block(ext2_filsys fs,
                return 0;
        }
 
+       /*
+        * For a directory, add logical block zero for processing even if it's
+        * not mapped or we'll be perennially stuck with broken "." and ".."
+        * entries.
+        */
+       if (p->is_dir && blockcnt == 0 && blk == 0) {
+               pctx->errcode = ext2fs_add_dir_block2(fs->dblist, p->ino, 0, 0);
+               if (pctx->errcode) {
+                       pctx->blk = blk;
+                       pctx->num = blockcnt;
+                       goto failed_add_dir_block;
+               }
+               p->last_db_block++;
+       }
+
        if (blk == 0)
                return 0;
 
diff --git a/tests/f_emptydir/expect.1 b/tests/f_emptydir/expect.1
new file mode 100644 (file)
index 0000000..c612621
--- /dev/null
@@ -0,0 +1,19 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 12, i_size is 1024, should be 0.  Fix? yes
+
+Pass 2: Checking directory structure
+Directory inode 12 has an unallocated block #0.  Allocate? yes
+
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+Free blocks count wrong for group #0 (957, counted=956).
+Fix? yes
+
+Free blocks count wrong (957, counted=956).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 12/256 files (8.3% non-contiguous), 1092/2048 blocks
+Exit status is 1
diff --git a/tests/f_emptydir/expect.2 b/tests/f_emptydir/expect.2
new file mode 100644 (file)
index 0000000..75c0515
--- /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/256 files (16.7% non-contiguous), 1092/2048 blocks
+Exit status is 0
diff --git a/tests/f_emptydir/image.gz b/tests/f_emptydir/image.gz
new file mode 100644 (file)
index 0000000..1b6f8f8
Binary files /dev/null and b/tests/f_emptydir/image.gz differ
diff --git a/tests/f_emptydir/name b/tests/f_emptydir/name
new file mode 100644 (file)
index 0000000..d5bc660
--- /dev/null
@@ -0,0 +1,2 @@
+always iterate dir block 0 or e2fsck goes into infinite loop
+