111 lines
4.0 KiB
Diff
111 lines
4.0 KiB
Diff
From fa0f9232bd89e2955ee54e0be4adb6713a00d8b4 Mon Sep 17 00:00:00 2001
|
|
From: "Darrick J. Wong" <djwong@kernel.org>
|
|
Date: Tue, 12 Jul 2022 13:22:33 -0500
|
|
Subject: [PATCH] xfs_repair: always rewrite secondary supers when needsrepair
|
|
is set
|
|
|
|
Dave Chinner complained about xfs_scrub failures coming from xfs/158.
|
|
That test induces xfs_repair to fail while upgrading a filesystem to
|
|
have the inobtcount feature, and then restarts xfs_repair to finish the
|
|
upgrade. When the second xfs_repair run starts, it will find that the
|
|
primary super has NEEDSREPAIR set, along with whatever new feature that
|
|
we were trying to add to the filesystem.
|
|
|
|
From there, repair completes the upgrade in much the same manner as the
|
|
first repair run would have, with one big exception -- it forgets to set
|
|
features_changed to trigger rewriting of the secondary supers at the end
|
|
of repair. This results in discrepancies between the supers:
|
|
|
|
# XFS_REPAIR_FAIL_AFTER_PHASE=2 xfs_repair -c inobtcount=1 /dev/sdf
|
|
Phase 1 - find and verify superblock...
|
|
Phase 2 - using internal log
|
|
- zero log...
|
|
- scan filesystem freespace and inode maps...
|
|
- found root inode chunk
|
|
Adding inode btree counts to filesystem.
|
|
Killed
|
|
# xfs_repair /dev/sdf
|
|
Phase 1 - find and verify superblock...
|
|
Phase 2 - using internal log
|
|
- zero log...
|
|
- scan filesystem freespace and inode maps...
|
|
clearing needsrepair flag and regenerating metadata
|
|
bad inobt block count 0, saw 1
|
|
bad finobt block count 0, saw 1
|
|
bad inobt block count 0, saw 1
|
|
bad finobt block count 0, saw 1
|
|
bad inobt block count 0, saw 1
|
|
bad finobt block count 0, saw 1
|
|
bad inobt block count 0, saw 1
|
|
bad finobt block count 0, saw 1
|
|
- found root inode chunk
|
|
Phase 3 - for each AG...
|
|
- scan and clear agi unlinked lists...
|
|
- process known inodes and perform inode discovery...
|
|
- agno = 0
|
|
- agno = 1
|
|
- agno = 2
|
|
- agno = 3
|
|
- process newly discovered inodes...
|
|
Phase 4 - check for duplicate blocks...
|
|
- setting up duplicate extent list...
|
|
- check for inodes claiming duplicate blocks...
|
|
- agno = 1
|
|
- agno = 2
|
|
- agno = 0
|
|
- agno = 3
|
|
Phase 5 - rebuild AG headers and trees...
|
|
- reset superblock...
|
|
Phase 6 - check inode connectivity...
|
|
- resetting contents of realtime bitmap and summary inodes
|
|
- traversing filesystem ...
|
|
- traversal finished ...
|
|
- moving disconnected inodes to lost+found ...
|
|
Phase 7 - verify and correct link counts...
|
|
done
|
|
# xfs_db -c 'sb 0' -c 'print' -c 'sb 1' -c 'print' /dev/sdf | \
|
|
egrep '(features_ro_compat|features_incompat)'
|
|
features_ro_compat = 0xd
|
|
features_incompat = 0xb
|
|
features_ro_compat = 0x5
|
|
features_incompat = 0xb
|
|
|
|
Curiously, re-running xfs_repair will not trigger any warnings about the
|
|
featureset mismatch between the primary and secondary supers. xfs_scrub
|
|
immediately notices, which is what causes xfs/158 to fail.
|
|
|
|
This discrepancy doesn't happen when the upgrade completes successfully
|
|
in a single repair run, so we need to teach repair to rewrite the
|
|
secondaries at the end of repair any time needsrepair was set.
|
|
|
|
Reported-by: Dave Chinner <david@fromorbit.com>
|
|
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
|
Reviewed-by: Dave Chinner <dchinner@redhat.com>
|
|
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
|
|
---
|
|
repair/agheader.c | 8 ++++++++
|
|
1 file changed, 8 insertions(+)
|
|
|
|
diff --git a/repair/agheader.c b/repair/agheader.c
|
|
index 36da139..e91509d 100644
|
|
--- a/repair/agheader.c
|
|
+++ b/repair/agheader.c
|
|
@@ -552,6 +552,14 @@ secondary_sb_whack(
|
|
else
|
|
do_warn(
|
|
_("would clear needsrepair flag and regenerate metadata\n"));
|
|
+ /*
|
|
+ * If needsrepair is set on the primary super, there's
|
|
+ * a possibility that repair crashed during an upgrade.
|
|
+ * Set features_changed to ensure that the secondary
|
|
+ * supers are rewritten with the new feature bits once
|
|
+ * we've finished the upgrade.
|
|
+ */
|
|
+ features_changed = true;
|
|
} else {
|
|
/*
|
|
* Quietly clear needsrepair on the secondary supers as
|
|
--
|
|
1.8.3.1
|
|
|