Whamcloud - gitweb
e2fsck: pass1c terminates early if hard links
authorJim Garlick <garlick@llnl.gov>
Wed, 11 Apr 2007 02:55:09 +0000 (22:55 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 11 Apr 2007 02:55:09 +0000 (22:55 -0400)
I think this is a small buglet in e2fsck:  if a file has multiple hard
links, e2fsck pass1c search_dirent_proc() doesn't maintain its count
properly and may return DIRENT_ABORT before it has found containing
directories for all inodes sharing blocks.

Signed-off-by: Jim Garlick <garlick@llnl.gov>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
e2fsck/ChangeLog
e2fsck/pass1b.c
tests/ChangeLog
tests/f_dup4/expect.1 [new file with mode: 0644]
tests/f_dup4/expect.2 [new file with mode: 0644]
tests/f_dup4/name [new file with mode: 0644]
tests/f_dup4/script [new file with mode: 0644]

index f53743c..3200d41 100644 (file)
@@ -1,3 +1,11 @@
+2007-04-10  Jim Garlick <garlick@llnl.gov>
+
+       * pass1b.c (search_dirent_proc): if a file has multiple hard
+               links, e2fsck pass1c search_dirent_proc() doesn't maintain
+               its count properly and may return DIRENT_ABORT before it
+               has found containing directories for all inodes sharing
+               blocks.
+
 2007-04-06  Theodore Tso  <tytso@mit.edu>
 
        * e2fsck.conf.5.in: Update man page to document the scratch_files
index ae2b15a..578c1fe 100644 (file)
@@ -372,8 +372,10 @@ static int search_dirent_proc(ext2_ino_t dir, int entry,
        if (!n)
                return 0;
        p = (struct dup_inode *) dnode_get(n);
-       p->dir = dir;
-       sd->count--;
+       if (!p->dir) {
+               p->dir = dir;
+               sd->count--;
+       }
 
        return(sd->count ? 0 : DIRENT_ABORT);
 }
index b867512..8e853b3 100644 (file)
@@ -1,3 +1,11 @@
+2007-04-10  Theodore Tso  <tytso@mit.edu>
+
+       * f_dup4: New test cases which tests a bugfix in e2fsck where if an
+               inode which has blocks claimed by other inodes has
+               multiple hard links, e2fsck could fail to collect the
+               directory information for all of the inodes with multiply
+               claimed blocks.
+
 2007-04-07  Theodore Tso  <tytso@mit.edu>
 
        * test_script.in: Skip completely empty directories
diff --git a/tests/f_dup4/expect.1 b/tests/f_dup4/expect.1
new file mode 100644 (file)
index 0000000..7d51bb1
--- /dev/null
@@ -0,0 +1,112 @@
+Pass 1: Checking inodes, blocks, and sizes
+
+Running additional passes to resolve blocks claimed by more than one inode...
+Pass 1B: Rescanning for multiply-claimed blocks
+Multiply-claimed block(s) in inode 16: 30
+Multiply-claimed block(s) in inode 17: 30
+Multiply-claimed block(s) in inode 18: 30
+Multiply-claimed block(s) in inode 19: 30
+Multiply-claimed block(s) in inode 20: 34
+Multiply-claimed block(s) in inode 21: 34
+Multiply-claimed block(s) in inode 22: 34
+Multiply-claimed block(s) in inode 23: 34
+Pass 1C: Scanning directories for inodes with multiply-claimed blocks
+Pass 1D: Reconciling multiply-claimed blocks
+(There are 8 inodes containing multiply-claimed blocks.)
+
+File /dir/foo (inode #16, mod time Tue Apr 10 21:00:00 2007) 
+  has 1 multiply-claimed block(s), shared with 3 file(s):
+       /dir/quux1 (inode #19, mod time Tue Apr 10 21:00:00 2007)
+       /dir3/baz (inode #18, mod time Tue Apr 10 21:00:00 2007)
+       /dir2/bar (inode #17, mod time Tue Apr 10 21:00:00 2007)
+Clone multiply-claimed blocks? yes
+
+File /dir2/bar (inode #17, mod time Tue Apr 10 21:00:00 2007) 
+  has 1 multiply-claimed block(s), shared with 3 file(s):
+       /dir/quux1 (inode #19, mod time Tue Apr 10 21:00:00 2007)
+       /dir3/baz (inode #18, mod time Tue Apr 10 21:00:00 2007)
+       /dir/foo (inode #16, mod time Tue Apr 10 21:00:00 2007)
+Clone multiply-claimed blocks? yes
+
+File /dir3/baz (inode #18, mod time Tue Apr 10 21:00:00 2007) 
+  has 1 multiply-claimed block(s), shared with 3 file(s):
+       /dir/quux1 (inode #19, mod time Tue Apr 10 21:00:00 2007)
+       /dir2/bar (inode #17, mod time Tue Apr 10 21:00:00 2007)
+       /dir/foo (inode #16, mod time Tue Apr 10 21:00:00 2007)
+Clone multiply-claimed blocks? yes
+
+File /dir/quux1 (inode #19, mod time Tue Apr 10 21:00:00 2007) 
+  has 1 multiply-claimed block(s), shared with 3 file(s):
+       /dir3/baz (inode #18, mod time Tue Apr 10 21:00:00 2007)
+       /dir2/bar (inode #17, mod time Tue Apr 10 21:00:00 2007)
+       /dir/foo (inode #16, mod time Tue Apr 10 21:00:00 2007)
+Multiply-claimed blocks already reassigned or cloned.
+
+File /dir/fee (inode #20, mod time Tue Apr 10 21:00:00 2007) 
+  has 1 multiply-claimed block(s), shared with 3 file(s):
+       /dir4/fum (inode #23, mod time Tue Apr 10 21:00:00 2007)
+       /dir3/foe (inode #22, mod time Tue Apr 10 21:00:00 2007)
+       /dir2/fie (inode #21, mod time Tue Apr 10 21:00:00 2007)
+Clone multiply-claimed blocks? yes
+
+File /dir2/fie (inode #21, mod time Tue Apr 10 21:00:00 2007) 
+  has 1 multiply-claimed block(s), shared with 3 file(s):
+       /dir4/fum (inode #23, mod time Tue Apr 10 21:00:00 2007)
+       /dir3/foe (inode #22, mod time Tue Apr 10 21:00:00 2007)
+       /dir/fee (inode #20, mod time Tue Apr 10 21:00:00 2007)
+Clone multiply-claimed blocks? yes
+
+File /dir3/foe (inode #22, mod time Tue Apr 10 21:00:00 2007) 
+  has 1 multiply-claimed block(s), shared with 3 file(s):
+       /dir4/fum (inode #23, mod time Tue Apr 10 21:00:00 2007)
+       /dir2/fie (inode #21, mod time Tue Apr 10 21:00:00 2007)
+       /dir/fee (inode #20, mod time Tue Apr 10 21:00:00 2007)
+Clone multiply-claimed blocks? yes
+
+File /dir4/fum (inode #23, mod time Tue Apr 10 21:00:00 2007) 
+  has 1 multiply-claimed block(s), shared with 3 file(s):
+       /dir3/foe (inode #22, mod time Tue Apr 10 21:00:00 2007)
+       /dir2/fie (inode #21, mod time Tue Apr 10 21:00:00 2007)
+       /dir/fee (inode #20, mod time Tue Apr 10 21:00:00 2007)
+Multiply-claimed blocks already reassigned or cloned.
+
+Pass 2: Checking directory structure
+Invalid inode number for '.' in directory inode 20.
+Fix? yes
+
+Invalid inode number for '.' in directory inode 21.
+Fix? yes
+
+Invalid inode number for '.' in directory inode 22.
+Fix? yes
+
+Pass 3: Checking directory connectivity
+'..' in /dir/fee (20) is /dir4 (15), should be /dir (12).
+Fix? yes
+
+'..' in /dir2/fie (21) is /dir4 (15), should be /dir2 (13).
+Fix? yes
+
+'..' in /dir3/foe (22) is /dir4 (15), should be /dir3 (14).
+Fix? yes
+
+Pass 4: Checking reference counts
+Inode 12 ref count is 4, should be 3.  Fix? yes
+
+Inode 13 ref count is 4, should be 3.  Fix? yes
+
+Inode 14 ref count is 4, should be 3.  Fix? yes
+
+Inode 15 ref count is 0, should be 3.  Fix? yes
+
+Inode 16 ref count is 1, should be 3.  Fix? yes
+
+Inode 17 ref count is 1, should be 2.  Fix? yes
+
+Inode 19 ref count is 1, should be 3.  Fix? yes
+
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 23/32 files (0.0% non-contiguous), 35/100 blocks
+Exit status is 1
diff --git a/tests/f_dup4/expect.2 b/tests/f_dup4/expect.2
new file mode 100644 (file)
index 0000000..eedf286
--- /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: 23/32 files (0.0% non-contiguous), 35/100 blocks
+Exit status is 0
diff --git a/tests/f_dup4/name b/tests/f_dup4/name
new file mode 100644 (file)
index 0000000..261cb44
--- /dev/null
@@ -0,0 +1,2 @@
+find all directdory pathnames
+
diff --git a/tests/f_dup4/script b/tests/f_dup4/script
new file mode 100644 (file)
index 0000000..350f88e
--- /dev/null
@@ -0,0 +1,50 @@
+SKIP_GUNZIP="true"
+TEST_DATA="test.data"
+
+echo "/ Murphy Magic.  The SeCrEt of the UnIvErSe is 43, NOT 42" > $TEST_DATA
+
+touch $TMPFILE
+$MKE2FS -N 32 -F -o Linux -b 1024 $TMPFILE 100 > /dev/null 2>&1 
+$DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1
+set_current_time 200704102100
+set_super_value lastcheck 0
+set_super_value hash_seed null
+set_super_value mkfs_time 0
+mkdir dir
+mkdir dir2
+mkdir dir3
+mkdir dir4
+cd /dir
+write $TEST_DATA foo
+cd /dir2
+write $TEST_DATA bar
+cd /dir3
+write $TEST_DATA baz
+cd /dir4
+write $TEST_DATA quux
+mkdir /dir/fee
+mkdir /dir2/fie
+mkdir /dir3/foe
+mkdir /dir4/fum
+link /dir/foo /dir2/foo1
+link /dir/foo /dir3/foo2
+link /dir2/bar /dir3/bar1
+link /dir4/quux /dir/quux1
+link /dir4/quux /dir2/quux2
+set_inode_field /dir/foo block[0] 30
+set_inode_field /dir2/bar block[0] 30
+set_inode_field /dir3/baz block[0] 30
+set_inode_field /dir/fee block[0] 34
+set_inode_field /dir2/fie block[0] 34
+set_inode_field /dir3/foe block[0] 34
+q
+EOF
+
+E2FSCK_TIME=200704102100
+export E2FSCK_TIME
+
+. $cmd_dir/run_e2fsck
+
+rm -f $TEST_DATA
+
+unset E2FSCK_TIME TEST_DATA