Commit 889b09b3 authored by Chandan Babu R's avatar Chandan Babu R
Browse files

Merge tag 'scrub-usage-stats-6.6_2023-08-10' of...

Merge tag 'scrub-usage-stats-6.6_2023-08-10' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux

 into xfs-6.6-mergeA

xfs: add usage counters for scrub

This series introduces simple usage and performance counters for the
online fsck subsystem.  The goal here is to enable developers and
sysadmins to look at summary counts of how many objects were checked and
repaired; what the outcomes were; and how much time the kernel has spent
on these operations.  The counter file is exposed in debugfs because
that's easier than cramming it into the device model, and debugfs
doesn't have rules against complex file contents, unlike sysfs.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandan.babu@oracle.com>

* tag 'scrub-usage-stats-6.6_2023-08-10' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
  xfs: track usage statistics of online fsck
  xfs: create scaffolding for creating debugfs entries
parents d668fc1f d7a74cad
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