mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
xfs: scrub the realtime group superblock
Enable scrubbing of realtime group superblocks. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
7333c948c2
commit
3f1bdf50ab
@ -191,6 +191,7 @@ xfs-y += $(addprefix scrub/, \
|
||||
xfs-$(CONFIG_XFS_ONLINE_SCRUB_STATS) += scrub/stats.o
|
||||
|
||||
xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \
|
||||
rgsuper.o \
|
||||
rtbitmap.o \
|
||||
rtsummary.o \
|
||||
)
|
||||
|
@ -736,9 +736,10 @@ struct xfs_scrub_metadata {
|
||||
#define XFS_SCRUB_TYPE_HEALTHY 27 /* everything checked out ok */
|
||||
#define XFS_SCRUB_TYPE_DIRTREE 28 /* directory tree structure */
|
||||
#define XFS_SCRUB_TYPE_METAPATH 29 /* metadata directory tree paths */
|
||||
#define XFS_SCRUB_TYPE_RGSUPER 30 /* realtime superblock */
|
||||
|
||||
/* Number of scrub subcommands. */
|
||||
#define XFS_SCRUB_TYPE_NR 30
|
||||
#define XFS_SCRUB_TYPE_NR 31
|
||||
|
||||
/*
|
||||
* This special type code only applies to the vectored scrub implementation.
|
||||
|
@ -79,9 +79,11 @@ int xchk_setup_metapath(struct xfs_scrub *sc);
|
||||
#ifdef CONFIG_XFS_RT
|
||||
int xchk_setup_rtbitmap(struct xfs_scrub *sc);
|
||||
int xchk_setup_rtsummary(struct xfs_scrub *sc);
|
||||
int xchk_setup_rgsuperblock(struct xfs_scrub *sc);
|
||||
#else
|
||||
# define xchk_setup_rtbitmap xchk_setup_nothing
|
||||
# define xchk_setup_rtsummary xchk_setup_nothing
|
||||
# define xchk_setup_rgsuperblock xchk_setup_nothing
|
||||
#endif
|
||||
#ifdef CONFIG_XFS_QUOTA
|
||||
int xchk_ino_dqattach(struct xfs_scrub *sc);
|
||||
|
@ -111,6 +111,7 @@ static const struct xchk_health_map type_to_health_flag[XFS_SCRUB_TYPE_NR] = {
|
||||
[XFS_SCRUB_TYPE_NLINKS] = { XHG_FS, XFS_SICK_FS_NLINKS },
|
||||
[XFS_SCRUB_TYPE_DIRTREE] = { XHG_INO, XFS_SICK_INO_DIRTREE },
|
||||
[XFS_SCRUB_TYPE_METAPATH] = { XHG_FS, XFS_SICK_FS_METAPATH },
|
||||
[XFS_SCRUB_TYPE_RGSUPER] = { XHG_RTGROUP, XFS_SICK_RG_SUPER },
|
||||
};
|
||||
|
||||
/* Return the health status mask for this scrub type. */
|
||||
|
68
fs/xfs/scrub/rgsuper.c
Normal file
68
fs/xfs/scrub/rgsuper.c
Normal file
@ -0,0 +1,68 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2022-2024 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_rtgroup.h"
|
||||
#include "scrub/scrub.h"
|
||||
#include "scrub/common.h"
|
||||
|
||||
/* Set us up with a transaction and an empty context. */
|
||||
int
|
||||
xchk_setup_rgsuperblock(
|
||||
struct xfs_scrub *sc)
|
||||
{
|
||||
return xchk_trans_alloc(sc, 0);
|
||||
}
|
||||
|
||||
/* Cross-reference with the other rt metadata. */
|
||||
STATIC void
|
||||
xchk_rgsuperblock_xref(
|
||||
struct xfs_scrub *sc)
|
||||
{
|
||||
if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
|
||||
return;
|
||||
|
||||
xchk_xref_is_used_rt_space(sc, xfs_rgbno_to_rtb(sc->sr.rtg, 0), 1);
|
||||
}
|
||||
|
||||
int
|
||||
xchk_rgsuperblock(
|
||||
struct xfs_scrub *sc)
|
||||
{
|
||||
xfs_rgnumber_t rgno = sc->sm->sm_agno;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Only rtgroup 0 has a superblock. We may someday want to use higher
|
||||
* rgno for other functions, similar to what we do with the primary
|
||||
* super scrub function.
|
||||
*/
|
||||
if (rgno != 0)
|
||||
return -ENOENT;
|
||||
|
||||
/*
|
||||
* Grab an active reference to the rtgroup structure. If we can't get
|
||||
* it, we're racing with something that's tearing down the group, so
|
||||
* signal that the group no longer exists. Take the rtbitmap in shared
|
||||
* mode so that the group can't change while we're doing things.
|
||||
*/
|
||||
error = xchk_rtgroup_init_existing(sc, rgno, &sc->sr);
|
||||
if (!xchk_xref_process_error(sc, 0, 0, &error))
|
||||
return error;
|
||||
|
||||
xchk_rtgroup_lock(&sc->sr, XFS_RTGLOCK_BITMAP_SHARED);
|
||||
|
||||
/*
|
||||
* Since we already validated the rt superblock at mount time, we don't
|
||||
* need to check its contents again. All we need is to cross-reference.
|
||||
*/
|
||||
xchk_rgsuperblock_xref(sc);
|
||||
return 0;
|
||||
}
|
@ -451,6 +451,13 @@ static const struct xchk_meta_ops meta_scrub_ops[] = {
|
||||
.has = xfs_has_metadir,
|
||||
.repair = xrep_metapath,
|
||||
},
|
||||
[XFS_SCRUB_TYPE_RGSUPER] = { /* realtime group superblock */
|
||||
.type = ST_RTGROUP,
|
||||
.setup = xchk_setup_rgsuperblock,
|
||||
.scrub = xchk_rgsuperblock,
|
||||
.has = xfs_has_rtsb,
|
||||
.repair = xrep_notsupported,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -273,9 +273,11 @@ int xchk_metapath(struct xfs_scrub *sc);
|
||||
#ifdef CONFIG_XFS_RT
|
||||
int xchk_rtbitmap(struct xfs_scrub *sc);
|
||||
int xchk_rtsummary(struct xfs_scrub *sc);
|
||||
int xchk_rgsuperblock(struct xfs_scrub *sc);
|
||||
#else
|
||||
# define xchk_rtbitmap xchk_nothing
|
||||
# define xchk_rtsummary xchk_nothing
|
||||
# define xchk_rgsuperblock xchk_nothing
|
||||
#endif
|
||||
#ifdef CONFIG_XFS_QUOTA
|
||||
int xchk_quota(struct xfs_scrub *sc);
|
||||
|
@ -81,6 +81,7 @@ static const char *name_map[XFS_SCRUB_TYPE_NR] = {
|
||||
[XFS_SCRUB_TYPE_NLINKS] = "nlinks",
|
||||
[XFS_SCRUB_TYPE_DIRTREE] = "dirtree",
|
||||
[XFS_SCRUB_TYPE_METAPATH] = "metapath",
|
||||
[XFS_SCRUB_TYPE_RGSUPER] = "rgsuper",
|
||||
};
|
||||
|
||||
/* Format the scrub stats into a text buffer, similar to pcp style. */
|
||||
|
@ -71,6 +71,7 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_HEALTHY);
|
||||
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_DIRTREE);
|
||||
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BARRIER);
|
||||
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_METAPATH);
|
||||
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RGSUPER);
|
||||
|
||||
#define XFS_SCRUB_TYPE_STRINGS \
|
||||
{ XFS_SCRUB_TYPE_PROBE, "probe" }, \
|
||||
@ -103,7 +104,8 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_METAPATH);
|
||||
{ XFS_SCRUB_TYPE_HEALTHY, "healthy" }, \
|
||||
{ XFS_SCRUB_TYPE_DIRTREE, "dirtree" }, \
|
||||
{ XFS_SCRUB_TYPE_BARRIER, "barrier" }, \
|
||||
{ XFS_SCRUB_TYPE_METAPATH, "metapath" }
|
||||
{ XFS_SCRUB_TYPE_METAPATH, "metapath" }, \
|
||||
{ XFS_SCRUB_TYPE_RGSUPER, "rgsuper" }
|
||||
|
||||
#define XFS_SCRUB_FLAG_STRINGS \
|
||||
{ XFS_SCRUB_IFLAG_REPAIR, "repair" }, \
|
||||
|
Loading…
Reference in New Issue
Block a user