]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2fsck: no parent lookup in disconnected dir
authorAndreas Dilger <adilger@whamcloud.com>
Mon, 13 Dec 2021 06:35:30 +0000 (23:35 -0700)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 3 May 2022 03:40:10 +0000 (23:40 -0400)
Don't call into ext2fs_get_pathname() to do a name lookup for a
disconnected directory, since the directory block traversal in
pass1 has already scanned all of the leaf blocks and never finds
the entry, always printing "???".  If the name entry had been
found earlier, the directory would not be disconnected in pass3.

Instead, lookup ".." and print the parent name in the prompt, and
then do not search for the current directory name at all.  This
avoids a useless full directory scan for each disconnected entry,
which can potentially be slow if the parent directory is large.

Separate the recursively looped directory case to a new error code,
since it is a different problem that should use its own descriptive
text, and a proper pathname can be shown in this case.

Lustre-bug-Id: https://jira.whamcloud.com/browse/LU-15330
Change-Id: If17a92689f24f365ca1fbe5c837e7d5f383ebbe5
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
13 files changed:
e2fsck/pass3.c
e2fsck/problem.c
e2fsck/problem.h
tests/f_bad_encryption/expect.1
tests/f_badroot/expect.1
tests/f_encrypted_lpf/expect.1
tests/f_expand/expect.1.gz
tests/f_lpf2/expect.1
tests/f_noroot/expect.1
tests/f_orphan_dotdot_ft/expect.1
tests/f_rebuild_csum_rootdir/expect.1
tests/f_recnect_bad/expect.1
tests/f_resize_inode_meta_bg/expect.1

index cedaaf5a5bb2fd8c528d801cc680c2c6265ae11e..d6b8c8b47da6af6bd04793faaac9be523ad9dd86 100644 (file)
@@ -22,7 +22,7 @@
  * will offer to reconnect it to /lost+found.  While it is chasing
  * parent pointers up the filesystem tree, if pass3 sees a directory
  * twice, then it has detected a filesystem loop, and it will again
- * offer to reconnect the directory to /lost+found in to break the
+ * offer to reconnect the directory to /lost+found in order to break the
  * filesystem loop.
  *
  * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
