]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: remove moveon from spacemap
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 6 Nov 2019 22:28:45 +0000 (17:28 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Wed, 6 Nov 2019 22:28:45 +0000 (17:28 -0500)
Replace the moveon returns in the space map iteration code with a direct
integer return.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
scrub/phase6.c
scrub/phase7.c
scrub/spacemap.c
scrub/spacemap.h

index a0a71ce3bb3ed762d2ebb4444382e5af2b0eeeec..62629732868f261a011d9ae514fc33aeb71f971d 100644 (file)
@@ -374,10 +374,9 @@ out:
 }
 
 /* Use a fsmap to report metadata lost to a media error. */
-static bool
+static int
 report_ioerr_fsmap(
        struct scrub_ctx        *ctx,
-       const char              *descr,
        struct fsmap            *map,
        void                    *arg)
 {
@@ -388,7 +387,7 @@ report_ioerr_fsmap(
 
        /* Don't care about unwritten extents. */
        if (map->fmr_flags & FMR_OF_PREALLOC)
-               return true;
+               return 0;
 
        if (err_physical > map->fmr_physical)
                err_off = err_physical - map->fmr_physical;
@@ -420,7 +419,7 @@ report_ioerr_fsmap(
         * to find the bad file's pathname.
         */
 
-       return true;
+       return 0;
 }
 
 /*
@@ -434,16 +433,11 @@ report_ioerr(
        void                            *arg)
 {
        struct fsmap                    keys[2];
-       char                            descr[DESCR_BUFSZ];
        struct disk_ioerr_report        *dioerr = arg;
        dev_t                           dev;
 
        dev = xfs_disk_to_dev(dioerr->ctx, dioerr->disk);
 
-       snprintf(descr, DESCR_BUFSZ,
-_("dev %d:%d ioerr @ %"PRIu64":%"PRIu64" "),
-                       major(dev), minor(dev), start, length);
-
        /* Go figure out which blocks are bad from the fsmap. */
        memset(keys, 0, sizeof(struct fsmap) * 2);
        keys->fmr_device = dev;
@@ -453,9 +447,8 @@ _("dev %d:%d ioerr @ %"PRIu64":%"PRIu64" "),
        (keys + 1)->fmr_owner = ULLONG_MAX;
        (keys + 1)->fmr_offset = ULLONG_MAX;
        (keys + 1)->fmr_flags = UINT_MAX;
-       xfs_iterate_fsmap(dioerr->ctx, descr, keys, report_ioerr_fsmap,
+       return scrub_iterate_fsmap(dioerr->ctx, keys, report_ioerr_fsmap,
                        &start);
-       return 0;
 }
 
 /* Report all the media errors found on a disk. */
@@ -511,10 +504,9 @@ report_all_media_errors(
 }
 
 /* Schedule a read-verify of a (data block) extent. */
-static bool
-xfs_check_rmap(
+static int
+check_rmap(
        struct scrub_ctx                *ctx,
-       const char                      *descr,
        struct fsmap                    *map,
        void                            *arg)
 {
@@ -544,7 +536,7 @@ xfs_check_rmap(
         */
        if (map->fmr_flags & (FMR_OF_PREALLOC | FMR_OF_ATTR_FORK |
                              FMR_OF_EXTENT_MAP | FMR_OF_SPECIAL_OWNER))
-               return true;
+               return 0;
 
        /* XXX: Filter out directory data blocks. */
 
@@ -552,11 +544,11 @@ xfs_check_rmap(
        ret = read_verify_schedule_io(rvp, map->fmr_physical, map->fmr_length,
                        vs);
        if (ret) {
-               str_liberror(ctx, ret, descr);
-               return false;
+               str_liberror(ctx, ret, _("scheduling media verify command"));
+               return ret;
        }
 
-       return true;
+       return 0;
 }
 
 /* Wait for read/verify actions to finish, then return # bytes checked. */
@@ -669,9 +661,11 @@ xfs_scan_blocks(
                        goto out_logpool;
                }
        }
-       moveon = xfs_scan_all_spacemaps(ctx, xfs_check_rmap, &vs);
-       if (!moveon)
+       ret = scrub_scan_all_spacemaps(ctx, check_rmap, &vs);
+       if (ret) {
+               moveon = false;
                goto out_rtpool;
+       }
 
        ret = clean_pool(vs.rvp_data, &ctx->bytes_checked);
        if (ret) {
index 6daf75b592f1c71c6ce7697278ed585d982e3c14..28689eac6eef1279cb97d96401daf23f1b590733 100644 (file)
@@ -27,10 +27,9 @@ struct summary_counts {
 };
 
 /* Record block usage. */
-static bool
-xfs_record_block_summary(
+static int
+count_block_summary(
        struct scrub_ctx        *ctx,
-       const char              *descr,
        struct fsmap            *fsmap,
        void                    *arg)
 {
@@ -41,13 +40,13 @@ xfs_record_block_summary(
        counts = ptvar_get((struct ptvar *)arg, &ret);
        if (ret) {
                str_liberror(ctx, ret, _("retrieving summary counts"));
-               return false;
+               return ret;
        }
        if (fsmap->fmr_device == ctx->fsinfo.fs_logdev)
-               return true;
+               return 0;
        if ((fsmap->fmr_flags & FMR_OF_SPECIAL_OWNER) &&
            fsmap->fmr_owner == XFS_FMR_OWN_FREE)
-               return true;
+               return 0;
 
        len = fsmap->fmr_length;
 
@@ -62,14 +61,14 @@ xfs_record_block_summary(
        } else {
                /* Count datadev extents. */
                if (counts->next_phys >= fsmap->fmr_physical + len)
-                       return true;
+                       return 0;
                else if (counts->next_phys > fsmap->fmr_physical)
                        len = counts->next_phys - fsmap->fmr_physical;
                counts->dbytes += len;
                counts->next_phys = fsmap->fmr_physical + fsmap->fmr_length;
        }
 
-       return true;
+       return 0;
 }
 
 /* Add all the summaries in the per-thread counter */
@@ -144,9 +143,11 @@ xfs_scan_summary(
        }
 
        /* Use fsmap to count blocks. */
-       moveon = xfs_scan_all_spacemaps(ctx, xfs_record_block_summary, ptvar);
-       if (!moveon)
+       error = scrub_scan_all_spacemaps(ctx, count_block_summary, ptvar);
+       if (error) {
+               moveon = false;
                goto out_free;
+       }
        error = ptvar_foreach(ptvar, xfs_add_summaries, &totalcount);
        if (error) {
                str_liberror(ctx, error, _("counting blocks"));
index 91e8badb7926dd4b3b838a338df01e8fc593abf3..e56f090d5eeb917789048809e13fe5e40cd756e8 100644 (file)
 
 #define FSMAP_NR       65536
 
-/* Iterate all the fs block mappings between the two keys. */
-bool
-xfs_iterate_fsmap(
+/*
+ * Iterate all the fs block mappings between the two keys.  Returns 0 or a
+ * positive error number.
+ */
+int
+scrub_iterate_fsmap(
        struct scrub_ctx        *ctx,
-       const char              *descr,
        struct fsmap            *keys,
-       xfs_fsmap_iter_fn       fn,
+       scrub_fsmap_iter_fn     fn,
        void                    *arg)
 {
        struct fsmap_head       *head;
        struct fsmap            *p;
-       bool                    moveon = true;
        int                     i;
        int                     error;
 
        head = malloc(fsmap_sizeof(FSMAP_NR));
-       if (!head) {
-               str_errno(ctx, descr);
-               return false;
-       }
+       if (!head)
+               return errno;
 
        memset(head, 0, sizeof(*head));
        memcpy(head->fmh_keys, keys, sizeof(struct fsmap) * 2);
@@ -60,13 +59,11 @@ xfs_iterate_fsmap(
                for (i = 0, p = head->fmh_recs;
                     i < head->fmh_entries;
                     i++, p++) {
-                       moveon = fn(ctx, descr, p, arg);
-                       if (!moveon)
+                       error = fn(ctx, p, arg);
+                       if (error)
                                goto out;
-                       if (xfs_scrub_excessive_errors(ctx)) {
-                               moveon = false;
+                       if (xfs_scrub_excessive_errors(ctx))
                                goto out;
-                       }
                }
 
                if (head->fmh_entries == 0)
@@ -76,45 +73,36 @@ xfs_iterate_fsmap(
                        break;
                fsmap_advance(head);
        }
-
-       if (error) {
-               str_errno(ctx, descr);
-               moveon = false;
-       }
+       if (error)
+               error = errno;
 out:
        free(head);
-       return moveon;
+       return error;
 }
 
 /* GETFSMAP wrappers routines. */
-struct xfs_scan_blocks {
-       xfs_fsmap_iter_fn       fn;
+struct scan_blocks {
+       scrub_fsmap_iter_fn     fn;
        void                    *arg;
-       bool                    moveon;
+       bool                    aborted;
 };
 
 /* Iterate all the reverse mappings of an AG. */
 static void
-xfs_scan_ag_blocks(
+scan_ag_rmaps(
        struct workqueue        *wq,
        xfs_agnumber_t          agno,
        void                    *arg)
 {
        struct scrub_ctx        *ctx = (struct scrub_ctx *)wq->wq_ctx;
-       struct xfs_scan_blocks  *sbx = arg;
-       char                    descr[DESCR_BUFSZ];
+       struct scan_blocks      *sbx = arg;
        struct fsmap            keys[2];
        off64_t                 bperag;
-       bool                    moveon;
+       int                     ret;
 
        bperag = (off64_t)ctx->mnt.fsgeom.agblocks *
                 (off64_t)ctx->mnt.fsgeom.blocksize;
 
-       snprintf(descr, DESCR_BUFSZ, _("dev %d:%d AG %u fsmap"),
-                               major(ctx->fsinfo.fs_datadev),
-                               minor(ctx->fsinfo.fs_datadev),
-                               agno);
-
        memset(keys, 0, sizeof(struct fsmap) * 2);
        keys->fmr_device = ctx->fsinfo.fs_datadev;
        keys->fmr_physical = agno * bperag;
@@ -124,25 +112,32 @@ xfs_scan_ag_blocks(
        (keys + 1)->fmr_offset = ULLONG_MAX;
        (keys + 1)->fmr_flags = UINT_MAX;
 
-       moveon = xfs_iterate_fsmap(ctx, descr, keys, sbx->fn, sbx->arg);
-       if (!moveon)
-               sbx->moveon = false;
+       if (sbx->aborted)
+               return;
+
+       ret = scrub_iterate_fsmap(ctx, keys, sbx->fn, sbx->arg);
+       if (ret) {
+               char            descr[DESCR_BUFSZ];
+
+               snprintf(descr, DESCR_BUFSZ, _("dev %d:%d AG %u fsmap"),
+                                       major(ctx->fsinfo.fs_datadev),
+                                       minor(ctx->fsinfo.fs_datadev),
+                                       agno);
+               str_liberror(ctx, ret, descr);
+               sbx->aborted = true;
+       }
 }
 
 /* Iterate all the reverse mappings of a standalone device. */
 static void
-xfs_scan_dev_blocks(
+scan_dev_rmaps(
        struct scrub_ctx        *ctx,
        int                     idx,
        dev_t                   dev,
-       struct xfs_scan_blocks  *sbx)
+       struct scan_blocks      *sbx)
 {
        struct fsmap            keys[2];
-       char                    descr[DESCR_BUFSZ];
-       bool                    moveon;
-
-       snprintf(descr, DESCR_BUFSZ, _("dev %d:%d fsmap"),
-                       major(dev), minor(dev));
+       int                     ret;
 
        memset(keys, 0, sizeof(struct fsmap) * 2);
        keys->fmr_device = dev;
@@ -152,79 +147,90 @@ xfs_scan_dev_blocks(
        (keys + 1)->fmr_offset = ULLONG_MAX;
        (keys + 1)->fmr_flags = UINT_MAX;
 
-       moveon = xfs_iterate_fsmap(ctx, descr, keys, sbx->fn, sbx->arg);
-       if (!moveon)
-               sbx->moveon = false;
+       if (sbx->aborted)
+               return;
+
+       ret = scrub_iterate_fsmap(ctx, keys, sbx->fn, sbx->arg);
+       if (ret) {
+               char            descr[DESCR_BUFSZ];
+
+               snprintf(descr, DESCR_BUFSZ, _("dev %d:%d fsmap"),
+                               major(dev), minor(dev));
+               str_liberror(ctx, ret, descr);
+               sbx->aborted = true;
+       }
 }
 
 /* Iterate all the reverse mappings of the realtime device. */
 static void
-xfs_scan_rt_blocks(
+scan_rt_rmaps(
        struct workqueue        *wq,
        xfs_agnumber_t          agno,
        void                    *arg)
 {
        struct scrub_ctx        *ctx = (struct scrub_ctx *)wq->wq_ctx;
 
-       xfs_scan_dev_blocks(ctx, agno, ctx->fsinfo.fs_rtdev, arg);
+       scan_dev_rmaps(ctx, agno, ctx->fsinfo.fs_rtdev, arg);
 }
 
 /* Iterate all the reverse mappings of the log device. */
 static void
-xfs_scan_log_blocks(
+scan_log_rmaps(
        struct workqueue        *wq,
        xfs_agnumber_t          agno,
        void                    *arg)
 {
        struct scrub_ctx        *ctx = (struct scrub_ctx *)wq->wq_ctx;
 
-       xfs_scan_dev_blocks(ctx, agno, ctx->fsinfo.fs_logdev, arg);
+       scan_dev_rmaps(ctx, agno, ctx->fsinfo.fs_logdev, arg);
 }
 
-/* Scan all the blocks in a filesystem. */
-bool
-xfs_scan_all_spacemaps(
+/*
+ * Scan all the blocks in a filesystem.  If errors occur, this function will
+ * log them and return nonzero.
+ */
+int
+scrub_scan_all_spacemaps(
        struct scrub_ctx        *ctx,
-       xfs_fsmap_iter_fn       fn,
+       scrub_fsmap_iter_fn     fn,
        void                    *arg)
 {
        struct workqueue        wq;
-       struct xfs_scan_blocks  sbx;
+       struct scan_blocks      sbx = {
+               .fn             = fn,
+               .arg            = arg,
+       };
        xfs_agnumber_t          agno;
        int                     ret;
 
-       sbx.moveon = true;
-       sbx.fn = fn;
-       sbx.arg = arg;
-
        ret = workqueue_create(&wq, (struct xfs_mount *)ctx,
                        scrub_nproc_workqueue(ctx));
        if (ret) {
                str_liberror(ctx, ret, _("creating fsmap workqueue"));
-               return false;
+               return ret;
        }
        if (ctx->fsinfo.fs_rt) {
-               ret = workqueue_add(&wq, xfs_scan_rt_blocks,
+               ret = workqueue_add(&wq, scan_rt_rmaps,
                                ctx->mnt.fsgeom.agcount + 1, &sbx);
                if (ret) {
-                       sbx.moveon = false;
+                       sbx.aborted = true;
                        str_liberror(ctx, ret, _("queueing rtdev fsmap work"));
                        goto out;
                }
        }
        if (ctx->fsinfo.fs_log) {
-               ret = workqueue_add(&wq, xfs_scan_log_blocks,
+               ret = workqueue_add(&wq, scan_log_rmaps,
                                ctx->mnt.fsgeom.agcount + 2, &sbx);
                if (ret) {
-                       sbx.moveon = false;
+                       sbx.aborted = true;
                        str_liberror(ctx, ret, _("queueing logdev fsmap work"));
                        goto out;
                }
        }
        for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
-               ret = workqueue_add(&wq, xfs_scan_ag_blocks, agno, &sbx);
+               ret = workqueue_add(&wq, scan_ag_rmaps, agno, &sbx);
                if (ret) {
-                       sbx.moveon = false;
+                       sbx.aborted = true;
                        str_liberror(ctx, ret, _("queueing per-AG fsmap work"));
                        break;
                }
@@ -232,10 +238,13 @@ xfs_scan_all_spacemaps(
 out:
        ret = workqueue_terminate(&wq);
        if (ret) {
-               sbx.moveon = false;
+               sbx.aborted = true;
                str_liberror(ctx, ret, _("finishing fsmap work"));
        }
        workqueue_destroy(&wq);
 
-       return sbx.moveon;
+       if (!ret && sbx.aborted)
+               ret = -1;
+
+       return ret;
 }
index c29c43a51c4a0d7dd3485c134a3a271f3efffb16..8a6d1e361580bc7c5eb33dad79a59c7c66b1cfa6 100644 (file)
@@ -7,15 +7,15 @@
 #define XFS_SCRUB_SPACEMAP_H_
 
 /*
- * Visit each space mapping in the filesystem.  Return true to continue
- * iteration or false to stop iterating and return to the caller.
+ * Visit each space mapping in the filesystem.  Return 0 to continue iteration
+ * or a positive error code to stop iterating and return to the caller.
  */
-typedef bool (*xfs_fsmap_iter_fn)(struct scrub_ctx *ctx, const char *descr,
+typedef int (*scrub_fsmap_iter_fn)(struct scrub_ctx *ctx,
                struct fsmap *fsr, void *arg);
 
-bool xfs_iterate_fsmap(struct scrub_ctx *ctx, const char *descr,
-               struct fsmap *keys, xfs_fsmap_iter_fn fn, void *arg);
-bool xfs_scan_all_spacemaps(struct scrub_ctx *ctx, xfs_fsmap_iter_fn fn,
+int scrub_iterate_fsmap(struct scrub_ctx *ctx, struct fsmap *keys,
+               scrub_fsmap_iter_fn fn, void *arg);
+int scrub_scan_all_spacemaps(struct scrub_ctx *ctx, scrub_fsmap_iter_fn fn,
                void *arg);
 
 #endif /* XFS_SCRUB_SPACEMAP_H_ */