@@ -217,6 +217,7 @@ xfs-y += $(addprefix scrub/, \
)
xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \
+ rgsuper_repair.o \
rtbitmap_repair.o \
rtsummary_repair.o \
)
@@ -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,
@@ -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)
@@ -131,9 +131,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
@@ -248,6 +250,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 */
new file mode 100644
@@ -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;
+}
@@ -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,
},
};