@@ -304,7 +304,7 @@ static int check_directory(e2fsck_t ctx, ext2_ino_t dir,
                 * If it was marked done already, then we've reached a
                 * parent we've already checked.
                 */
-               if (ext2fs_mark_inode_bitmap2(inode_done_map, ino))
+               if (ext2fs_mark_inode_bitmap2(inode_done_map, ino))
                        break;
 
                if (e2fsck_dir_info_get_parent(ctx, ino, &parent)) {
@@ -319,13 +319,18 @@ static int check_directory(e2fsck_t ctx, ext2_ino_t dir,
                 */
                if (!parent ||
                    (loop_pass &&
-                    (ext2fs_test_inode_bitmap2(inode_loop_detect,
-                                              parent)))) {
+                    ext2fs_test_inode_bitmap2(inode_loop_detect, parent))) {
                        pctx->ino = ino;
-                       if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
-                               if (e2fsck_reconnect_file(ctx, pctx->ino))
+                       if (parent)
+                               pctx->dir = parent;
+                       else
+                               ext2fs_lookup(fs, ino, "..", 2, NULL,
+                                             &pctx->dir);
+                       if (fix_problem(ctx, !parent ? PR_3_UNCONNECTED_DIR :
+                                                      PR_3_LOOPED_DIR, pctx)) {
+                               if (e2fsck_reconnect_file(ctx, pctx->ino)) {
                                        ext2fs_unmark_valid(fs);
-                               else {
+                               else {
                                        fix_dotdot(ctx, pctx->ino,
                                                   ctx->lost_and_found);
                                        parent = ctx->lost_and_found;
index 2d02468c83182a949fde340e22c78749044400b9..46a74273e91f25be48866ccdbc8a098c0f64a8a3 100644 (file)
@@ -1852,7 +1852,7 @@ static struct e2fsck_problem problem_table[] = {
        /* Unconnected directory inode */
        { PR_3_UNCONNECTED_DIR,
          /* xgettext:no-c-format */
-         N_("Unconnected @d @i %i (%p)\n"),
+         N_("Unconnected @d @i %i (was in %q)\n"),
          PROMPT_CONNECT, 0, 0, 0, 0 },
 
        /* /lost+found not found */
@@ -1989,6 +1989,12 @@ static struct e2fsck_problem problem_table[] = {
          N_("/@l is encrypted\n"),
          PROMPT_CLEAR, 0, 0, 0, 0 },
 
+       /* Recursively looped directory inode */
+       { PR_3_LOOPED_DIR,
+         /* xgettext:no-c-format */
+         N_("Recursively looped @d @i %i (%p)\n"),
+         PROMPT_CONNECT, 0, 0, 0, 0 },
+
        /* Pass 3A Directory Optimization       */
 
        /* Pass 3A: Optimizing directories */
index 24cdcf9b90f7821f371d91260faba9f0c4447a80..e86bc889d35ed801dcf84ed53c40b75a6f85e065 100644 (file)
@@ -1132,6 +1132,9 @@ struct problem_context {
 /* Lost+found is encrypted */
 #define PR_3_LPF_ENCRYPTED             0x03001B
 
+/* Recursively looped directory inode */
+#define PR_3_LOOPED_DIR                        0x03001D
+
 /*
  * Pass 3a --- rehashing directories
  */
index d743e66f74347ff4ca8366406bda97263c5067c5..702709596190a0286e711d532c1d2eadc889ae41 100644 (file)
@@ -54,13 +54,13 @@ Encrypted entry '\M-ggCeM-/?M-^BM-{(M-^OM-9M-^QQAM-^N=M-c^Mo' in /edir (12) refe
 Clear? yes
 
 Pass 3: Checking directory connectivity
-Unconnected directory inode 18 (/edir/???)
+Unconnected directory inode 18 (was in /edir)
 Connect to /lost+found? yes
 
-Unconnected directory inode 24 (/edir/???)
+Unconnected directory inode 24 (was in /edir)
 Connect to /lost+found? yes
 
-Unconnected directory inode 27 (/edir/???)
+Unconnected directory inode 27 (was in /edir)
 Connect to /lost+found? yes
 
 Pass 4: Checking reference counts
index f9d01e5708d56a871e1bb98a4b5c92f98a3aed4b..ff9242689b637645db5f4edf1d7ad09b0ccccaf9 100644 (file)
@@ -9,7 +9,7 @@ Entry '..' in <2>/<11> (11) has deleted/unused inode 2.  Clear? yes
 Pass 3: Checking directory connectivity
 Root inode not allocated.  Allocate? yes
 
-Unconnected directory inode 11 (...)
+Unconnected directory inode 11 (was in /)
 Connect to /lost+found? yes
 
 /lost+found not found.  Create? yes
index 7e215b7deb7d585fc3339487e76e6f697b251eb7..63ac5f3bf0aaa9cc411c256e0717c311d4c7aebd 100644 (file)
@@ -1,7 +1,7 @@
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
-Unconnected directory inode 12 (/???)
+Unconnected directory inode 12 (was in /)
 Connect to /lost+found? yes
 
 /lost+found is encrypted
@@ -13,7 +13,7 @@ Restarting e2fsck from the beginning...
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
-Unconnected directory inode 11 (/???)
+Unconnected directory inode 11 (was in /)
 Connect to /lost+found? yes
 
 Pass 3A: Optimizing directories
index 1015e155ca93f1aea0edfad09be6e795c0ab1898..81fe7dd67f81dd64100b5fdfe2884fab129ab721 100644 (file)
Binary files a/tests/f_expand/expect.1.gz and b/tests/f_expand/expect.1.gz differ
index 633586cc6730a4aa2b0e12e78d1b7dd8818d253d..ab5d9ba370dee9a592679cae157c1f2c922b0e14 100644 (file)
@@ -1,12 +1,12 @@
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
-Unconnected directory inode 12 (/???)
+Unconnected directory inode 12 (was in /)
 Connect to /lost+found? yes
 
 /lost+found not found.  Create? yes
 
-Unconnected directory inode 13 (/???)
+Unconnected directory inode 13 (was in /)
 Connect to /lost+found? yes
 
 Pass 4: Checking reference counts
index 7bdd7cba98fc100134c6c7835d299ce3476e9ee7..f8f652ec09060fd7b4344bc94b9def0ce1130185 100644 (file)
@@ -11,12 +11,12 @@ Entry '..' in /foo (12) has deleted/unused inode 2.  Clear? yes
 Pass 3: Checking directory connectivity
 Root inode not allocated.  Allocate? yes
 
-Unconnected directory inode 11 (...)
+Unconnected directory inode 11 (was in /)
 Connect to /lost+found? yes
 
 /lost+found not found.  Create? yes
 
-Unconnected directory inode 12 (...)
+Unconnected directory inode 12 (was in /lost+found)
 Connect to /lost+found? yes
 
 Pass 4: Checking reference counts
index 6a1373f2a03e5a645f2d042c8a533d5cc6226e03..609249584cad50d64268a84d887e5499e9a9f004 100644 (file)
@@ -17,13 +17,13 @@ Entry '..' in <12>/<15> (15) has an incorrect filetype (was 2, should be 6).
 Fix? yes
 
 Pass 3: Checking directory connectivity
-Unconnected directory inode 13 (<12>/<13>)
+Unconnected directory inode 13 (was in <12>)
 Connect to /lost+found? yes
 
-Unconnected directory inode 14 (<12>/<14>)
+Unconnected directory inode 14 (was in <12>)
 Connect to /lost+found? yes
 
-Unconnected directory inode 15 (<12>/<15>)
+Unconnected directory inode 15 (was in <12>)
 Connect to /lost+found? yes
 
 Pass 4: Checking reference counts
index 91e6027df50c7fa308a876e28066a5fc5afd553d..063fb8cc3bee799e80d1de804b7b2ddc087ccd23 100644 (file)
@@ -13,7 +13,7 @@ Pass 3: Checking directory connectivity
 '..' in / (2) is <The NULL inode> (0), should be / (2).
 Fix? yes
 
-Unconnected directory inode 11 (/???)
+Unconnected directory inode 11 (was in /)
 Connect to /lost+found? yes
 
 /lost+found not found.  Create? yes
index 97ffcc52b58ca09ec09a14826064373615ecfc1f..685eedfee22a1de102349d34fd34668e38edcace 100644 (file)
@@ -12,7 +12,7 @@ i_faddr for inode 13 (/test/???) is 12, should be zero.
 Clear? yes
 
 Pass 3: Checking directory connectivity
-Unconnected directory inode 13 (/test/???)
+Unconnected directory inode 13 (was in /test)
 Connect to /lost+found? yes
 
 Pass 4: Checking reference counts
index 769f71aea22b0a5a0eeff6c06cdef62099a8e71f..e248083f8e2b2bf1b6c85f8401d834cd820fb7e1 100644 (file)
@@ -45,7 +45,7 @@ Pass 3: Checking directory connectivity
 '..' in / (2) is <The NULL inode> (0), should be / (2).
 Fix? yes
 
-Unconnected directory inode 11 (/???)
+Unconnected directory inode 11 (was in /)
 Connect to /lost+found? yes
 
 /lost+found not found.  Create? yes