From: Darrick J. Wong <djwong@xxxxxxxxxx> 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@xxxxxxxxxx> --- fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_rtgroup.c | 2 +- fs/xfs/libxfs/xfs_rtgroup.h | 3 +++ fs/xfs/scrub/repair.h | 3 +++ fs/xfs/scrub/rgsuper_repair.c | 48 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/scrub.c | 2 +- 6 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 fs/xfs/scrub/rgsuper_repair.c diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index a02fb09fed64..4bf6d663272b 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -217,6 +217,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 c6461acd1112..292e252efae3 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -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 */ 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@xxxxxxxxxx> + */ +#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, }, };