From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> Replace the moveon retuns in the inode iteration functions with a direct integer error return. While we're at it, drop the xfs_ prefix. Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- scrub/inodes.c | 131 ++++++++++++++++++++++++-------------------------------- scrub/inodes.h | 6 +-- scrub/phase3.c | 7 +-- scrub/phase5.c | 10 ++-- scrub/phase6.c | 5 +- 5 files changed, 70 insertions(+), 89 deletions(-) diff --git a/scrub/inodes.c b/scrub/inodes.c index bfc0a1e9..9fb9d1a5 100644 --- a/scrub/inodes.c +++ b/scrub/inodes.c @@ -47,7 +47,7 @@ * time (or fake it) into the bulkstat data. */ static void -xfs_iterate_inodes_range_check( +fill_in_bulkstat_holes( struct scrub_ctx *ctx, struct xfs_inumbers *inumbers, struct xfs_bulkstat *bstat) @@ -76,54 +76,66 @@ xfs_iterate_inodes_range_check( } } +/* BULKSTAT wrapper routines. */ +struct scan_inodes { + scrub_inode_iter_fn fn; + void *arg; + bool aborted; +}; + /* * Call into the filesystem for inode/bulkstat information and call our * iterator function. We'll try to fill the bulkstat information in batches, * but we also can detect iget failures. */ -static bool -xfs_iterate_inodes_ag( - struct scrub_ctx *ctx, - const char *descr, - void *fshandle, - uint32_t agno, - xfs_inode_iter_fn fn, +static void +scan_ag_inodes( + struct workqueue *wq, + xfs_agnumber_t agno, void *arg) { struct xfs_handle handle; + char descr[DESCR_BUFSZ]; struct xfs_inumbers_req *ireq; struct xfs_bulkstat_req *breq; - char idescr[DESCR_BUFSZ]; + struct scan_inodes *si = arg; + struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx; struct xfs_bulkstat *bs; struct xfs_inumbers *inumbers; - bool moveon = true; int i; int error; int stale_count = 0; - memcpy(&handle.ha_fsid, fshandle, sizeof(handle.ha_fsid)); + snprintf(descr, DESCR_BUFSZ, _("dev %d:%d AG %u inodes"), + major(ctx->fsinfo.fs_datadev), + minor(ctx->fsinfo.fs_datadev), + agno); + + memcpy(&handle.ha_fsid, ctx->fshandle, sizeof(handle.ha_fsid)); handle.ha_fid.fid_len = sizeof(xfs_fid_t) - sizeof(handle.ha_fid.fid_len); handle.ha_fid.fid_pad = 0; breq = xfrog_bulkstat_alloc_req(XFS_INODES_PER_CHUNK, 0); if (!breq) { - str_info(ctx, descr, _("Insufficient memory; giving up.")); - return false; + str_errno(ctx, descr); + si->aborted = true; + return; } ireq = xfrog_inumbers_alloc_req(1, 0); if (!ireq) { - str_info(ctx, descr, _("Insufficient memory; giving up.")); + str_errno(ctx, descr); free(breq); - return false; + si->aborted = true; + return; } inumbers = &ireq->inumbers[0]; xfrog_inumbers_set_ag(ireq, agno); /* Find the inode chunk & alloc mask */ error = xfrog_inumbers(&ctx->mnt, ireq); - while (!error && ireq->hdr.ocount > 0) { + while (!error && !si->aborted && ireq->hdr.ocount > 0) { /* * We can have totally empty inode chunks on filesystems where * there are more than 64 inodes per block. Skip these. @@ -141,19 +153,21 @@ xfs_iterate_inodes_ag( errbuf, DESCR_BUFSZ)); } - xfs_iterate_inodes_range_check(ctx, inumbers, breq->bulkstat); + fill_in_bulkstat_holes(ctx, inumbers, breq->bulkstat); /* Iterate all the inodes. */ for (i = 0, bs = breq->bulkstat; - i < inumbers->xi_alloccount; + !si->aborted && i < inumbers->xi_alloccount; i++, bs++) { handle.ha_fid.fid_ino = bs->bs_ino; handle.ha_fid.fid_gen = bs->bs_gen; - error = fn(ctx, &handle, bs, arg); + error = si->fn(ctx, &handle, bs, si->arg); switch (error) { case 0: break; - case ESTALE: + case ESTALE: { + char idescr[DESCR_BUFSZ]; + stale_count++; if (stale_count < 30) { ireq->hdr.ino = inumbers->xi_startino; @@ -164,17 +178,16 @@ xfs_iterate_inodes_ag( str_info(ctx, idescr, _("Changed too many times during scan; giving up.")); break; + } case XFS_ITERATE_INODES_ABORT: error = 0; /* fall thru */ default: - moveon = false; - errno = error; goto err; } if (xfs_scrub_excessive_errors(ctx)) { - moveon = false; - goto out; + si->aborted = true; + return; } } @@ -186,71 +199,41 @@ _("Changed too many times during scan; giving up.")); err: if (error) { str_liberror(ctx, error, descr); - moveon = false; + si->aborted = true; } free(ireq); free(breq); -out: - return moveon; -} - -/* BULKSTAT wrapper routines. */ -struct xfs_scan_inodes { - xfs_inode_iter_fn fn; - void *arg; - bool moveon; -}; - -/* Scan all the inodes in an AG. */ -static void -xfs_scan_ag_inodes( - struct workqueue *wq, - xfs_agnumber_t agno, - void *arg) -{ - struct xfs_scan_inodes *si = arg; - struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx; - char descr[DESCR_BUFSZ]; - bool moveon; - - snprintf(descr, DESCR_BUFSZ, _("dev %d:%d AG %u inodes"), - major(ctx->fsinfo.fs_datadev), - minor(ctx->fsinfo.fs_datadev), - agno); - - moveon = xfs_iterate_inodes_ag(ctx, descr, ctx->fshandle, agno, - si->fn, si->arg); - if (!moveon) - si->moveon = false; } -/* Scan all the inodes in a filesystem. */ -bool -xfs_scan_all_inodes( +/* + * Scan all the inodes in a filesystem. On error, this function will log + * an error message and return -1. + */ +int +scrub_scan_all_inodes( struct scrub_ctx *ctx, - xfs_inode_iter_fn fn, + scrub_inode_iter_fn fn, void *arg) { - struct xfs_scan_inodes si; + struct scan_inodes si = { + .fn = fn, + .arg = arg, + }; xfs_agnumber_t agno; struct workqueue wq; int ret; - si.moveon = true; - si.fn = fn; - si.arg = arg; - ret = workqueue_create(&wq, (struct xfs_mount *)ctx, scrub_nproc_workqueue(ctx)); if (ret) { str_liberror(ctx, ret, _("creating bulkstat workqueue")); - return false; + return -1; } for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) { - ret = workqueue_add(&wq, xfs_scan_ag_inodes, agno, &si); + ret = workqueue_add(&wq, scan_ag_inodes, agno, &si); if (ret) { - si.moveon = false; + si.aborted = true; str_liberror(ctx, ret, _("queueing bulkstat work")); break; } @@ -258,19 +241,17 @@ xfs_scan_all_inodes( ret = workqueue_terminate(&wq); if (ret) { - si.moveon = false; + si.aborted = true; str_liberror(ctx, ret, _("finishing bulkstat work")); } workqueue_destroy(&wq); - return si.moveon; + return si.aborted ? -1 : 0; } -/* - * Open a file by handle, or return a negative error code. - */ +/* Open a file by handle, returning either the fd or -1 on error. */ int -xfs_open_handle( +scrub_open_handle( struct xfs_handle *handle) { return open_by_fshandle(handle, sizeof(*handle), diff --git a/scrub/inodes.h b/scrub/inodes.h index 3341c6d9..5bedd55b 100644 --- a/scrub/inodes.h +++ b/scrub/inodes.h @@ -6,13 +6,13 @@ #ifndef XFS_SCRUB_INODES_H_ #define XFS_SCRUB_INODES_H_ -typedef int (*xfs_inode_iter_fn)(struct scrub_ctx *ctx, +typedef int (*scrub_inode_iter_fn)(struct scrub_ctx *ctx, struct xfs_handle *handle, struct xfs_bulkstat *bs, void *arg); #define XFS_ITERATE_INODES_ABORT (-1) -bool xfs_scan_all_inodes(struct scrub_ctx *ctx, xfs_inode_iter_fn fn, +int scrub_scan_all_inodes(struct scrub_ctx *ctx, scrub_inode_iter_fn fn, void *arg); -int xfs_open_handle(struct xfs_handle *handle); +int scrub_open_handle(struct xfs_handle *handle); #endif /* XFS_SCRUB_INODES_H_ */ diff --git a/scrub/phase3.c b/scrub/phase3.c index 48bcc21c..13601ed7 100644 --- a/scrub/phase3.c +++ b/scrub/phase3.c @@ -78,7 +78,7 @@ xfs_scrub_inode( /* Try to open the inode to pin it. */ if (S_ISREG(bstat->bs_mode)) { - fd = xfs_open_handle(handle); + fd = scrub_open_handle(handle); /* Stale inode means we scan the whole cluster again. */ if (fd < 0 && errno == ESTALE) return ESTALE; @@ -161,7 +161,6 @@ xfs_scan_inodes( struct scrub_inode_ctx ictx; uint64_t val; int err; - bool ret; ictx.moveon = true; err = ptcounter_alloc(scrub_nproc(ctx), &ictx.icount); @@ -170,8 +169,8 @@ xfs_scan_inodes( return false; } - ret = xfs_scan_all_inodes(ctx, xfs_scrub_inode, &ictx); - if (!ret) + err = scrub_scan_all_inodes(ctx, xfs_scrub_inode, &ictx); + if (err) ictx.moveon = false; if (!ictx.moveon) goto free; diff --git a/scrub/phase5.c b/scrub/phase5.c index 18056afd..3ee6df1b 100644 --- a/scrub/phase5.c +++ b/scrub/phase5.c @@ -264,7 +264,7 @@ xfs_scrub_connections( /* Open the dir, let the kernel try to reconnect it to the root. */ if (S_ISDIR(bstat->bs_mode)) { - fd = xfs_open_handle(handle); + fd = scrub_open_handle(handle); if (fd < 0) { if (errno == ESTALE) return ESTALE; @@ -360,7 +360,7 @@ xfs_scan_connections( struct scrub_ctx *ctx) { bool moveon = true; - bool ret; + int ret; if (ctx->errors_found || ctx->unfixable_errors) { str_info(ctx, ctx->mntpoint, @@ -372,9 +372,9 @@ _("Filesystem has errors, skipping connectivity checks.")); if (!moveon) return false; - ret = xfs_scan_all_inodes(ctx, xfs_scrub_connections, &moveon); - if (!ret) - moveon = false; + ret = scrub_scan_all_inodes(ctx, xfs_scrub_connections, &moveon); + if (ret) + return false; if (!moveon) return false; xfs_scrub_report_preen_triggers(ctx); diff --git a/scrub/phase6.c b/scrub/phase6.c index 7607001a..55b5a611 100644 --- a/scrub/phase6.c +++ b/scrub/phase6.c @@ -273,7 +273,7 @@ xfs_report_verify_inode( bstat->bs_ino, bstat->bs_gen, _(" (unlinked)")); /* Try to open the inode. */ - fd = xfs_open_handle(handle); + fd = scrub_open_handle(handle); if (fd < 0) { error = errno; if (error == ESTALE) @@ -530,7 +530,8 @@ xfs_report_verify_errors( return false; /* Scan for unlinked files. */ - return xfs_scan_all_inodes(ctx, xfs_report_verify_inode, vs); + ret = scrub_scan_all_inodes(ctx, xfs_report_verify_inode, vs); + return ret == 0; } /* Schedule a read-verify of a (data block) extent. */