From: Bill O'Donnell Date: Tue, 15 Apr 2025 18:48:49 +0000 (-0500) Subject: xfs_repair: phase6: scan longform entries before header check X-Git-Tag: v6.15.0~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=140fd5b163577bd99e07adcdea7e08a99bccbccd;p=thirdparty%2Fxfsprogs-dev.git xfs_repair: phase6: scan longform entries before header check In longform_dir2_entry_check, if check_dir3_header() fails for v5 metadata, we immediately go to out_fix: and try to rebuild the directory via longform_dir2_rebuild. But because we haven't yet called longform_dir2_entry_check_data, the *hashtab used to rebuild the directory is empty, which results in all existing entries getting moved to lost+found, and an empty rebuilt directory. On top of that, the empty directory is now short form, so its nlinks come out wrong and this requires another repair run to fix. Scan the entries before checking the header, so that we have a decent chance of properly rebuilding the dir if the header is corrupt, rather than orphaning all the entries and moving them to lost+found. Suggested-by: Eric Sandeen Signed-off-by: Bill O'Donnell [aalbersh updated changelog as suggested by Eric Sandeen] Reviewed-by: Eric Sandeen Reviewed-by: Darrick J. Wong --- diff --git a/repair/phase6.c b/repair/phase6.c index 8804278a..a67cc0ab 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -2431,6 +2431,11 @@ longform_dir2_entry_check( continue; } + /* salvage any dirents that look ok */ + longform_dir2_entry_check_data(mp, ip, num_illegal, need_dot, + irec, ino_offset, bp, hashtab, + &freetab, da_bno, fmt == XFS_DIR2_FMT_BLOCK); + /* check v5 metadata */ if (xfs_has_crc(mp)) { error = check_dir3_header(mp, bp, ino); @@ -2445,9 +2450,6 @@ longform_dir2_entry_check( } } - longform_dir2_entry_check_data(mp, ip, num_illegal, need_dot, - irec, ino_offset, bp, hashtab, - &freetab, da_bno, fmt == XFS_DIR2_FMT_BLOCK); if (fmt == XFS_DIR2_FMT_BLOCK) break;