aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Dilger <adilger@whamcloud.com>2021-12-12 23:35:30 -0700
committerTheodore Ts'o <tytso@mit.edu>2022-05-02 23:40:10 -0400
commit6b0e3bd7bd2f2db3c3993c5d91379ad55e60b51e (patch)
treea7baa29733aa15ea204127e5c676f281ecb11886
parentc1bd25333e8986b081b82a8eb8c9173a0c7480af (diff)
downloade2fsprogs-6b0e3bd7bd2f2db3c3993c5d91379ad55e60b51e.tar.gz
e2fsck: no parent lookup in disconnected dir
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>
-rw-r--r--e2fsck/pass3.c19
-rw-r--r--e2fsck/problem.c8
-rw-r--r--e2fsck/problem.h3
-rw-r--r--tests/f_bad_encryption/expect.16
-rw-r--r--tests/f_badroot/expect.12
-rw-r--r--tests/f_encrypted_lpf/expect.14
-rw-r--r--tests/f_expand/expect.1.gzbin13462 -> 13461 bytes
-rw-r--r--tests/f_lpf2/expect.14
-rw-r--r--tests/f_noroot/expect.14
-rw-r--r--tests/f_orphan_dotdot_ft/expect.16
-rw-r--r--tests/f_rebuild_csum_rootdir/expect.12
-rw-r--r--tests/f_recnect_bad/expect.12
-rw-r--r--tests/f_resize_inode_meta_bg/expect.12
13 files changed, 38 insertions, 24 deletions
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index cedaaf5a5..d6b8c8b47 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -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;
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 2d02468c8..46a74273e 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -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 */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 24cdcf9b9..e86bc889d 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -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
*/
diff --git a/tests/f_bad_encryption/expect.1 b/tests/f_bad_encryption/expect.1
index d743e66f7..702709596 100644
--- a/tests/f_bad_encryption/expect.1
+++ b/tests/f_bad_encryption/expect.1
@@ -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
diff --git a/tests/f_badroot/expect.1 b/tests/f_badroot/expect.1
index f9d01e570..ff9242689 100644
--- a/tests/f_badroot/expect.1
+++ b/tests/f_badroot/expect.1
@@ -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
diff --git a/tests/f_encrypted_lpf/expect.1 b/tests/f_encrypted_lpf/expect.1
index 7e215b7de..63ac5f3bf 100644
--- a/tests/f_encrypted_lpf/expect.1
+++ b/tests/f_encrypted_lpf/expect.1
@@ -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
diff --git a/tests/f_expand/expect.1.gz b/tests/f_expand/expect.1.gz
index 1015e155c..81fe7dd67 100644
--- a/tests/f_expand/expect.1.gz
+++ b/tests/f_expand/expect.1.gz
Binary files differ
diff --git a/tests/f_lpf2/expect.1 b/tests/f_lpf2/expect.1
index 633586cc6..ab5d9ba37 100644
--- a/tests/f_lpf2/expect.1
+++ b/tests/f_lpf2/expect.1
@@ -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
diff --git a/tests/f_noroot/expect.1 b/tests/f_noroot/expect.1
index 7bdd7cba9..f8f652ec0 100644
--- a/tests/f_noroot/expect.1
+++ b/tests/f_noroot/expect.1
@@ -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
diff --git a/tests/f_orphan_dotdot_ft/expect.1 b/tests/f_orphan_dotdot_ft/expect.1
index 6a1373f2a..609249584 100644
--- a/tests/f_orphan_dotdot_ft/expect.1
+++ b/tests/f_orphan_dotdot_ft/expect.1
@@ -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
diff --git a/tests/f_rebuild_csum_rootdir/expect.1 b/tests/f_rebuild_csum_rootdir/expect.1
index 91e6027df..063fb8cc3 100644
--- a/tests/f_rebuild_csum_rootdir/expect.1
+++ b/tests/f_rebuild_csum_rootdir/expect.1
@@ -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
diff --git a/tests/f_recnect_bad/expect.1 b/tests/f_recnect_bad/expect.1
index 97ffcc52b..685eedfee 100644
--- a/tests/f_recnect_bad/expect.1
+++ b/tests/f_recnect_bad/expect.1
@@ -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
diff --git a/tests/f_resize_inode_meta_bg/expect.1 b/tests/f_resize_inode_meta_bg/expect.1
index 769f71aea..e248083f8 100644
--- a/tests/f_resize_inode_meta_bg/expect.1
+++ b/tests/f_resize_inode_meta_bg/expect.1
@@ -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