xfs: count escaped corruption errors in scrub stats

The main scrub code will quietly turn bubbled-up EFSCORRUPTED and
EFSBADCRC errors into corruption errors.  These aren't recorded in the
scrub stats code (says LOLLM) so do that now.

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: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
Darrick J. Wong 2026-09-02 22:52:23 -07:00 committed by Carlos Maiolino
parent 6b760b3232
commit 4d0624679a
3 changed files with 22 additions and 13 deletions

View File

@ -765,8 +765,7 @@ xfs_scrub_metadata(
out_teardown:
error = xchk_teardown(sc, error);
out_sc:
if (error != -ENOENT)
xchk_stats_merge(mp, sm, &run);
xchk_stats_merge(mp, sm, error, &run);
kfree(sc);
out:
trace_xchk_done(XFS_I(file_inode(file)), sm, error);

View File

@ -188,31 +188,37 @@ STATIC void
xchk_stats_merge_one(
struct xchk_stats *cs,
const struct xfs_scrub_metadata *sm,
int error,
const struct xchk_stats_run *run)
{
struct xchk_scrub_stats *css;
unsigned int sm_flags = sm->sm_flags;
if (sm->sm_type >= XFS_SCRUB_TYPE_NR) {
ASSERT(sm->sm_type < XFS_SCRUB_TYPE_NR);
return;
}
/* caller applies this same transformation after we return */
if (error == -EFSCORRUPTED || error == -EFSBADCRC)
sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
css = &cs->cs_stats[sm->sm_type];
spin_lock(&css->css_lock);
css->invocations++;
if (!(sm->sm_flags & XFS_SCRUB_OFLAG_UNCLEAN))
if (!(sm_flags & XFS_SCRUB_OFLAG_UNCLEAN))
css->clean++;
if (sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
if (sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
css->corrupt++;
if (sm->sm_flags & XFS_SCRUB_OFLAG_PREEN)
if (sm_flags & XFS_SCRUB_OFLAG_PREEN)
css->preen++;
if (sm->sm_flags & XFS_SCRUB_OFLAG_XFAIL)
if (sm_flags & XFS_SCRUB_OFLAG_XFAIL)
css->xfail++;
if (sm->sm_flags & XFS_SCRUB_OFLAG_XCORRUPT)
if (sm_flags & XFS_SCRUB_OFLAG_XCORRUPT)
css->xcorrupt++;
if (sm->sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
if (sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
css->incomplete++;
if (sm->sm_flags & XFS_SCRUB_OFLAG_WARNING)
if (sm_flags & XFS_SCRUB_OFLAG_WARNING)
css->warning++;
css->retries += run->retries;
css->checktime_us += howmany_64(run->scrub_ns, NSEC_PER_USEC);
@ -230,10 +236,14 @@ void
xchk_stats_merge(
struct xfs_mount *mp,
const struct xfs_scrub_metadata *sm,
int error,
const struct xchk_stats_run *run)
{
xchk_stats_merge_one(&global_stats, sm, run);
xchk_stats_merge_one(mp->m_scrub_stats, sm, run);
if (error == -ENOENT)
return;
xchk_stats_merge_one(&global_stats, sm, error, run);
xchk_stats_merge_one(mp->m_scrub_stats, sm, error, run);
}
/* debugfs boilerplate */

View File

@ -27,7 +27,7 @@ void xchk_stats_register(struct xchk_stats *cs, struct dentry *parent);
void xchk_stats_unregister(struct xchk_stats *cs);
void xchk_stats_merge(struct xfs_mount *mp, const struct xfs_scrub_metadata *sm,
const struct xchk_stats_run *run);
int error, const struct xchk_stats_run *run);
static inline u64 xchk_stats_now(void) { return ktime_get_ns(); }
static inline u64 xchk_stats_elapsed_ns(u64 since)
@ -53,7 +53,7 @@ static inline u64 xchk_stats_elapsed_ns(u64 since)
# define xchk_stats_unregister(cs) ((void)0)
# define xchk_stats_now() (0)
# define xchk_stats_elapsed_ns(x) (0 * (x))
# define xchk_stats_merge(mp, sm, run) ((void)0)
# define xchk_stats_merge(mp, sm, error, run) ((void)0)
#endif /* CONFIG_XFS_ONLINE_SCRUB_STATS */
#endif /* __XFS_SCRUB_STATS_H__ */