xfs: snapshot scrub stats when rendering them

LOLLM complains about concurrency problems in the scrub stats code
because xchk_stats_format doesn't synchronize in any way with updates.
These stats are only reported through debugfs so I don't think it really
matters, but I guess I exist to make bots happy now.

Note: We snapshot the entire stats object with a spinlock so that we
don't have to worry about users seeing slightly weird numbers (e.g.
invocations has incremented but none of the outcomes have been yet) if
we race with xchk_stats_merge_one.  This isn't a hot path.

Cc: stable@vger.kernel.org # v6.6
Fixes: d7a74cad8f ("xfs: track usage statistics of online fsck")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
Darrick J. Wong 2026-09-08 23:03:02 -07:00 committed by Carlos Maiolino
parent 157dcb8230
commit 568a1588b9

View File

@ -99,25 +99,31 @@ xchk_stats_format(
int ret = 0;
for (i = 0; i < XFS_SCRUB_TYPE_NR; i++, css++) {
struct xchk_scrub_stats fss;
if (!name_map[i])
continue;
spin_lock(&css->css_lock);
memcpy(&fss, css, offsetof(struct xchk_scrub_stats, css_lock));
spin_unlock(&css->css_lock);
ret = scnprintf(buf, remaining,
"%s %u %u %u %u %u %u %u %u %u %llu %u %u %llu\n",
name_map[i],
(unsigned int)css->invocations,
(unsigned int)css->clean,
(unsigned int)css->corrupt,
(unsigned int)css->preen,
(unsigned int)css->xfail,
(unsigned int)css->xcorrupt,
(unsigned int)css->incomplete,
(unsigned int)css->warning,
(unsigned int)css->retries,
(unsigned long long)css->checktime_us,
(unsigned int)css->repair_invocations,
(unsigned int)css->repair_success,
(unsigned long long)css->repairtime_us);
(unsigned int)fss.invocations,
(unsigned int)fss.clean,
(unsigned int)fss.corrupt,
(unsigned int)fss.preen,
(unsigned int)fss.xfail,
(unsigned int)fss.xcorrupt,
(unsigned int)fss.incomplete,
(unsigned int)fss.warning,
(unsigned int)fss.retries,
(unsigned long long)fss.checktime_us,
(unsigned int)fss.repair_invocations,
(unsigned int)fss.repair_success,
(unsigned long long)fss.repairtime_us);
if (ret <= 0)
break;