1dc728923Sopenharmony_ciFrom 79a7b5e1f387caf907ec88460cdb39b8364bfb0b Mon Sep 17 00:00:00 2001 2dc728923Sopenharmony_ciFrom: Theodore Ts'o <tytso@mit.edu> 3dc728923Sopenharmony_ciDate: Thu, 16 Mar 2023 22:57:10 -0400 4dc728923Sopenharmony_ciSubject: e2fsck: fix bad htree checksums in preen mode 5dc728923Sopenharmony_ci 6dc728923Sopenharmony_ciWe attempt to fix directories which have a bad/corrupted htree index 7dc728923Sopenharmony_cinode by completely rebuilding the directory htree nodes. Since this 8dc728923Sopenharmony_ciis a very safe thing to do and has no risk of losing directory 9dc728923Sopenharmony_cientries, we've enabled this for preen mode. Unfortunately, subsequent 10dc728923Sopenharmony_ciindex nodes look like empty directory entries that fill the entire 11dc728923Sopenharmony_ciblock --- without a checksum at the end of the directory. So these 12dc728923Sopenharmony_cinodes will be treated as a completely corrupted directory block, and 13dc728923Sopenharmony_cithis will *not* be fixed while in preen mode. 14dc728923Sopenharmony_ci 15dc728923Sopenharmony_ciSo add code to treat an empty directory entry which covers the entire 16dc728923Sopenharmony_ciblock as valid if the directory is already on the list of inodes to be 17dc728923Sopenharmony_cirebuilt. 18dc728923Sopenharmony_ci 19dc728923Sopenharmony_ciAddresses-Gooogle-Bug: 178607853 20dc728923Sopenharmony_ciSigned-off-by: Theodore Ts'o <tytso@mit.edu> 21dc728923Sopenharmony_ci--- 22dc728923Sopenharmony_ci e2fsck/pass2.c | 16 ++++++++++++++-- 23dc728923Sopenharmony_ci 1 file changed, 14 insertions(+), 2 deletions(-) 24dc728923Sopenharmony_ci 25dc728923Sopenharmony_cidiff --git a/e2fsck/pass2.c b/e2fsck/pass2.c 26dc728923Sopenharmony_ciindex 287360943..2700e3409 100644 27dc728923Sopenharmony_ci--- a/e2fsck/pass2.c 28dc728923Sopenharmony_ci+++ b/e2fsck/pass2.c 29dc728923Sopenharmony_ci@@ -1341,7 +1341,18 @@ skip_checksum: 30dc728923Sopenharmony_ci (rec_len < min_dir_len) || 31dc728923Sopenharmony_ci ((rec_len % 4) != 0) || 32dc728923Sopenharmony_ci ((ext2fs_dir_rec_len(ext2fs_dirent_name_len(dirent), 33dc728923Sopenharmony_ci- extended)) > rec_len)) { 34dc728923Sopenharmony_ci+ extended)) > rec_len)) 35dc728923Sopenharmony_ci+ problem = PR_2_DIR_CORRUPTED; 36dc728923Sopenharmony_ci+ if (problem) { 37dc728923Sopenharmony_ci+ if ((offset == 0) && 38dc728923Sopenharmony_ci+ (rec_len == fs->blocksize) && 39dc728923Sopenharmony_ci+ (dirent->inode == 0) && 40dc728923Sopenharmony_ci+ e2fsck_dir_will_be_rehashed(ctx, ino)) { 41dc728923Sopenharmony_ci+ problem = 0; 42dc728923Sopenharmony_ci+ max_block_size = fs->blocksize; 43dc728923Sopenharmony_ci+ } 44dc728923Sopenharmony_ci+ } 45dc728923Sopenharmony_ci+ if (problem) { 46dc728923Sopenharmony_ci if (fix_problem(ctx, PR_2_DIR_CORRUPTED, 47dc728923Sopenharmony_ci &cd->pctx)) { 48dc728923Sopenharmony_ci #ifdef WORDS_BIGENDIAN 49dc728923Sopenharmony_ci@@ -1573,7 +1584,8 @@ skip_checksum: 50dc728923Sopenharmony_ci */ 51dc728923Sopenharmony_ci if (!(ctx->flags & E2F_FLAG_RESTART_LATER) && 52dc728923Sopenharmony_ci !(ext2fs_test_inode_bitmap2(ctx->inode_used_map, 53dc728923Sopenharmony_ci- dirent->inode))) 54dc728923Sopenharmony_ci+ dirent->inode)) 55dc728923Sopenharmony_ci+ ) 56dc728923Sopenharmony_ci problem = PR_2_UNUSED_INODE; 57dc728923Sopenharmony_ci 58dc728923Sopenharmony_ci if (problem) { 59dc728923Sopenharmony_ci-- 60dc728923Sopenharmony_cicgit 61