Skip to content

Commit 3f1bdf5

Browse files
author
Darrick J. Wong
committed
xfs: scrub the realtime group superblock
Enable scrubbing of realtime group superblocks. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent 7333c94 commit 3f1bdf5

File tree

9 files changed

+87
-2
lines changed

9 files changed

+87
-2
lines changed

fs/xfs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ xfs-y += $(addprefix scrub/, \
191191
xfs-$(CONFIG_XFS_ONLINE_SCRUB_STATS) += scrub/stats.o
192192

193193
xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \
194+
rgsuper.o \
194195
rtbitmap.o \
195196
rtsummary.o \
196197
)

fs/xfs/libxfs/xfs_fs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,9 +736,10 @@ struct xfs_scrub_metadata {
736736
#define XFS_SCRUB_TYPE_HEALTHY 27 /* everything checked out ok */
737737
#define XFS_SCRUB_TYPE_DIRTREE 28 /* directory tree structure */
738738
#define XFS_SCRUB_TYPE_METAPATH 29 /* metadata directory tree paths */
739+
#define XFS_SCRUB_TYPE_RGSUPER 30 /* realtime superblock */
739740

740741
/* Number of scrub subcommands. */
741-
#define XFS_SCRUB_TYPE_NR 30
742+
#define XFS_SCRUB_TYPE_NR 31
742743

743744
/*
744745
* This special type code only applies to the vectored scrub implementation.

fs/xfs/scrub/common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,11 @@ int xchk_setup_metapath(struct xfs_scrub *sc);
7979
#ifdef CONFIG_XFS_RT
8080
int xchk_setup_rtbitmap(struct xfs_scrub *sc);
8181
int xchk_setup_rtsummary(struct xfs_scrub *sc);
82+
int xchk_setup_rgsuperblock(struct xfs_scrub *sc);
8283
#else
8384
# define xchk_setup_rtbitmap xchk_setup_nothing
8485
# define xchk_setup_rtsummary xchk_setup_nothing
86+
# define xchk_setup_rgsuperblock xchk_setup_nothing
8587
#endif
8688
#ifdef CONFIG_XFS_QUOTA
8789
int xchk_ino_dqattach(struct xfs_scrub *sc);

fs/xfs/scrub/health.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ static const struct xchk_health_map type_to_health_flag[XFS_SCRUB_TYPE_NR] = {
111111
[XFS_SCRUB_TYPE_NLINKS] = { XHG_FS, XFS_SICK_FS_NLINKS },
112112
[XFS_SCRUB_TYPE_DIRTREE] = { XHG_INO, XFS_SICK_INO_DIRTREE },
113113
[XFS_SCRUB_TYPE_METAPATH] = { XHG_FS, XFS_SICK_FS_METAPATH },
114+
[XFS_SCRUB_TYPE_RGSUPER] = { XHG_RTGROUP, XFS_SICK_RG_SUPER },
114115
};
115116

116117
/* Return the health status mask for this scrub type. */

fs/xfs/scrub/rgsuper.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* Copyright (c) 2022-2024 Oracle. All Rights Reserved.
4+
* Author: Darrick J. Wong <[email protected]>
5+
*/
6+
#include "xfs.h"
7+
#include "xfs_fs.h"
8+
#include "xfs_shared.h"
9+
#include "xfs_format.h"
10+
#include "xfs_trans_resv.h"
11+
#include "xfs_mount.h"
12+
#include "xfs_rtgroup.h"
13+
#include "scrub/scrub.h"
14+
#include "scrub/common.h"
15+
16+
/* Set us up with a transaction and an empty context. */
17+
int
18+
xchk_setup_rgsuperblock(
19+
struct xfs_scrub *sc)
20+
{
21+
return xchk_trans_alloc(sc, 0);
22+
}
23+
24+
/* Cross-reference with the other rt metadata. */
25+
STATIC void
26+
xchk_rgsuperblock_xref(
27+
struct xfs_scrub *sc)
28+
{
29+
if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
30+
return;
31+
32+
xchk_xref_is_used_rt_space(sc, xfs_rgbno_to_rtb(sc->sr.rtg, 0), 1);
33+
}
34+
35+
int
36+
xchk_rgsuperblock(
37+
struct xfs_scrub *sc)
38+
{
39+
xfs_rgnumber_t rgno = sc->sm->sm_agno;
40+
int error;
41+
42+
/*
43+
* Only rtgroup 0 has a superblock. We may someday want to use higher
44+
* rgno for other functions, similar to what we do with the primary
45+
* super scrub function.
46+
*/
47+
if (rgno != 0)
48+
return -ENOENT;
49+
50+
/*
51+
* Grab an active reference to the rtgroup structure. If we can't get
52+
* it, we're racing with something that's tearing down the group, so
53+
* signal that the group no longer exists. Take the rtbitmap in shared
54+
* mode so that the group can't change while we're doing things.
55+
*/
56+
error = xchk_rtgroup_init_existing(sc, rgno, &sc->sr);
57+
if (!xchk_xref_process_error(sc, 0, 0, &error))
58+
return error;
59+
60+
xchk_rtgroup_lock(&sc->sr, XFS_RTGLOCK_BITMAP_SHARED);
61+
62+
/*
63+
* Since we already validated the rt superblock at mount time, we don't
64+
* need to check its contents again. All we need is to cross-reference.
65+
*/
66+
xchk_rgsuperblock_xref(sc);
67+
return 0;
68+
}

fs/xfs/scrub/scrub.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,13 @@ static const struct xchk_meta_ops meta_scrub_ops[] = {
451451
.has = xfs_has_metadir,
452452
.repair = xrep_metapath,
453453
},
454+
[XFS_SCRUB_TYPE_RGSUPER] = { /* realtime group superblock */
455+
.type = ST_RTGROUP,
456+
.setup = xchk_setup_rgsuperblock,
457+
.scrub = xchk_rgsuperblock,
458+
.has = xfs_has_rtsb,
459+
.repair = xrep_notsupported,
460+
},
454461
};
455462

