xfs unrepairable if dir block not junked in ph3
xfs unrepairable filesystem if directory block not junked in phase 3 Resolves: RHEL-89682 Signed-off-by: Pavel Reichl <preichl@redhat.com>
This commit is contained in:
parent
b225f5212e
commit
ec9e661736
@ -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
|
||||
|
||||
@ -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
|
||||
@@ -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;
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
From 8cd85addd72f1f6e569bd286f6a44dfce90355f1 Mon Sep 17 00:00:00 2001
|
||||
From: Bill O'Donnell <bodonnel@redhat.com>
|
||||
Date: Fri, 21 Mar 2025 17:05:35 -0500
|
||||
Subject: [PATCH] xfs_repair: handling a block with bad crc, bad uuid, and bad
|
||||
magic number needs fixing
|
||||
|
||||
In certain cases, if a block is so messed up that crc, uuid and magic
|
||||
number are all bad, we need to not only detect in phase3 but fix it
|
||||
properly in phase6. In the current code, the mechanism doesn't work
|
||||
in that it only pays attention to one of the parameters.
|
||||
|
||||
Note: in this case, the nlink inode link count drops to 1, but
|
||||
re-running xfs_repair fixes it back to 2. This is a side effect that
|
||||
should probably be handled in update_inode_nlinks() with separate patch.
|
||||
Regardless, running xfs_repair twice, with this patch applied
|
||||
fixes the issue. Recognize that this patch is a fix for xfs v5.
|
||||
|
||||
Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
|
||||
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
|
||||
|
||||
v2: remove superfluous needmagic logic
|
||||
v3: clarify the description
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
---
|
||||
repair/phase6.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/repair/phase6.c b/repair/phase6.c
|
||||
index 44b9bfc3..dbc090a5 100644
|
||||
--- a/repair/phase6.c
|
||||
+++ b/repair/phase6.c
|
||||
@@ -2378,7 +2378,6 @@ longform_dir2_entry_check(
|
||||
da_bno = (xfs_dablk_t)next_da_bno) {
|
||||
const struct xfs_buf_ops *ops;
|
||||
int error;
|
||||
- struct xfs_dir2_data_hdr *d;
|
||||
|
||||
next_da_bno = da_bno + mp->m_dir_geo->fsbcount - 1;
|
||||
if (bmap_next_offset(ip, &next_da_bno)) {
|
||||
@@ -2426,9 +2425,7 @@ longform_dir2_entry_check(
|
||||
}
|
||||
|
||||
/* check v5 metadata */
|
||||
- d = bp->b_addr;
|
||||
- if (be32_to_cpu(d->magic) == XFS_DIR3_BLOCK_MAGIC ||
|
||||
- be32_to_cpu(d->magic) == XFS_DIR3_DATA_MAGIC) {
|
||||
+ if (xfs_has_crc(mp)) {
|
||||
error = check_dir3_header(mp, bp, ino);
|
||||
if (error) {
|
||||
fixit++;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
Summary: Utilities for managing the XFS filesystem
|
||||
Name: xfsprogs
|
||||
Version: 6.11.0
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
License: GPL-1.0-or-later AND LGPL-2.1-or-later
|
||||
URL: https://xfs.wiki.kernel.org
|
||||
Source0: http://kernel.org/pub/linux/utils/fs/xfs/xfsprogs/%{name}-%{version}.tar.xz
|
||||
@ -30,6 +30,10 @@ Provides: /usr/sbin/fsck.xfs
|
||||
Provides: /usr/sbin/mkfs.xfs
|
||||
%endif
|
||||
|
||||
Patch0: v6.14-xfs_repair-handling-a-block-with-bad-crc-bad-uuid-an.patch
|
||||
Patch1: for-next-xfs_repair-Bump-link-count-if-longform_dir2_rebuild-.patch
|
||||
Patch2: for-next-xfs_repair-phase6-scan-longform-entries-before-heade.patch
|
||||
|
||||
%description
|
||||
A set of commands to use the XFS filesystem, including mkfs.xfs.
|
||||
|
||||
@ -140,6 +144,10 @@ rm -rf $RPM_BUILD_ROOT/%{_datadir}/doc/xfsprogs/
|
||||
%{_libdir}/*.so
|
||||
|
||||
%changelog
|
||||
* Tue May 20 2025 Pavel Reichl <preichl@redhat.com> - 6.11.0-2
|
||||
- xfs unrepairable filesystem if directory block not junked in phase 3
|
||||
- Related: RHEL-89682
|
||||
|
||||
* Sat Nov 16 2024 Pavel Reichl <preichl@redhat.com> - 6.11.0-1
|
||||
- Update to the latest upstream version
|
||||
- Related: rhbz#2319902
|
||||
|
||||
Loading…
Reference in New Issue
Block a user