summaryrefslogtreecommitdiff
path: root/e2fsck/pass3.c
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 /e2fsck/pass3.c
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>
Diffstat (limited to 'e2fsck/pass3.c')
-rw-r--r--e2fsck/pass3.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index cedaaf5a..d6b8c8b4 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;