From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> Replace the moveon returns in the phase 2 code with a direct integer error return. Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- scrub/phase2.c | 88 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/scrub/phase2.c b/scrub/phase2.c index 7388b8e2..81b2b3dc 100644 --- a/scrub/phase2.c +++ b/scrub/phase2.c @@ -19,13 +19,13 @@ /* Scrub each AG's metadata btrees. */ static void -xfs_scan_ag_metadata( +scan_ag_metadata( struct workqueue *wq, xfs_agnumber_t agno, void *arg) { struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx; - bool *pmoveon = arg; + bool *aborted = arg; struct action_list alist; struct action_list immediate_alist; unsigned long long broken_primaries; @@ -33,6 +33,9 @@ xfs_scan_ag_metadata( char descr[DESCR_BUFSZ]; int ret; + if (*aborted) + return; + action_list_init(&alist); action_list_init(&immediate_alist); snprintf(descr, DESCR_BUFSZ, _("AG %u"), agno); @@ -84,48 +87,52 @@ _("Filesystem might not be repairable.")); /* Everything else gets fixed during phase 4. */ action_list_defer(ctx, agno, &alist); - return; err: - *pmoveon = false; + *aborted = true; } /* Scrub whole-FS metadata btrees. */ static void -xfs_scan_fs_metadata( +scan_fs_metadata( struct workqueue *wq, xfs_agnumber_t agno, void *arg) { struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx; - bool *pmoveon = arg; + bool *aborted = arg; struct action_list alist; int ret; + if (*aborted) + return; + action_list_init(&alist); ret = xfs_scrub_fs_metadata(ctx, &alist); - if (ret) - *pmoveon = false; + if (ret) { + *aborted = true; + return; + } action_list_defer(ctx, agno, &alist); } /* Scan all filesystem metadata. */ -bool -xfs_scan_metadata( +int +phase2_func( struct scrub_ctx *ctx) { struct action_list alist; struct workqueue wq; xfs_agnumber_t agno; - bool moveon = true; - int ret; + bool aborted = false; + int ret, ret2; ret = workqueue_create(&wq, (struct xfs_mount *)ctx, scrub_nproc_workqueue(ctx)); if (ret) { str_liberror(ctx, ret, _("creating scrub workqueue")); - return false; + return ret; } /* @@ -135,48 +142,53 @@ xfs_scan_metadata( */ action_list_init(&alist); ret = xfs_scrub_primary_super(ctx, &alist); - if (ret) { - moveon = false; + if (ret) goto out; - } ret = action_list_process_or_defer(ctx, 0, &alist); - if (ret) { - moveon = false; + if (ret) goto out; - } - for (agno = 0; moveon && agno < ctx->mnt.fsgeom.agcount; agno++) { - ret = workqueue_add(&wq, xfs_scan_ag_metadata, agno, &moveon); + for (agno = 0; !aborted && agno < ctx->mnt.fsgeom.agcount; agno++) { + ret = workqueue_add(&wq, scan_ag_metadata, agno, &aborted); if (ret) { - moveon = false; str_liberror(ctx, ret, _("queueing per-AG scrub work")); goto out; } } - if (!moveon) + if (aborted) goto out; - ret = workqueue_add(&wq, xfs_scan_fs_metadata, 0, &moveon); + ret = workqueue_add(&wq, scan_fs_metadata, 0, &aborted); if (ret) { - moveon = false; str_liberror(ctx, ret, _("queueing per-FS scrub work")); goto out; } out: - ret = workqueue_terminate(&wq); - if (ret) { - moveon = false; - str_liberror(ctx, ret, _("finishing scrub work")); + ret2 = workqueue_terminate(&wq); + if (ret2) { + str_liberror(ctx, ret2, _("finishing scrub work")); + if (!ret && ret2) + ret = ret2; } workqueue_destroy(&wq); - return moveon; + + if (!ret && aborted) + ret = ECANCELED; + return ret; } -/* Estimate how much work we're going to do. */ bool -xfs_estimate_metadata_work( +xfs_scan_metadata( + struct scrub_ctx *ctx) +{ + return phase2_func(ctx) == 0; +} + +/* Estimate how much work we're going to do. */ +int +phase2_estimate( struct scrub_ctx *ctx, uint64_t *items, unsigned int *nr_threads, @@ -185,5 +197,15 @@ xfs_estimate_metadata_work( *items = scrub_estimate_ag_work(ctx); *nr_threads = scrub_nproc(ctx); *rshift = 0; - return true; + return 0; +} + +bool +xfs_estimate_metadata_work( + struct scrub_ctx *ctx, + uint64_t *items, + unsigned int *nr_threads, + int *rshift) +{ + return phase2_estimate(ctx, items, nr_threads, rshift) == 0; }