diff options
author | Andreas Dilger <adilger@whamcloud.com> | 2021-12-12 23:35:30 -0700 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2022-05-02 23:40:10 -0400 |
commit | 6b0e3bd7bd2f2db3c3993c5d91379ad55e60b51e (patch) | |
tree | a7baa29733aa15ea204127e5c676f281ecb11886 /e2fsck/pass3.c | |
parent | c1bd25333e8986b081b82a8eb8c9173a0c7480af (diff) | |
download | e2fsprogs-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.c | 19 |
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; |