]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2fsck: fix bad htree checksums in preen mode
authorTheodore Ts'o <tytso@mit.edu>
Fri, 17 Mar 2023 02:57:10 +0000 (22:57 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 17 Mar 2023 03:35:58 +0000 (23:35 -0400)
We attempt to fix directories which have a bad/corrupted htree index
node by completely rebuilding the directory htree nodes.  Since this
is a very safe thing to do and has no risk of losing directory
entries, we've enabled this for preen mode.  Unfortunately, subsequent
index nodes look like empty directory entries that fill the entire
block --- without a checksum at the end of the directory.  So these
nodes will be treated as a completely corrupted directory block, and
this will *not* be fixed while in preen mode.

So add code to treat an empty directory entry which covers the entire
block as valid if the directory is already on the list of inodes to be
rebuilt.

Addresses-Gooogle-Bug: 178607853
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/pass2.c

index 28736094355e5502b04a96baa4af4cb2b0f9e444..2700e3409d1d4e1d1dbdb268183f9ab0d75137e6 100644 (file)
@@ -1341,7 +1341,18 @@ skip_checksum:
                            (rec_len < min_dir_len) ||
                            ((rec_len % 4) != 0) ||
                            ((ext2fs_dir_rec_len(ext2fs_dirent_name_len(dirent),
-                                                extended)) > rec_len)) {
+                                                extended)) > rec_len))
+                               problem = PR_2_DIR_CORRUPTED;
+                       if (problem) {
+                               if ((offset == 0) &&
+                                   (rec_len == fs->blocksize) &&
+                                   (dirent->inode == 0) &&
+                                   e2fsck_dir_will_be_rehashed(ctx, ino)) {
+                                       problem = 0;
+                                       max_block_size = fs->blocksize;
+                               }
+                       }
+                       if (problem) {
                                if (fix_problem(ctx, PR_2_DIR_CORRUPTED,
                                                &cd->pctx)) {
 #ifdef WORDS_BIGENDIAN
@@ -1573,7 +1584,8 @@ skip_checksum:
                 */
                if (!(ctx->flags & E2F_FLAG_RESTART_LATER) &&
                    !(ext2fs_test_inode_bitmap2(ctx->inode_used_map,
-                                               dirent->inode)))
+                                               dirent->inode))
+                       )
                        problem = PR_2_UNUSED_INODE;
 
                if (problem) {