]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_scrub: support internal RT device
authorChristoph Hellwig <hch@lst.de>
Fri, 20 Dec 2024 03:51:06 +0000 (19:51 -0800)
committerChristoph Hellwig <hch@lst.de>
Mon, 14 Apr 2025 05:36:00 +0000 (07:36 +0200)
Handle the synthetic fmr_device values, and deal with the fact that
ctx->fsinfo.fs_rt is allowed to be non-NULL for internal RT devices as
it is the same as the data device in this case.

Signed-off-by: Christoph Hellwig <hch@lst.de>
scrub/phase1.c
scrub/phase6.c
scrub/phase7.c
scrub/spacemap.c

index d03a9099a2173ca329984ec645066ba14ba878fb..10e9aa1892b7014907c162b1257fe92a693d1b01 100644 (file)
@@ -341,7 +341,8 @@ _("Kernel metadata repair facility is not available.  Use -n to scrub."));
 _("Unable to find log device path."));
                return ECANCELED;
        }
-       if (ctx->mnt.fsgeom.rtblocks && ctx->fsinfo.fs_rt == NULL) {
+       if (ctx->mnt.fsgeom.rtblocks && ctx->fsinfo.fs_rt == NULL &&
+           !ctx->mnt.fsgeom.rtstart) {
                str_error(ctx, ctx->mntpoint,
 _("Unable to find realtime device path."));
                return ECANCELED;
index 2a52b2c9241993272073071cef44d7c364087ebf..abf6f9713f1a4d71f8df803d49622da1c1eb01e1 100644 (file)
@@ -56,12 +56,21 @@ dev_to_pool(
        struct media_verify_state       *vs,
        dev_t                           dev)
 {
-       if (dev == ctx->fsinfo.fs_datadev)
-               return vs->rvp_data;
-       else if (dev == ctx->fsinfo.fs_logdev)
-               return vs->rvp_log;
-       else if (dev == ctx->fsinfo.fs_rtdev)
-               return vs->rvp_realtime;
+       if (ctx->mnt.fsgeom.rtstart) {
+               if (dev == XFS_DEV_DATA)
+                       return vs->rvp_data;
+               if (dev == XFS_DEV_LOG)
+                       return vs->rvp_log;
+               if (dev == XFS_DEV_RT)
+                       return vs->rvp_realtime;
+       } else {
+               if (dev == ctx->fsinfo.fs_datadev)
+                       return vs->rvp_data;
+               if (dev == ctx->fsinfo.fs_logdev)
+                       return vs->rvp_log;
+               if (dev == ctx->fsinfo.fs_rtdev)
+                       return vs->rvp_realtime;
+       }
        abort();
 }
 
@@ -71,12 +80,21 @@ disk_to_dev(
        struct scrub_ctx        *ctx,
        struct disk             *disk)
 {
-       if (disk == ctx->datadev)
-               return ctx->fsinfo.fs_datadev;
-       else if (disk == ctx->logdev)
-               return ctx->fsinfo.fs_logdev;
-       else if (disk == ctx->rtdev)
-               return ctx->fsinfo.fs_rtdev;
+       if (ctx->mnt.fsgeom.rtstart) {
+               if (disk == ctx->datadev)
+                       return XFS_DEV_DATA;
+               if (disk == ctx->logdev)
+                       return XFS_DEV_LOG;
+               if (disk == ctx->rtdev)
+                       return XFS_DEV_RT;
+       } else {
+               if (disk == ctx->datadev)
+                       return ctx->fsinfo.fs_datadev;
+               if (disk == ctx->logdev)
+                       return ctx->fsinfo.fs_logdev;
+               if (disk == ctx->rtdev)
+                       return ctx->fsinfo.fs_rtdev;
+       }
        abort();
 }
 
@@ -87,11 +105,9 @@ bitmap_for_disk(
        struct disk                     *disk,
        struct media_verify_state       *vs)
 {
-       dev_t                           dev = disk_to_dev(ctx, disk);
-
-       if (dev == ctx->fsinfo.fs_datadev)
+       if (disk == ctx->datadev)
                return vs->d_bad;
-       else if (dev == ctx->fsinfo.fs_rtdev)
+       if (disk == ctx->rtdev)
                return vs->r_bad;
        return NULL;
 }
@@ -501,14 +517,11 @@ report_ioerr(
                .length                 = length,
        };
        struct disk_ioerr_report        *dioerr = arg;
-       dev_t                           dev;
-
-       dev = disk_to_dev(dioerr->ctx, dioerr->disk);
 
        /* Go figure out which blocks are bad from the fsmap. */
-       keys[0].fmr_device = dev;
+       keys[0].fmr_device = disk_to_dev(dioerr->ctx, dioerr->disk);
        keys[0].fmr_physical = start;
-       keys[1].fmr_device = dev;
+       keys[1].fmr_device = keys[0].fmr_device;
        keys[1].fmr_physical = start + length - 1;
        keys[1].fmr_owner = ULLONG_MAX;
        keys[1].fmr_offset = ULLONG_MAX;
@@ -675,14 +688,12 @@ remember_ioerr(
        int                             ret;
 
        if (!length) {
-               dev_t                   dev = disk_to_dev(ctx, disk);
-
-               if (dev == ctx->fsinfo.fs_datadev)
+               if (disk == ctx->datadev)
                        vs->d_trunc = true;
-               else if (dev == ctx->fsinfo.fs_rtdev)
-                       vs->r_trunc = true;
-               else if (dev == ctx->fsinfo.fs_logdev)
+               else if (disk == ctx->logdev)
                        vs->l_trunc = true;
+               else if (disk == ctx->rtdev)
+                       vs->r_trunc = true;
                return;
        }
 
index 01097b67879878b1e46077435f48f6f7cdd92819..e25502668b1c41c59bf1d4f83fe9004ca259a651 100644 (file)
@@ -68,25 +68,37 @@ count_block_summary(
        void                    *arg)
 {
        struct summary_counts   *counts;
+       bool                    is_rt = false;
        unsigned long long      len;
        int                     ret;
 
+       if (ctx->mnt.fsgeom.rtstart) {
+               if (fsmap->fmr_device == XFS_DEV_LOG)
+                       return 0;
+               if (fsmap->fmr_device == XFS_DEV_RT)
+                       is_rt = true;
+       } else {
+               if (fsmap->fmr_device == ctx->fsinfo.fs_logdev)
+                       return 0;
+               if (fsmap->fmr_device == ctx->fsinfo.fs_rtdev)
+                       is_rt = true;
+       }
+
        counts = ptvar_get((struct ptvar *)arg, &ret);
        if (ret) {
                str_liberror(ctx, -ret, _("retrieving summary counts"));
                return -ret;
        }
-       if (fsmap->fmr_device == ctx->fsinfo.fs_logdev)
-               return 0;
+
        if ((fsmap->fmr_flags & FMR_OF_SPECIAL_OWNER) &&
            fsmap->fmr_owner == XFS_FMR_OWN_FREE) {
                uint64_t        blocks;
 
                blocks = cvt_b_to_off_fsbt(&ctx->mnt, fsmap->fmr_length);
-               if (fsmap->fmr_device == ctx->fsinfo.fs_datadev)
-                       hist_add(&counts->datadev_hist, blocks);
-               else if (fsmap->fmr_device == ctx->fsinfo.fs_rtdev)
+               if (is_rt)
                        hist_add(&counts->rtdev_hist, blocks);
+               else
+                       hist_add(&counts->datadev_hist, blocks);
                return 0;
        }
 
@@ -94,10 +106,10 @@ count_block_summary(
 
        /* freesp btrees live in free space, need to adjust counters later. */
        if ((fsmap->fmr_flags & FMR_OF_SPECIAL_OWNER) &&
-           fsmap->fmr_owner == XFS_FMR_OWN_AG) {
+           fsmap->fmr_owner == XFS_FMR_OWN_AG)
                counts->agbytes += fsmap->fmr_length;
-       }
-       if (fsmap->fmr_device == ctx->fsinfo.fs_rtdev) {
+
+       if (is_rt) {
                /* Count realtime extents. */
                counts->rbytes += len;
        } else {
index c293ab44a5286c213a8200748a8eb6cc93dd547e..1ee4d1946d3db7d3ebc89529b9b262ccaf1db446 100644 (file)
@@ -103,9 +103,12 @@ scan_ag_rmaps(
        bperag = (off_t)ctx->mnt.fsgeom.agblocks *
                 (off_t)ctx->mnt.fsgeom.blocksize;
 
-       keys[0].fmr_device = ctx->fsinfo.fs_datadev;
+       if (ctx->mnt.fsgeom.rtstart)
+               keys[0].fmr_device = XFS_DEV_DATA;
+       else
+               keys[0].fmr_device = ctx->fsinfo.fs_datadev;
        keys[0].fmr_physical = agno * bperag;
-       keys[1].fmr_device = ctx->fsinfo.fs_datadev;
+       keys[1].fmr_device = keys[0].fmr_device;
        keys[1].fmr_physical = ((agno + 1) * bperag) - 1;
        keys[1].fmr_owner = ULLONG_MAX;
        keys[1].fmr_offset = ULLONG_MAX;
@@ -140,9 +143,12 @@ scan_rtg_rmaps(
        off_t                   bperrg = bytes_per_rtgroup(&ctx->mnt.fsgeom);
        int                     ret;
 
-       keys[0].fmr_device = ctx->fsinfo.fs_rtdev;
+       if (ctx->mnt.fsgeom.rtstart)
+               keys[0].fmr_device = XFS_DEV_RT;
+       else
+               keys[0].fmr_device = ctx->fsinfo.fs_rtdev;
        keys[0].fmr_physical = (xfs_rtblock_t)rgno * bperrg;
-       keys[1].fmr_device = ctx->fsinfo.fs_rtdev;
+       keys[1].fmr_device = keys[0].fmr_device;
        keys[1].fmr_physical = ((rgno + 1) * bperrg) - 1;
        keys[1].fmr_owner = ULLONG_MAX;
        keys[1].fmr_offset = ULLONG_MAX;
@@ -216,7 +222,8 @@ scan_log_rmaps(
 {
        struct scrub_ctx        *ctx = (struct scrub_ctx *)wq->wq_ctx;
 
-       scan_dev_rmaps(ctx, ctx->fsinfo.fs_logdev, arg);
+       scan_dev_rmaps(ctx, ctx->mnt.fsgeom.rtstart ? 2 : ctx->fsinfo.fs_logdev,
+                       arg);
 }
 
 /*