From 918e82a4879dccaf3673871be925a87efc2fbabc Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <djwong@kernel.org>
Date: Fri, 25 Feb 2022 17:42:16 -0500
Subject: [PATCH] xfs_repair: update secondary superblocks after changing
 features

When we add features to an existing filesystem, make sure we update the
secondary superblocks to reflect the new geometry so that if we lose the
primary super in the future, repair will recover correctly.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
 libxfs/libxfs_api_defs.h |  2 ++
 repair/globals.c         |  1 +
 repair/globals.h         |  1 +
 repair/phase2.c          |  2 ++
 repair/xfs_repair.c      | 15 +++++++++++++++
 5 files changed, 21 insertions(+)

diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index b76e638..63628ae 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -195,6 +195,8 @@
 #define xfs_trans_roll			libxfs_trans_roll
 #define xfs_trim_extent			libxfs_trim_extent
 
+#define xfs_update_secondary_sbs	libxfs_update_secondary_sbs
+
 #define xfs_validate_stripe_geometry	libxfs_validate_stripe_geometry
 #define xfs_verify_agbno		libxfs_verify_agbno
 #define xfs_verify_agino		libxfs_verify_agino
diff --git a/repair/globals.c b/repair/globals.c
index 506a4e7..f8d4f1e 100644
--- a/repair/globals.c
+++ b/repair/globals.c
@@ -48,6 +48,7 @@ char	*rt_name;		/* Name of realtime device */
 int	rt_spec;		/* Realtime dev specified as option */
 int	convert_lazy_count;	/* Convert lazy-count mode on/off */
 int	lazy_count;		/* What to set if to if converting */
+bool	features_changed;	/* did we change superblock feature bits? */
 bool	add_inobtcount;		/* add inode btree counts to AGI */
 bool	add_bigtime;		/* add support for timestamps up to 2486 */
 
diff --git a/repair/globals.h b/repair/globals.h
index 929b82b..0f98bd2 100644
--- a/repair/globals.h
+++ b/repair/globals.h
@@ -89,6 +89,7 @@ extern char	*rt_name;		/* Name of realtime device */
 extern int	rt_spec;		/* Realtime dev specified as option */
 extern int	convert_lazy_count;	/* Convert lazy-count mode on/off */
 extern int	lazy_count;		/* What to set if to if converting */
+extern bool	features_changed;	/* did we change superblock feature bits? */
 extern bool	add_inobtcount;		/* add inode btree counts to AGI */
 extern bool	add_bigtime;		/* add support for timestamps up to 2486 */
 
diff --git a/repair/phase2.c b/repair/phase2.c
index 32ffe18..ab53ee0 100644
--- a/repair/phase2.c
+++ b/repair/phase2.c
@@ -216,6 +216,8 @@ upgrade_filesystem(
         }
         if (bp)
                 libxfs_buf_relse(bp);
+
+	features_changed = true;
 }
 
 /*
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index 38406ee..e44aa40 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -1298,6 +1298,21 @@ _("Note - stripe unit (%d) and width (%d) were copied from a backup superblock.\
 	libxfs_buf_relse(sbp);
 
 	/*
+	 * If we upgraded V5 filesystem features, we need to update the
+	 * secondary superblocks to include the new feature bits.  Don't set
+	 * NEEDSREPAIR on the secondaries.
+	 */
+	if (features_changed) {
+		mp->m_sb.sb_features_incompat &=
+				~XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
+		error = -libxfs_update_secondary_sbs(mp);
+		if (error)
+			do_error(_("upgrading features of secondary supers"));
+		mp->m_sb.sb_features_incompat |=
+				XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
+	}
+
+	/*
 	 * Done. Flush all cached buffers and inodes first to ensure all
 	 * verifiers are run (where we discover the max metadata LSN), reformat
 	 * the log if necessary and unmount.
-- 
1.8.3.1

