summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-08-18 14:56:50 -0700
committerDarrick J. Wong <djwong@kernel.org>2022-11-09 19:07:59 -0800
commita77db85b442f185dc3dcb5290c905266b449ee3c (patch)
treecd9d283e9f07420231726f7fbcda095390013c71
parente643a1a066faa419cf66e26e563ed632d9095d85 (diff)
xfs: repair secondary realtime group superblocks
Repair secondary realtime group superblocks. They're not critical for anything, but some consistency would be a good idea. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/libxfs/xfs_rtgroup.c2
-rw-r--r--fs/xfs/libxfs/xfs_rtgroup.h3
-rw-r--r--fs/xfs/scrub/repair.h3
-rw-r--r--fs/xfs/scrub/rgsuper_repair.c48
-rw-r--r--fs/xfs/scrub/scrub.c2
6 files changed, 57 insertions, 2 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 5a6772762e8f..36c6351d17a1 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -214,6 +214,7 @@ xfs-y += $(addprefix scrub/, \
)
xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \
+ rgsuper_repair.o \
rtbitmap_repair.o \
rtsummary_repair.o \
)
diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c
index a428dff81888..4d9e2c0f2fd3 100644
--- a/fs/xfs/libxfs/xfs_rtgroup.c
+++ b/fs/xfs/libxfs/xfs_rtgroup.c
@@ -384,7 +384,7 @@ xfs_rtgroup_log_super(
}
/* Initialize a secondary realtime superblock. */
-static int
+int
xfs_rtgroup_init_secondary_super(
struct xfs_mount *mp,
xfs_rgnumber_t rgno,
diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h
index 1fec49c496d4..3c9572677f79 100644
--- a/fs/xfs/libxfs/xfs_rtgroup.h
+++ b/fs/xfs/libxfs/xfs_rtgroup.h
@@ -210,6 +210,8 @@ void xfs_rtgroup_update_super(struct xfs_buf *rtsb_bp,
const struct xfs_buf *sb_bp);
void xfs_rtgroup_log_super(struct xfs_trans *tp, const struct xfs_buf *sb_bp);
int xfs_rtgroup_update_secondary_sbs(struct xfs_mount *mp);
+int xfs_rtgroup_init_secondary_super(struct xfs_mount *mp, xfs_rgnumber_t rgno,
+ struct xfs_buf **bpp);
/* Lock the rt bitmap inode in exclusive mode */
#define XFS_RTGLOCK_BITMAP (1U << 0)
@@ -230,6 +232,7 @@ int xfs_rtgroup_get_geometry(struct xfs_rtgroup *rtg,
# define xfs_rtgroup_update_super(bp, sb_bp) ((void)0)
# define xfs_rtgroup_log_super(tp, sb_bp) ((void)0)
# define xfs_rtgroup_update_secondary_sbs(mp) (0)
+# define xfs_rtgroup_init_secondary_super(mp, rgno, bpp) (-EOPNOTSUPP)
# define xfs_rtgroup_lock(tp, rtg, gf) ((void)0)
# define xfs_rtgroup_unlock(rtg, gf) ((void)0)
# define xfs_rtgroup_get_geometry(rtg, rgeo) (-EOPNOTSUPP)
diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h
index 753ae12b98e1..2322a8b31c7c 100644
--- a/fs/xfs/scrub/repair.h
+++ b/fs/xfs/scrub/repair.h
@@ -128,9 +128,11 @@ int xrep_symlink(struct xfs_scrub *sc);
#ifdef CONFIG_XFS_RT
int xrep_rtbitmap(struct xfs_scrub *sc);
int xrep_rtsummary(struct xfs_scrub *sc);
+int xrep_rgsuperblock(struct xfs_scrub *sc);
#else
# define xrep_rtbitmap xrep_notsupported
# define xrep_rtsummary xrep_notsupported
+# define xrep_rgsuperblock xrep_notsupported
#endif /* CONFIG_XFS_RT */
#ifdef CONFIG_XFS_QUOTA
@@ -243,6 +245,7 @@ static inline int xrep_setup_symlink(struct xfs_scrub *sc, unsigned int *x)
#define xrep_directory xrep_notsupported
#define xrep_parent xrep_notsupported
#define xrep_symlink xrep_notsupported
+#define xrep_rgsuperblock xrep_notsupported
#endif /* CONFIG_XFS_ONLINE_REPAIR */
diff --git a/fs/xfs/scrub/rgsuper_repair.c b/fs/xfs/scrub/rgsuper_repair.c
new file mode 100644
index 000000000000..9dc379c593ba
--- /dev/null
+++ b/fs/xfs/scrub/rgsuper_repair.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2022 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "xfs.h"
+#include "xfs_fs.h"
+#include "xfs_shared.h"
+#include "xfs_format.h"
+#include "xfs_trans_resv.h"
+#include "xfs_mount.h"
+#include "xfs_defer.h"
+#include "xfs_btree.h"
+#include "xfs_inode.h"
+#include "xfs_bit.h"
+#include "xfs_log_format.h"
+#include "xfs_trans.h"
+#include "xfs_rtgroup.h"
+#include "xfs_sb.h"
+#include "scrub/scrub.h"
+#include "scrub/repair.h"
+
+int
+xrep_rgsuperblock(
+ struct xfs_scrub *sc)
+{
+ struct xfs_buf *bp;
+ int error;
+
+ /*
+ * If this is the primary rtgroup superblock, log a superblock update
+ * to force both to disk.
+ */
+ if (sc->sr.rtg->rtg_rgno == 0) {
+ xfs_log_sb(sc->tp);
+ return 0;
+ }
+
+ /* Otherwise just write a new secondary to disk directly. */
+ error = xfs_rtgroup_init_secondary_super(sc->mp, sc->sr.rtg->rtg_rgno,
+ &bp);
+ if (error)
+ return error;
+
+ error = xfs_bwrite(bp);
+ xfs_buf_relse(bp);
+ return error;
+}
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 6c54f00b516c..5e07150e8f14 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -414,7 +414,7 @@ static const struct xchk_meta_ops meta_scrub_ops[] = {
.setup = xchk_setup_rgsuperblock,
.scrub = xchk_rgsuperblock,
.has = xfs_has_rtgroups,
- .repair = xrep_notsupported,
+ .repair = xrep_rgsuperblock,
},
};