Whamcloud - gitweb
LU-14710 e2fsck: fix ".." more gracefully if possible
authorAndreas Dilger <adilger@whamcloud.com>
Fri, 28 May 2021 04:57:20 +0000 (22:57 -0600)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 15 Dec 2022 22:48:33 +0000 (15:48 -0700)
If the "." entry is corrupted, it will be reset in check_dot().
It is possible that the ".." entry can be recovered from the
directory block instead of also resetting it immediately.  If
it appears that there is a valid ".." entry in the block, allow
that to be used, and let check_dotdot() verify the dirent itself.

When resetting the "." and ".." entries, use EXT2_FT_DIR as the
file type instead of EXT2_FT_UNKNOWN, to avoid extra problems
later can easily be avoided.

Fixup affected tests using the new "repair-test" script that
updates the expect.[12] files from $test.[12].log for the given
tests and re-runs the test to ensure it now passes.

Change-Id: Ia5e579bcf31a9d9ee260d5640de6dbdb60514823
Signed-off-by: Andreas dilger <adilger@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/43858
Reviewed-by: Artem Blagodarenko <artem.blagodarenko@hpe.com>
e2fsck/pass2.c

index 1f494b4..6ca1e99 100644 (file)
@@ -484,8 +484,8 @@ static int check_dot(e2fsck_t ctx,
        int             status = 0;
        int             created = 0;
        problem_t       problem = 0;
-       int             ftype = EXT2_FT_DIR;
        int             dir_data_error;
+       int             ftype = EXT2_FT_DIR;
 
        if (!dirent->inode)
                problem = PR_2_MISSING_DOT;
@@ -502,7 +502,7 @@ static int check_dot(e2fsck_t ctx,
                if (!ext2fs_has_feature_filetype(ctx->fs->super))
                        ftype = EXT2_FT_UNKNOWN;
                if (fix_problem(ctx, problem, pctx)) {
-                       if (rec_len < 12 && dir_data_error)
+                       if (rec_len < 12)
                                rec_len = dirent->rec_len = 12;
                        dirent->inode = ino;
                        ext2fs_dirent_set_name_len(dirent, 1);
@@ -538,12 +538,6 @@ static int check_dot(e2fsck_t ctx,
                                        ext2fs_dirent_set_name_len(nextdir, 0);
                                        ext2fs_dirent_set_file_type(nextdir,
                                                                    ftype);
-#ifdef WORDS_BIGENDIAN
-                               } else {
-                                       (void) ext2fs_dirent_swab_in2(ctx->fs,
-                                               (char *) nextdir,
-                                               ctx->fs->blocksize - 12, 0);
-#endif
                                }
                                status = 1;
                        }
@@ -564,7 +558,6 @@ static int check_dotdot(e2fsck_t ctx,
        problem_t       problem = 0;
        unsigned int    rec_len;
        int             ftype = EXT2_FT_DIR;
-       int             dir_data_error;
 
        if (!dirent->inode)
                problem = PR_2_MISSING_DOT_DOT;
@@ -575,14 +568,14 @@ static int check_dotdot(e2fsck_t ctx,
        else if (dirent->name[2] != '\0')
                problem = PR_2_DOT_DOT_NULL_TERM;
 
-       dir_data_error = e2fsck_check_dirent_data(ctx, dirent, offset, pctx);
+       e2fsck_check_dirent_data(ctx, dirent, offset, pctx);
 
        (void) ext2fs_get_rec_len(ctx->fs, dirent, &rec_len);
        if (problem) {
                if (!ext2fs_has_feature_filetype(ctx->fs->super))
                        ftype = EXT2_FT_UNKNOWN;
                if (fix_problem(ctx, problem, pctx)) {
-                       if (rec_len < 12 && dir_data_error)
+                       if (rec_len < 12)
                                dirent->rec_len = 12;
                        /*
                         * Note: we don't have the parent inode just