xfs_repair phase 3 - more fixes

Resolves: RHEL-54342

Signed-off-by: Pavel Reichl <preichl@redhat.com>
This commit is contained in:
Pavel Reichl 2025-05-16 11:37:49 +02:00
parent a3e908ee7f
commit 0d2427c934
3 changed files with 129 additions and 1 deletions

View File

@ -0,0 +1,63 @@
From 454fab69c484c24d8fb76ac3676553a54af381f7 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Tue, 15 Apr 2025 13:09:23 -0500
Subject: [PATCH] xfs_repair: Bump link count if longform_dir2_rebuild yields
shortform dir
If longform_dir2_rebuild() has so few entries in *hashtab that it results
in a short form directory, bump the link count manually as shortform
directories have no explicit "." entry.
Without this, repair will end with i.e.:
resetting inode 131 nlinks from 2 to 1
in this case, because it thinks this directory inode only has 1 link
discovered, and then a 2nd repair will fix it:
resetting inode 131 nlinks from 1 to 2
because shortform_dir2_entry_check() explicitly adds the extra ref when
the (newly-created)shortform directory is checked:
/*
* no '.' entry in shortform dirs, just bump up ref count by 1
* '..' was already (or will be) accounted for and checked when
* the directory is reached or will be taken care of when the
* directory is moved to orphanage.
*/
add_inode_ref(current_irec, current_ino_offset);
Avoid this by adding the extra ref if we convert from longform to
shortform.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
[aalbersh drop SoB with user.mail as name]
Reviewed-by: Bill O'Donnell <bodonnel@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
repair/phase6.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/repair/phase6.c b/repair/phase6.c
index dbc090a5..8804278a 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -1392,6 +1392,13 @@ _("name create failed in ino %" PRIu64 " (%d)\n"), ino, error);
_("name create failed (%d) during rebuild\n"), error);
}
+ /*
+ * If we added too few entries to retain longform, add the extra
+ * ref for . as this is now a shortform directory.
+ */
+ if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL)
+ add_inode_ref(irec, ino_offset);
+
return;
out_bmap_cancel:
--
2.49.0

View File

@ -0,0 +1,58 @@
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

View File

@ -1,7 +1,7 @@
Summary: Utilities for managing the XFS filesystem
Name: xfsprogs
Version: 6.4.0
Release: 6%{?dist}
Release: 7%{?dist}
License: GPL+ and LGPLv2+
URL: https://xfs.wiki.kernel.org
Source0: http://kernel.org/pub/linux/utils/fs/xfs/xfsprogs/%{name}-%{version}.tar.xz
@ -40,6 +40,8 @@ Patch13: xfsprogs-6.5.0-xfs.8-xfs-fix-bounds-check-in-xfs_defer_agfl_block.patch
# v6.9.0-270-g5a43a004: This patch is taken from the `for-next` branch.
Patch14: xfsprogs-for-next-xfs_repair-allow-symlinks-with-short-remote-targets.patch
Patch15: xfsprogs-6.14.0-xfs_repair-handling-a-block-with-bad-crc-bad-uuid-an.patch
Patch16: xfsprogs-for-next-xfs_repair-Bump-link-count-if-longform_dir2_rebuild-.patch
Patch17: xfsprogs-for-next-xfs_repair-phase6-scan-longform-entries-before-heade.patch
%description
A set of commands to use the XFS filesystem, including mkfs.xfs.
@ -152,6 +154,11 @@ install -m 0644 %{SOURCE3} %{buildroot}%{mkfsdir}
%{_libdir}/*.so
%changelog
* Tue May 13 2025 Pavel Reichl <preichl@redhat.com> - 6.4.0-7
- xfs unrepairable filesystem if directory block not junked in phase 3 - more
- fixes
- Related: RHEL-54342
* Tue May 06 2025 Pavel Reichl <preichl@redhat.com> - 6.4.0-6
- xfs unrepairable filesystem if directory block not junked in phase 3
- Related: RHEL-54342