59 lines
1.9 KiB
Diff
59 lines
1.9 KiB
Diff
From 140fd5b163577bd99e07adcdea7e08a99bccbccd Mon Sep 17 00:00:00 2001
|
|
From: Bill O'Donnell <bodonnel@redhat.com>
|
|
Date: Tue, 15 Apr 2025 13:48:49 -0500
|
|
Subject: [PATCH] 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 <sandeen@sandeen.net>
|
|
Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
|
|
[aalbersh updated changelog as suggested by Eric Sandeen]
|
|
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
|
|
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
|
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
|
---
|
|
repair/phase6.c | 8 +++++---
|
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/repair/phase6.c b/repair/phase6.c
|
|
index 8804278a..a67cc0ab 100644
|
|
--- a/repair/phase6.c
|
|
+++ b/repair/phase6.c
|
|
@@ -2326,7 +2326,11 @@
|
|
continue;
|
|
}
|
|
|
|
- /* check v5 metadata */
|
|
+ longform_dir2_entry_check_data(mp, ip, num_illegal, need_dot,
|
|
+ irec, ino_offset, bp, hashtab,
|
|
+ &freetab, da_bno, isblock);
|
|
+
|
|
+ /* check v5 metadata */
|
|
if (xfs_has_crc(mp)) {
|
|
error = check_dir3_header(mp, bp, ino);
|
|
if (error) {
|
|
@@ -2340,9 +2344,6 @@
|
|
}
|
|
}
|
|
|
|
- longform_dir2_entry_check_data(mp, ip, num_illegal, need_dot,
|
|
- irec, ino_offset, bp, hashtab,
|
|
- &freetab, da_bno, isblock);
|
|
if (isblock)
|
|
break;
|
|
|
|
--
|
|
2.49.0
|