Skip to content

Commit a1f3e0c

Browse files
author
Darrick J. Wong
committed
xfs: update health status if we get a clean bill of health
If scrub finds that everything is ok with the filesystem, we need a way to tell the health tracking that it can let go of indirect health flags, since indirect flags only mean that at some point in the past we lost some context. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
1 parent 0e24ec3 commit a1f3e0c

6 files changed

Lines changed: 77 additions & 2 deletions

File tree

fs/xfs/libxfs/xfs_fs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,9 +714,10 @@ struct xfs_scrub_metadata {
714714
#define XFS_SCRUB_TYPE_FSCOUNTERS 24 /* fs summary counters */
715715
#define XFS_SCRUB_TYPE_QUOTACHECK 25 /* quota counters */
716716
#define XFS_SCRUB_TYPE_NLINKS 26 /* inode link counts */
717+
#define XFS_SCRUB_TYPE_HEALTHY 27 /* everything checked out ok */
717718

718719
/* Number of scrub subcommands. */
719-
#define XFS_SCRUB_TYPE_NR 27
720+
#define XFS_SCRUB_TYPE_NR 28
720721

721722
/* i: Repair this metadata. */
722723
#define XFS_SCRUB_IFLAG_REPAIR (1u << 0)

fs/xfs/scrub/health.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "xfs_health.h"
1515
#include "scrub/scrub.h"
1616
#include "scrub/health.h"
17+
#include "scrub/common.h"
1718

1819
/*
1920
* Scrub and In-Core Filesystem Health Assessments
@@ -149,6 +150,24 @@ xchk_file_looks_zapped(
149150
return xfs_inode_has_sickness(sc->ip, mask);
150151
}
151152

153+
/*
154+
* Scrub gave the filesystem a clean bill of health, so clear all the indirect
155+
* markers of past problems (at least for the fs and ags) so that we can be
156+
* healthy again.
157+
*/
158+
STATIC void
159+
xchk_mark_all_healthy(
160+
struct xfs_mount *mp)
161+
{
162+
struct xfs_perag *pag;
163+
xfs_agnumber_t agno;
164+
165+
xfs_fs_mark_healthy(mp, XFS_SICK_FS_INDIRECT);
166+
xfs_rt_mark_healthy(mp, XFS_SICK_RT_INDIRECT);
167+
for_each_perag(mp, agno, pag)
168+
xfs_ag_mark_healthy(pag, XFS_SICK_AG_INDIRECT);
169+
}
170+
152171
/*
153172
* Update filesystem health assessments based on what we found and did.
154173
*
@@ -166,6 +185,18 @@ xchk_update_health(
166185
struct xfs_perag *pag;
167186
bool bad;
168187

188+
/*
189+
* The HEALTHY scrub type is a request from userspace to clear all the
190+
* indirect flags after a clean scan of the entire filesystem. As such
191+
* there's no sick flag defined for it, so we branch here ahead of the
192+
* mask check.
193+
*/
194+
if (sc->sm->sm_type == XFS_SCRUB_TYPE_HEALTHY &&
195+
!(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) {
196+
xchk_mark_all_healthy(sc->mp);
197+
return;
198+
}
199+
169200
if (!sc->sick_mask)
170201
return;
171202

@@ -285,3 +316,36 @@ xchk_ag_btree_healthy_enough(
285316

286317
return true;
287318
}
319+
320+
/*
321+
* Quick scan to double-check that there isn't any evidence of lingering
322+
* primary health problems. If we're still clear, then the health update will
323+
* take care of clearing the indirect evidence.
324+
*/
325+
int
326+
xchk_health_record(
327+
struct xfs_scrub *sc)
328+
{
329+
struct xfs_mount *mp = sc->mp;
330+
struct xfs_perag *pag;
331+
xfs_agnumber_t agno;
332+
333+
unsigned int sick;
334+
unsigned int checked;
335+
336+
xfs_fs_measure_sickness(mp, &sick, &checked);
337+
if (sick & XFS_SICK_FS_PRIMARY)
338+
xchk_set_corrupt(sc);
339+
340+
xfs_rt_measure_sickness(mp, &sick, &checked);
341+
if (sick & XFS_SICK_RT_PRIMARY)
342+
xchk_set_corrupt(sc);
343+
344+
for_each_perag(mp, agno, pag) {
345+
xfs_ag_measure_sickness(pag, &sick, &checked);
346+
if (sick & XFS_SICK_AG_PRIMARY)
347+
xchk_set_corrupt(sc);
348+
}
349+
350+
return 0;
351+
}

fs/xfs/scrub/health.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ bool xchk_ag_btree_healthy_enough(struct xfs_scrub *sc, struct xfs_perag *pag,
1212
xfs_btnum_t btnum);
1313
void xchk_mark_healthy_if_clean(struct xfs_scrub *sc, unsigned int mask);
1414
bool xchk_file_looks_zapped(struct xfs_scrub *sc, unsigned int mask);
15+
int xchk_health_record(struct xfs_scrub *sc);
1516

1617
#endif /* __XFS_SCRUB_HEALTH_H__ */

fs/xfs/scrub/repair.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "xfs_errortag.h"
3131
#include "xfs_error.h"
3232
#include "xfs_reflink.h"
33+
#include "xfs_health.h"
3334
#include "scrub/scrub.h"
3435
#include "scrub/common.h"
3536
#include "scrub/trace.h"

fs/xfs/scrub/scrub.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,12 @@ static const struct xchk_meta_ops meta_scrub_ops[] = {
378378
.scrub = xchk_nlinks,
379379
.repair = xrep_nlinks,
380380
},
381+
[XFS_SCRUB_TYPE_HEALTHY] = { /* fs healthy; clean all reminders */
382+
.type = ST_FS,
383+
.setup = xchk_setup_fs,
384+
.scrub = xchk_health_record,
385+
.repair = xrep_notsupported,
386+
},
381387
};
382388

383389
static int

fs/xfs/scrub/trace.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_PQUOTA);
6969
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_FSCOUNTERS);
7070
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_QUOTACHECK);
7171
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_NLINKS);
72+
TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_HEALTHY);
7273

7374
#define XFS_SCRUB_TYPE_STRINGS \
7475
{ XFS_SCRUB_TYPE_PROBE, "probe" }, \
@@ -97,7 +98,8 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_NLINKS);
9798
{ XFS_SCRUB_TYPE_PQUOTA, "prjquota" }, \
9899
{ XFS_SCRUB_TYPE_FSCOUNTERS, "fscounters" }, \
99100
{ XFS_SCRUB_TYPE_QUOTACHECK, "quotacheck" }, \
100-
{ XFS_SCRUB_TYPE_NLINKS, "nlinks" }
101+
{ XFS_SCRUB_TYPE_NLINKS, "nlinks" }, \
102+
{ XFS_SCRUB_TYPE_HEALTHY, "healthy" }
101103

102104
#define XFS_SCRUB_FLAG_STRINGS \
103105
{ XFS_SCRUB_IFLAG_REPAIR, "repair" }, \

0 commit comments

Comments
 (0)