Commit d7a74cad authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: track usage statistics of online fsck



Track the usage, outcomes, and run times of the online fsck code, and
report these values via debugfs.  The columns in the file are:

 * scrubber name

 * number of scrub invocations
 * clean objects found
 * corruptions found
 * optimizations found
 * cross referencing failures
 * inconsistencies found during cross referencing
 * incomplete scrubs
 * warnings
 * number of time scrub had to retry
 * cumulative amount of time spent scrubbing (microseconds)

 * number of repair inovcations
 * successfully repaired objects
 * cumuluative amount of time spent repairing (microseconds)

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent a76dba3b
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -143,6 +143,23 @@ config XFS_ONLINE_SCRUB

	  If unsure, say N.

config XFS_ONLINE_SCRUB_STATS
	bool "XFS online metadata check usage data collection"
	default y
	depends on XFS_ONLINE_SCRUB
	select FS_DEBUG
	help
	  If you say Y here, the kernel will gather usage data about
	  the online metadata check subsystem.  This includes the number
	  of invocations, the outcomes, and the results of repairs, if any.
	  This may slow down scrub slightly due to the use of high precision
	  timers and the need to merge per-invocation information into the
	  filesystem counters.

	  Usage data are collected in /sys/kernel/debug/xfs/scrub.

	  If unsure, say N.

config XFS_ONLINE_REPAIR
	bool "XFS online metadata repair support"
	default n
+1 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ xfs-y += $(addprefix scrub/, \
				   xfile.o \
				   )

xfs-$(CONFIG_XFS_ONLINE_SCRUB_STATS) += scrub/stats.o
xfs-$(CONFIG_XFS_RT)		+= scrub/rtbitmap.o
xfs-$(CONFIG_XFS_QUOTA)		+= scrub/quota.o

+10 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "scrub/trace.h"
#include "scrub/repair.h"
#include "scrub/bitmap.h"
#include "scrub/stats.h"

/*
 * Attempt to repair some metadata, if the metadata is corrupt and userspace
@@ -40,8 +41,10 @@
 */
int
xrep_attempt(
	struct xfs_scrub	*sc)
	struct xfs_scrub	*sc,
	struct xchk_stats_run	*run)
{
	u64			repair_start;
	int			error = 0;

	trace_xrep_attempt(XFS_I(file_inode(sc->file)), sc->sm, error);
@@ -50,8 +53,11 @@ xrep_attempt(

	/* Repair whatever's broken. */
	ASSERT(sc->ops->repair);
	run->repair_attempted = true;
	repair_start = xchk_stats_now();
	error = sc->ops->repair(sc);
	trace_xrep_done(XFS_I(file_inode(sc->file)), sc->sm, error);
	run->repair_ns += xchk_stats_elapsed_ns(repair_start);
	switch (error) {
	case 0:
		/*
@@ -60,14 +66,17 @@ xrep_attempt(
		 */
		sc->sm->sm_flags &= ~XFS_SCRUB_FLAGS_OUT;
		sc->flags |= XREP_ALREADY_FIXED;
		run->repair_succeeded = true;
		return -EAGAIN;
	case -ECHRNG:
		sc->flags |= XCHK_NEED_DRAIN;
		run->retries++;
		return -EAGAIN;
	case -EDEADLOCK:
		/* Tell the caller to try again having grabbed all the locks. */
		if (!(sc->flags & XCHK_TRY_HARDER)) {
			sc->flags |= XCHK_TRY_HARDER;
			run->retries++;
			return -EAGAIN;
		}
		/*
+5 −2
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@

#include "xfs_quota_defs.h"

struct xchk_stats_run;

static inline int xrep_notsupported(struct xfs_scrub *sc)
{
	return -EOPNOTSUPP;
@@ -25,7 +27,7 @@ static inline int xrep_notsupported(struct xfs_scrub *sc)

/* Repair helpers */

int xrep_attempt(struct xfs_scrub *sc);
int xrep_attempt(struct xfs_scrub *sc, struct xchk_stats_run *run);
void xrep_failure(struct xfs_mount *mp);
int xrep_roll_ag_trans(struct xfs_scrub *sc);
int xrep_defer_finish(struct xfs_scrub *sc);
@@ -70,7 +72,8 @@ int xrep_agi(struct xfs_scrub *sc);

static inline int
xrep_attempt(
	struct xfs_scrub	*sc)
	struct xfs_scrub	*sc,
	struct xchk_stats_run	*run)
{
	return -EOPNOTSUPP;
}
+10 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "scrub/trace.h"
#include "scrub/repair.h"
#include "scrub/health.h"
#include "scrub/stats.h"

/*
 * Online Scrub and Repair
@@ -461,8 +462,10 @@ xfs_scrub_metadata(
	struct file			*file,
	struct xfs_scrub_metadata	*sm)
{
	struct xchk_stats_run		run = { };
	struct xfs_scrub		*sc;
	struct xfs_mount		*mp = XFS_I(file_inode(file))->i_mount;
	u64				check_start;
	int				error = 0;

	BUILD_BUG_ON(sizeof(meta_scrub_ops) !=
@@ -517,7 +520,9 @@ xfs_scrub_metadata(
		goto out_teardown;

	/* Scrub for errors. */
	check_start = xchk_stats_now();
	error = sc->ops->scrub(sc);
	run.scrub_ns += xchk_stats_elapsed_ns(check_start);
	if (error == -EDEADLOCK && !(sc->flags & XCHK_TRY_HARDER))
		goto try_harder;
	if (error == -ECHRNG && !(sc->flags & XCHK_NEED_DRAIN))
@@ -551,7 +556,7 @@ xfs_scrub_metadata(
		 * If it's broken, userspace wants us to fix it, and we haven't
		 * already tried to fix it, then attempt a repair.
		 */
		error = xrep_attempt(sc);
		error = xrep_attempt(sc, &run);
		if (error == -EAGAIN) {
			/*
			 * Either the repair function succeeded or it couldn't
@@ -579,12 +584,15 @@ xfs_scrub_metadata(
		sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
		error = 0;
	}
	if (error != -ENOENT)
		xchk_stats_merge(mp, sm, &run);
	return error;
need_drain:
	error = xchk_teardown(sc, 0);
	if (error)
		goto out_sc;
	sc->flags |= XCHK_NEED_DRAIN;
	run.retries++;
	goto retry_op;
try_harder:
	/*
@@ -596,5 +604,6 @@ xfs_scrub_metadata(
	if (error)
		goto out_sc;
	sc->flags |= XCHK_TRY_HARDER;
	run.retries++;
	goto retry_op;
}
Loading