From 56c8c592ac48c0fc9772153bb7bdf621b1de0ab9 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 31 Mar 2007 19:18:24 -0400 Subject: [PATCH] Fix e2fsck to set the filetype of '..' when connecting a dir, to lost+found If there is an orphaned inode whose '..' entry is pointing at a special file, the filetype of the '..' entry will set to the type of the special file. When the orphaned directory is reconnected to /lost+found, the filetype of the '..' field is not reset to EXT2_FT_DIR, so a second e2fsck is required to repair the filesystem. We address this situation by setting the filetype of '..' when we reconnect the inode to /lost+found. Addresses Lustre Bug: #11645 Signed-off-by: "Theodore Ts'o" --- e2fsck/ChangeLog | 3 ++ e2fsck/pass3.c | 6 ++++ tests/ChangeLog | 6 ++++ tests/f_orphan_dotdot_ft/expect.1 | 56 ++++++++++++++++++++++++++++++++++++++ tests/f_orphan_dotdot_ft/expect.2 | 7 +++++ tests/f_orphan_dotdot_ft/image.gz | Bin 0 -> 590 bytes tests/f_orphan_dotdot_ft/name | 1 + 7 files changed, 79 insertions(+) create mode 100644 tests/f_orphan_dotdot_ft/expect.1 create mode 100644 tests/f_orphan_dotdot_ft/expect.2 create mode 100644 tests/f_orphan_dotdot_ft/image.gz create mode 100644 tests/f_orphan_dotdot_ft/name diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 1ea3b1e..5d1de4f 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,5 +1,8 @@ 2007-03-31 Theodore Tso + * pass3.c (fix_dotdot_proc): Fix the filetype of the '..' entry to + be EXT2_FT_DIR. (Addresses Lustre BZ #11645) + * pass1.c (e2fsck_pass1_check_device_inode): Don't assume that a special device is bogus just because i_blocks is non-zero. The i_blocks field could get adjusted later, and if this diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index 26c0a03..72c4ec4 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -645,6 +645,12 @@ static int fix_dotdot_proc(struct ext2_dir_entry *dirent, fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx); } dirent->inode = fp->parent; + if (fp->ctx->fs->super->s_feature_incompat & + EXT2_FEATURE_INCOMPAT_FILETYPE) + dirent->name_len = (dirent->name_len & 0xFF) | + (EXT2_FT_DIR << 8); + else + dirent->name_len = dirent->name_len & 0xFF; fp->done++; return DIRENT_ABORT | DIRENT_CHANGED; diff --git a/tests/ChangeLog b/tests/ChangeLog index 1ec389b..d771138 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2007-03-31 Theodore Tso + + * f_orphan_dotdot_ft: New test case which checks to see what + happens when an orphaned directory's '..' entry points to + special device. + 2006-11-12 Theodore Tso * f_extents: This test is currently skipped, but we are adding it diff --git a/tests/f_orphan_dotdot_ft/expect.1 b/tests/f_orphan_dotdot_ft/expect.1 new file mode 100644 index 0000000..ac309e8 --- /dev/null +++ b/tests/f_orphan_dotdot_ft/expect.1 @@ -0,0 +1,56 @@ +Pass 1: Checking inodes, blocks, and sizes +Special (device/socket/fifo) inode 12 has non-zero size. Fix? yes + +Inode 12, i_blocks is 2, should be 0. Fix? yes + +Pass 2: Checking directory structure +Entry 'dir' in / (2) has an incorrect filetype (was 2, should be 6). +Fix? yes + +Entry '..' in ??? (13) has an incorrect filetype (was 2, should be 6). +Fix? yes + +Entry '..' in ??? (14) has an incorrect filetype (was 2, should be 6). +Fix? yes + +Entry '..' in ??? (15) has an incorrect filetype (was 2, should be 6). +Fix? yes + +Pass 3: Checking directory connectivity +Unconnected directory inode 13 (???) +Connect to /lost+found? yes + +Unconnected directory inode 14 (???) +Connect to /lost+found? yes + +Unconnected directory inode 15 (???) +Connect to /lost+found? yes + +Pass 4: Checking reference counts +Inode 2 ref count is 4, should be 3. Fix? yes + +Inode 12 ref count is 2, should be 1. Fix? yes + +Inode 13 ref count is 3, should be 2. Fix? yes + +Inode 14 ref count is 3, should be 2. Fix? yes + +Inode 15 ref count is 3, should be 2. Fix? yes + +Pass 5: Checking group summary information +Block bitmap differences: -23 +Fix? yes + +Free blocks count wrong for group #0 (73, counted=74). +Fix? yes + +Free blocks count wrong (73, counted=74). +Fix? yes + +Directories count wrong for group #0 (6, counted=5). +Fix? yes + + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 15/32 files (0.0% non-contiguous), 26/100 blocks +Exit status is 1 diff --git a/tests/f_orphan_dotdot_ft/expect.2 b/tests/f_orphan_dotdot_ft/expect.2 new file mode 100644 index 0000000..fc68e79 --- /dev/null +++ b/tests/f_orphan_dotdot_ft/expect.2 @@ -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: 15/32 files (0.0% non-contiguous), 26/100 blocks +Exit status is 0 diff --git a/tests/f_orphan_dotdot_ft/image.gz b/tests/f_orphan_dotdot_ft/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..cb91a64d0948ce4702187fc393b788e49f29133f GIT binary patch literal 590 zcmb2|=HQrfiO-FRIWspgJ(c0@ozq!Y5+v9j_)O~BcKKRX^eXAy;$3>NC4ntX8h0yL zy)-!a4e7(O>Cb$*JGnd1M0oD~oF})RzMpRPsr2c0 zH>WUXzm_9+&(F`-XEucf0!gGjm(kmxHhV<}A|kEuZ(lSN`1o`-X2n@a@^oebnXYx%>8gXe^@Vve zi~g_vn*J;1zwe6ZW#NC7YuD`;do}H4=>HXAj11p8EaWenJ=(eUsl~k6+Q)WHzF1JR zv-Iz=k5j{bpDHr^_IHNL$4^VM`DETOD&PL~KRf7)eSq*vXNF($7ydW=WB+2m;6LME z{ulKQ|CvET33=