From: Darrick J. Wong Date: Tue, 30 Jun 2026 01:02:24 +0000 (-0700) Subject: xfs_scrub: fix spacemap external log device scan dev key X-Git-Tag: v7.1.0~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4399db49dec0a04431f5c93960a5c73ac30fc8d0;p=xfsprogs-dev.git xfs_scrub: fix spacemap external log device scan dev key Codex bizarrely complains about the rtstart>0 logic in scan_log_rmaps, because it gets confused about the difference between internal logs (which are scanned by scan_ag_rmaps) and external logs, which this function handles. I'm ignoring the report, but we shouldn't open-code the synthetic device keys so let's fix that by hoisting the fsmap device helpers from phase6.c to spacemap.h and using them everywhere. Cc: linux-xfs@vger.kernel.org # v6.15.0 Fixes: 37591ef3f4f14c ("xfs_scrub: support internal RT device") Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- diff --git a/scrub/phase6.c b/scrub/phase6.c index aef817ad..c562a076 100644 --- a/scrub/phase6.c +++ b/scrub/phase6.c @@ -45,48 +45,6 @@ struct media_verify_state { struct read_verify_pool *rvp[XFS_DEV_RT + 1]; }; -/* Return XFS device index from fsmap device. */ -static enum xfs_device -from_fsmap_dev( - struct scrub_ctx *ctx, - dev_t dev) -{ - if (ctx->mnt.fsgeom.rtstart) { - if (dev < XFS_DEV_DATA || dev > XFS_DEV_RT) - abort(); - return dev; - } - - if (dev == ctx->fsinfo.fs_datadev) - return XFS_DEV_DATA; - if (dev == ctx->fsinfo.fs_logdev) - return XFS_DEV_LOG; - if (dev == ctx->fsinfo.fs_rtdev) - return XFS_DEV_RT; - abort(); -} - -/* Return fsmap device for XFS device index. */ -static uint32_t -to_fsmap_dev( - struct scrub_ctx *ctx, - enum xfs_device dev) -{ - if (ctx->mnt.fsgeom.rtstart) - return dev; - - switch (dev) { - case XFS_DEV_DATA: - return ctx->fsinfo.fs_datadev; - case XFS_DEV_LOG: - return ctx->fsinfo.fs_logdev; - case XFS_DEV_RT: - return ctx->fsinfo.fs_rtdev; - default: - abort(); - } -} - struct disk_ioerr_report { struct scrub_ctx *ctx; enum xfs_device dev; diff --git a/scrub/phase7.c b/scrub/phase7.c index 375ba063..d7418652 100644 --- a/scrub/phase7.c +++ b/scrub/phase7.c @@ -70,19 +70,10 @@ count_block_summary( void *arg) { struct summary_counts *counts; - enum xfs_device dev; + enum xfs_device dev = from_fsmap_dev(ctx, fsmap->fmr_device); unsigned long long len; int ret; - if (ctx->mnt.fsgeom.rtstart) - dev = fsmap->fmr_device; - else if (fsmap->fmr_device == ctx->fsinfo.fs_logdev) - dev = XFS_DEV_LOG; - else if (fsmap->fmr_device == ctx->fsinfo.fs_rtdev) - dev = XFS_DEV_RT; - else - dev = XFS_DEV_DATA; - counts = ptvar_get((struct ptvar *)arg, &ret); if (ret) { str_liberror(ctx, -ret, _("retrieving summary counts")); diff --git a/scrub/spacemap.c b/scrub/spacemap.c index 8f595ad9..45ac61d0 100644 --- a/scrub/spacemap.c +++ b/scrub/spacemap.c @@ -103,10 +103,7 @@ scan_ag_rmaps( bperag = (off_t)ctx->mnt.fsgeom.agblocks * (off_t)ctx->mnt.fsgeom.blocksize; - if (ctx->mnt.fsgeom.rtstart) - keys[0].fmr_device = XFS_DEV_DATA; - else - keys[0].fmr_device = ctx->fsinfo.fs_datadev; + keys[0].fmr_device = to_fsmap_dev(ctx, XFS_DEV_DATA); keys[0].fmr_physical = agno * bperag; keys[1].fmr_device = keys[0].fmr_device; keys[1].fmr_physical = ((agno + 1) * bperag) - 1; @@ -143,10 +140,7 @@ scan_rtg_rmaps( off_t bperrg = bytes_per_rtgroup(&ctx->mnt.fsgeom); int ret; - if (ctx->mnt.fsgeom.rtstart) - keys[0].fmr_device = XFS_DEV_RT; - else - keys[0].fmr_device = ctx->fsinfo.fs_rtdev; + keys[0].fmr_device = to_fsmap_dev(ctx, XFS_DEV_RT); keys[0].fmr_physical = (xfs_rtblock_t)rgno * bperrg; keys[1].fmr_device = keys[0].fmr_device; keys[1].fmr_physical = ((rgno + 1) * bperrg) - 1; @@ -210,10 +204,10 @@ scan_rt_rmaps( { struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx; - scan_dev_rmaps(ctx, ctx->fsinfo.fs_rtdev, arg); + scan_dev_rmaps(ctx, to_fsmap_dev(ctx, XFS_DEV_RT), arg); } -/* Iterate all the reverse mappings of the log device. */ +/* Iterate all the reverse mappings of the external log device. */ static void scan_log_rmaps( struct workqueue *wq, @@ -222,8 +216,7 @@ scan_log_rmaps( { struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx; - scan_dev_rmaps(ctx, ctx->mnt.fsgeom.rtstart ? 2 : ctx->fsinfo.fs_logdev, - arg); + scan_dev_rmaps(ctx, to_fsmap_dev(ctx, XFS_DEV_LOG), arg); } /* diff --git a/scrub/spacemap.h b/scrub/spacemap.h index 759d0f89..0d85285f 100644 --- a/scrub/spacemap.h +++ b/scrub/spacemap.h @@ -23,4 +23,46 @@ static inline unsigned int scrub_scan_spacemaps_nproc(struct scrub_ctx *ctx) return scrub_nproc(ctx); } +/* Return XFS device index from fsmap device. */ +static inline enum xfs_device +from_fsmap_dev( + struct scrub_ctx *ctx, + dev_t dev) +{ + if (ctx->mnt.fsgeom.rtstart) { + if (dev < XFS_DEV_DATA || dev > XFS_DEV_RT) + abort(); + return dev; + } + + if (dev == ctx->fsinfo.fs_datadev) + return XFS_DEV_DATA; + if (dev == ctx->fsinfo.fs_logdev) + return XFS_DEV_LOG; + if (dev == ctx->fsinfo.fs_rtdev) + return XFS_DEV_RT; + abort(); +} + +/* Return fsmap device for XFS device index. */ +static inline uint32_t +to_fsmap_dev( + struct scrub_ctx *ctx, + enum xfs_device dev) +{ + if (ctx->mnt.fsgeom.rtstart) + return dev; + + switch (dev) { + case XFS_DEV_DATA: + return ctx->fsinfo.fs_datadev; + case XFS_DEV_LOG: + return ctx->fsinfo.fs_logdev; + case XFS_DEV_RT: + return ctx->fsinfo.fs_rtdev; + default: + abort(); + } +} + #endif /* XFS_SCRUB_SPACEMAP_H_ */