From: Darrick J. Wong <djwong@xxxxxxxxxx> For metadata check calls, use the ioctl retry and freeze permission tracking in scrub_item that we created in the last patch. This enables us to move the check retry loop out of xfs_scrub_metadata and into its caller to remove a long backwards jump, and gets us closer to vectorizing scrub calls. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> Reviewed-by: Christoph Hellwig <hch@xxxxxx> --- scrub/scrub.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/scrub/scrub.c b/scrub/scrub.c index 8c6bf845f..69dfb1eb8 100644 --- a/scrub/scrub.c +++ b/scrub/scrub.c @@ -88,7 +88,6 @@ xfs_check_metadata( DEFINE_DESCR(dsc, ctx, format_scrub_descr); struct xfs_scrub_metadata meta = { }; enum xfrog_scrub_group group; - unsigned int tries = 0; int error; background_sleep(); @@ -116,7 +115,7 @@ xfs_check_metadata( descr_set(&dsc, &meta); dbg_printf("check %s flags %xh\n", descr_render(&dsc), meta.sm_flags); -retry: + error = -xfrog_scrub_metadata(xfdp, &meta); if (debug_tweak_on("XFS_SCRUB_FORCE_REPAIR") && !error) meta.sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; @@ -163,10 +162,8 @@ _("Filesystem is shut down, aborting.")); * we'll try the scan again, just in case the fs was busy. * Only retry so many times. */ - if (want_retry(&meta) && tries < 10) { - tries++; - goto retry; - } + if (want_retry(&meta) && scrub_item_schedule_retry(sri, scrub_type)) + return 0; /* Complain about incomplete or suspicious metadata. */ scrub_warn_incomplete_scrub(ctx, &dsc, &meta); @@ -304,6 +301,7 @@ scrub_item_check_file( int override_fd) { struct xfs_fd xfd; + struct scrub_item old_sri; struct xfs_fd *xfdp = &ctx->mnt; unsigned int scrub_type; int error; @@ -323,7 +321,14 @@ scrub_item_check_file( if (!(sri->sri_state[scrub_type] & SCRUB_ITEM_NEEDSCHECK)) continue; - error = xfs_check_metadata(ctx, xfdp, scrub_type, sri); + sri->sri_tries[scrub_type] = SCRUB_ITEM_MAX_RETRIES; + do { + memcpy(&old_sri, sri, sizeof(old_sri)); + error = xfs_check_metadata(ctx, xfdp, scrub_type, sri); + if (error) + return error; + } while (scrub_item_call_kernel_again(sri, scrub_type, + SCRUB_ITEM_NEEDSCHECK, &old_sri)); /* * Progress is counted by the inode for inode metadata; for