456463
static int

fs/xfs/scrub/scrub.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,11 @@ int xchk_metapath(struct xfs_scrub *sc);
273273
#ifdef CONFIG_XFS_RT
274274
int xchk_rtbitmap(struct xfs_scrub *sc);
275275
int xchk_rtsummary(struct xfs_scrub *sc);
276+
int xchk_rgsuperblock(struct xfs_scrub *sc);
276277
#else
277278
# define xchk_rtbitmap xchk_nothing
278279
# define xchk_rtsummary xchk_nothing
280+
# define xchk_rgsuperblock xchk_nothing
279281
#endif
280282
#ifdef CONFIG_XFS_QUOTA
281283
int xchk_quota(struct xfs_scrub *sc);

fs/xfs/scrub/stats.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static const char *name_map[XFS_SCRUB_TYPE_NR] = {
8181
[XFS_SCRUB_TYPE_NLINKS] = "nlinks",
8282
[XFS_SCRUB_TYPE_DIRTREE] = "dirtree",
8383
[XFS_SCRUB_TYPE_METAPATH] = "metapath",
84+
[XFS_SCRUB_TYPE_RGSUPER] = "rgsuper",
8485
};
8586

8687
/* Format the scrub stats into a text buffer, similar to pcp style. */

fs/xfs/scrub/trace.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_HEALTHY);
7171
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_DIRTREE);
7272
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_BARRIER);
7373
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_METAPATH);
74+
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_RGSUPER);
7475

7576
#define XFS_SCRUB_TYPE_STRINGS \
7677
{ XFS_SCRUB_TYPE_PROBE, "probe" }, \
@@ -103,7 +104,8 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_METAPATH);
103104
{ XFS_SCRUB_TYPE_HEALTHY, "healthy" }, \
104105
{ XFS_SCRUB_TYPE_DIRTREE, "dirtree" }, \
105106
{ XFS_SCRUB_TYPE_BARRIER, "barrier" }, \
106-
{ XFS_SCRUB_TYPE_METAPATH, "metapath" }
107+
{ XFS_SCRUB_TYPE_METAPATH, "metapath" }, \
108+
{ XFS_SCRUB_TYPE_RGSUPER, "rgsuper" }
107109

108110
#define XFS_SCRUB_FLAG_STRINGS \
109111
{ XFS_SCRUB_IFLAG_REPAIR, "repair" }, \

0 commit comments

Comments
 (0)