From patchwork Tue Jul 30 01:03:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746086 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 886C279CC for ; Tue, 30 Jul 2024 01:03:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301422; cv=none; b=rEp8P5p3ND/YB7Ms2GbN1WQtnxCSDstv1PaPd1pHeIK6unaSfwSLmP4HGGLw75lSNGxEsvyLFv14y6934hHTnzblkh5mcxkDEMYkazVOO3JCCwMfxTjglII9t/TAdOz9dcjGcpqivoyNLTvnYTnIiM6rQPU8jN7RqGAZOPPdhqc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301422; c=relaxed/simple; bh=opD6L6YHRHr7csA6VNv+QS+M8WHwZDZ0QBXn470QoMo=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=t8DvCfLdBADtF3rdfVfFb/B5TNoGXBaTb5v/pNcWmoVibiyJUFjgoXxP556zl43XQy2gTqwFjovOZpZLJSEP7izJzs1hUHqtfngDQ1j8YZbWI3JJJyPhq7mo8B+ayTMD2ELHrnbvecCT8mUOkvwA+gPcBuqgnesf5ydIzwj/YTw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SHZ4JDDK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SHZ4JDDK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0E834C32786; Tue, 30 Jul 2024 01:03:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722301422; bh=opD6L6YHRHr7csA6VNv+QS+M8WHwZDZ0QBXn470QoMo=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=SHZ4JDDK039UIX6vbdDSz5xQXCCeL+qK4WbfAvy3aeowYM2hIhN9pY7iWuH1QVCtR BSBVx5GlJ7/tp0KoTbwYIHJ+uq7utdrbfbARc4nlJ/AmoX51GrAlNnQrvLKPR5GGgR EU/vzwTGO0OxtavJNoRg8RuE2qvQmXCrKpnSp95zNuEEvYtDovksP5zA3V/gp8OfrF yZzW2CE1nQydPcGAZezFu395WvgeZE4aoilDG9yOt8JgdlS0TAzCI/XdNETjtmspe7 5oO0L0RSvPXMLinuxt5FmJftAu0j0wKnBKJhmX9nEawWxQYuvVAAgMv5KAeeToEgRT Tn5+gN27MAQqA== Date: Mon, 29 Jul 2024 18:03:41 -0700 Subject: [PATCH 1/5] xfs_scrub: start tracking scrub state in scrub_item From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229846782.1348436.4643532435282964088.stgit@frogsfrogsfrogs> In-Reply-To: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> References: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Start using the scrub_item to track which metadata objects need checking by adding a new flag to the scrub_item state set. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- scrub/phase1.c | 3 + scrub/phase2.c | 12 +++-- scrub/phase3.c | 41 +++++----------- scrub/phase4.c | 16 +++--- scrub/phase5.c | 5 +- scrub/phase7.c | 5 ++ scrub/scrub.c | 147 +++++++++++++++++++------------------------------------- scrub/scrub.h | 28 ++++++++--- 8 files changed, 108 insertions(+), 149 deletions(-) diff --git a/scrub/phase1.c b/scrub/phase1.c index 1e56f9fb1..60a8db572 100644 --- a/scrub/phase1.c +++ b/scrub/phase1.c @@ -61,7 +61,8 @@ report_to_kernel( return 0; scrub_item_init_fs(&sri); - ret = scrub_meta_type(ctx, XFS_SCRUB_TYPE_HEALTHY, &sri); + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_HEALTHY); + ret = scrub_item_check(ctx, &sri); if (ret) return ret; diff --git a/scrub/phase2.c b/scrub/phase2.c index 4d90291ed..79b33dd04 100644 --- a/scrub/phase2.c +++ b/scrub/phase2.c @@ -75,7 +75,8 @@ scan_ag_metadata( * First we scrub and fix the AG headers, because we need * them to work well enough to check the AG btrees. */ - ret = scrub_ag_headers(ctx, &sri); + scrub_item_schedule_group(&sri, XFROG_SCRUB_GROUP_AGHEADER); + ret = scrub_item_check(ctx, &sri); if (ret) goto err; @@ -85,7 +86,8 @@ scan_ag_metadata( goto err; /* Now scrub the AG btrees. */ - ret = scrub_ag_metadata(ctx, &sri); + scrub_item_schedule_group(&sri, XFROG_SCRUB_GROUP_PERAG); + ret = scrub_item_check(ctx, &sri); if (ret) goto err; @@ -131,7 +133,8 @@ scan_fs_metadata( goto out; scrub_item_init_fs(&sri); - ret = scrub_meta_type(ctx, type, &sri); + scrub_item_schedule(&sri, type); + ret = scrub_item_check(ctx, &sri); if (ret) { sctl->aborted = true; goto out; @@ -189,7 +192,8 @@ phase2_func( * If errors occur, this function will log them and return nonzero. */ scrub_item_init_ag(&sri, 0); - ret = scrub_meta_type(ctx, XFS_SCRUB_TYPE_SB, &sri); + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_SB); + ret = scrub_item_check(ctx, &sri); if (ret) goto out_wq; ret = repair_item_completely(ctx, &sri); diff --git a/scrub/phase3.c b/scrub/phase3.c index fa2eef4de..09347c977 100644 --- a/scrub/phase3.c +++ b/scrub/phase3.c @@ -144,7 +144,8 @@ scrub_inode( fd = scrub_open_handle(handle); /* Scrub the inode. */ - error = scrub_file(ctx, fd, bstat, XFS_SCRUB_TYPE_INODE, &sri); + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_INODE); + error = scrub_item_check_file(ctx, &sri, fd); if (error) goto out; @@ -153,13 +154,10 @@ scrub_inode( goto out; /* Scrub all block mappings. */ - error = scrub_file(ctx, fd, bstat, XFS_SCRUB_TYPE_BMBTD, &sri); - if (error) - goto out; - error = scrub_file(ctx, fd, bstat, XFS_SCRUB_TYPE_BMBTA, &sri); - if (error) - goto out; - error = scrub_file(ctx, fd, bstat, XFS_SCRUB_TYPE_BMBTC, &sri); + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_BMBTD); + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_BMBTA); + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_BMBTC); + error = scrub_item_check_file(ctx, &sri, fd); if (error) goto out; @@ -177,27 +175,14 @@ scrub_inode( * content scrubbers. Better to have them return -ENOENT than miss * some coverage. */ - if (S_ISLNK(bstat->bs_mode) || !bstat->bs_mode) { - /* Check symlink contents. */ - error = scrub_file(ctx, fd, bstat, XFS_SCRUB_TYPE_SYMLINK, - &sri); - if (error) - goto out; - } - if (S_ISDIR(bstat->bs_mode) || !bstat->bs_mode) { - /* Check the directory entries. */ - error = scrub_file(ctx, fd, bstat, XFS_SCRUB_TYPE_DIR, &sri); - if (error) - goto out; - } + if (S_ISLNK(bstat->bs_mode) || !bstat->bs_mode) + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_SYMLINK); + if (S_ISDIR(bstat->bs_mode) || !bstat->bs_mode) + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_DIR); - /* Check all the extended attributes. */ - error = scrub_file(ctx, fd, bstat, XFS_SCRUB_TYPE_XATTR, &sri); - if (error) - goto out; - - /* Check parent pointers. */ - error = scrub_file(ctx, fd, bstat, XFS_SCRUB_TYPE_PARENT, &sri); + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_XATTR); + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_PARENT); + error = scrub_item_check_file(ctx, &sri, fd); if (error) goto out; diff --git a/scrub/phase4.c b/scrub/phase4.c index 230c559f0..3c51b38a5 100644 --- a/scrub/phase4.c +++ b/scrub/phase4.c @@ -143,9 +143,7 @@ phase4_func( * metadata. If repairs fails, we'll come back during phase 7. */ scrub_item_init_fs(&sri); - ret = scrub_meta_type(ctx, XFS_SCRUB_TYPE_FSCOUNTERS, &sri); - if (ret) - return ret; + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_FSCOUNTERS); /* * Repair possibly bad quota counts before starting other repairs, @@ -157,13 +155,13 @@ phase4_func( if (ret) return ret; - if (fsgeom.sick & XFS_FSOP_GEOM_SICK_QUOTACHECK) { - ret = scrub_meta_type(ctx, XFS_SCRUB_TYPE_QUOTACHECK, &sri); - if (ret) - return ret; - } + if (fsgeom.sick & XFS_FSOP_GEOM_SICK_QUOTACHECK) + scrub_item_schedule(&sri, XFS_SCRUB_TYPE_QUOTACHECK); - /* Repair counters before starting on the rest. */ + /* Check and repair counters before starting on the rest. */ + ret = scrub_item_check(ctx, &sri); + if (ret) + return ret; ret = repair_item_corruption(ctx, &sri); if (ret) return ret; diff --git a/scrub/phase5.c b/scrub/phase5.c index 6c9a518db..0df8c46e9 100644 --- a/scrub/phase5.c +++ b/scrub/phase5.c @@ -387,7 +387,6 @@ check_fs_label( struct fs_scan_item { struct scrub_item sri; bool *abortedp; - unsigned int scrub_type; }; /* Run one full-fs scan scrubber in this thread. */ @@ -412,7 +411,7 @@ fs_scan_worker( nanosleep(&tv, NULL); } - ret = scrub_meta_type(ctx, item->scrub_type, &item->sri); + ret = scrub_item_check(ctx, &item->sri); if (ret) { str_liberror(ctx, ret, _("checking fs scan metadata")); *item->abortedp = true; @@ -450,7 +449,7 @@ queue_fs_scan( return ret; } scrub_item_init_fs(&item->sri); - item->scrub_type = scrub_type; + scrub_item_schedule(&item->sri, scrub_type); item->abortedp = abortedp; ret = -workqueue_add(wq, fs_scan_worker, nr, item); diff --git a/scrub/phase7.c b/scrub/phase7.c index 02da6b42b..cd4501f72 100644 --- a/scrub/phase7.c +++ b/scrub/phase7.c @@ -10,6 +10,8 @@ #include #include "libfrog/paths.h" #include "libfrog/ptvar.h" +#include "libfrog/fsgeom.h" +#include "libfrog/scrub.h" #include "list.h" #include "xfs_scrub.h" #include "common.h" @@ -118,7 +120,8 @@ phase7_func( /* Check and fix the summary metadata. */ scrub_item_init_fs(&sri); - error = scrub_summary_metadata(ctx, &sri); + scrub_item_schedule_group(&sri, XFROG_SCRUB_GROUP_SUMMARY); + error = scrub_item_check(ctx, &sri); if (error) return error; error = repair_item_completely(ctx, &sri); diff --git a/scrub/scrub.c b/scrub/scrub.c index 5fc549f97..5aa36a964 100644 --- a/scrub/scrub.c +++ b/scrub/scrub.c @@ -86,9 +86,11 @@ xfs_check_metadata( bool is_inode) { DEFINE_DESCR(dsc, ctx, format_scrub_descr); + enum xfrog_scrub_group group; unsigned int tries = 0; int error; + group = xfrog_scrubbers[meta->sm_type].group; assert(!debug_tweak_on("XFS_SCRUB_NO_KERNEL")); assert(meta->sm_type < XFS_SCRUB_TYPE_NR); descr_set(&dsc, meta); @@ -165,7 +167,7 @@ _("Repairs are required.")); */ if (is_unoptimized(meta)) { if (ctx->mode != SCRUB_MODE_REPAIR) { - if (!is_inode) { + if (group != XFROG_SCRUB_GROUP_INODE) { /* AG or FS metadata, always warn. */ str_info(ctx, descr_render(&dsc), _("Optimization is possible.")); @@ -223,9 +225,10 @@ _("Optimizations of %s are possible."), _(xfrog_scrubbers[i].descr)); * Returns 0 for success. If errors occur, this function will log them and * return a positive error code. */ -int +static int scrub_meta_type( struct scrub_ctx *ctx, + struct xfs_fd *xfdp, unsigned int type, struct scrub_item *sri) { @@ -243,16 +246,20 @@ scrub_meta_type( break; case XFROG_SCRUB_GROUP_FS: case XFROG_SCRUB_GROUP_SUMMARY: + case XFROG_SCRUB_GROUP_ISCAN: case XFROG_SCRUB_GROUP_NONE: break; - default: - assert(0); + case XFROG_SCRUB_GROUP_INODE: + meta.sm_ino = sri->sri_ino; + meta.sm_gen = sri->sri_gen; break; } /* Check the item. */ - fix = xfs_check_metadata(ctx, &ctx->mnt, &meta, false); - progress_add(1); + fix = xfs_check_metadata(ctx, xfdp, &meta, false); + + if (xfrog_scrubbers[type].group != XFROG_SCRUB_GROUP_INODE) + progress_add(1); switch (fix) { case CHECK_ABORT: @@ -269,60 +276,54 @@ scrub_meta_type( } } -/* - * Scrub all metadata types that are assigned to the given XFROG_SCRUB_GROUP_*, - * saving corruption reports for later. This should not be used for - * XFROG_SCRUB_GROUP_INODE or for checking summary metadata. - */ -static bool -scrub_group( - struct scrub_ctx *ctx, - enum xfrog_scrub_group group, - struct scrub_item *sri) +/* Schedule scrub for all metadata of a given group. */ +void +scrub_item_schedule_group( + struct scrub_item *sri, + enum xfrog_scrub_group group) { - const struct xfrog_scrub_descr *sc; - unsigned int type; - - sc = xfrog_scrubbers; - for (type = 0; type < XFS_SCRUB_TYPE_NR; type++, sc++) { - int ret; + unsigned int scrub_type; - if (sc->group != group) + foreach_scrub_type(scrub_type) { + if (xfrog_scrubbers[scrub_type].group != group) continue; - - ret = scrub_meta_type(ctx, type, sri); - if (ret) - return ret; + scrub_item_schedule(sri, scrub_type); } - - return 0; } -/* Scrub each AG's header blocks. */ +/* Run all the incomplete scans on this scrub principal. */ int -scrub_ag_headers( +scrub_item_check_file( struct scrub_ctx *ctx, - struct scrub_item *sri) + struct scrub_item *sri, + int override_fd) { - return scrub_group(ctx, XFROG_SCRUB_GROUP_AGHEADER, sri); -} + struct xfs_fd xfd; + struct xfs_fd *xfdp = &ctx->mnt; + unsigned int scrub_type; + int error; -/* Scrub each AG's metadata btrees. */ -int -scrub_ag_metadata( - struct scrub_ctx *ctx, - struct scrub_item *sri) -{ - return scrub_group(ctx, XFROG_SCRUB_GROUP_PERAG, sri); -} + /* + * If the caller passed us a file descriptor for a scrub, use it + * instead of scrub-by-handle because this enables the kernel to skip + * costly inode btree lookups. + */ + if (override_fd >= 0) { + memcpy(&xfd, xfdp, sizeof(xfd)); + xfd.fd = override_fd; + xfdp = &xfd; + } -/* Scrub all FS summary metadata. */ -int -scrub_summary_metadata( - struct scrub_ctx *ctx, - struct scrub_item *sri) -{ - return scrub_group(ctx, XFROG_SCRUB_GROUP_SUMMARY, sri); + foreach_scrub_type(scrub_type) { + if (!(sri->sri_state[scrub_type] & SCRUB_ITEM_NEEDSCHECK)) + continue; + + error = scrub_meta_type(ctx, xfdp, scrub_type, sri); + if (error) + break; + } + + return error; } /* How many items do we have to check? */ @@ -374,54 +375,6 @@ scrub_estimate_iscan_work( return estimate; } -/* - * Scrub file metadata of some sort. If errors occur, this function will log - * them and return nonzero. - */ -int -scrub_file( - struct scrub_ctx *ctx, - int fd, - const struct xfs_bulkstat *bstat, - unsigned int type, - struct scrub_item *sri) -{ - struct xfs_scrub_metadata meta = {0}; - struct xfs_fd xfd; - struct xfs_fd *xfdp = &ctx->mnt; - enum check_outcome fix; - - assert(type < XFS_SCRUB_TYPE_NR); - assert(xfrog_scrubbers[type].group == XFROG_SCRUB_GROUP_INODE); - - meta.sm_type = type; - meta.sm_ino = bstat->bs_ino; - meta.sm_gen = bstat->bs_gen; - - /* - * If the caller passed us a file descriptor for a scrub, use it - * instead of scrub-by-handle because this enables the kernel to skip - * costly inode btree lookups. - */ - if (fd >= 0) { - memcpy(&xfd, xfdp, sizeof(xfd)); - xfd.fd = fd; - xfdp = &xfd; - } - - /* Scrub the piece of metadata. */ - fix = xfs_check_metadata(ctx, xfdp, &meta, true); - if (fix == CHECK_ABORT) - return ECANCELED; - if (fix == CHECK_DONE) { - scrub_item_clean_state(sri, type); - return 0; - } - - scrub_item_save_state(sri, type, meta.sm_flags); - return 0; -} - /* Dump a scrub item for debugging purposes. */ void scrub_item_dump( diff --git a/scrub/scrub.h b/scrub/scrub.h index 3ae0bfd29..1ac0d8aed 100644 --- a/scrub/scrub.h +++ b/scrub/scrub.h @@ -6,6 +6,8 @@ #ifndef XFS_SCRUB_SCRUB_H_ #define XFS_SCRUB_SCRUB_H_ +enum xfrog_scrub_group; + /* Online scrub and repair. */ enum check_outcome { CHECK_DONE, /* no further processing needed */ @@ -33,6 +35,9 @@ enum check_outcome { #define SCRUB_ITEM_XFAIL (XFS_SCRUB_OFLAG_XFAIL) /* (1 << 3) */ #define SCRUB_ITEM_XCORRUPT (XFS_SCRUB_OFLAG_XCORRUPT) /* (1 << 4) */ +/* This scrub type needs to be checked. */ +#define SCRUB_ITEM_NEEDSCHECK (1 << 5) + /* All of the state flags that we need to prioritize repair work. */ #define SCRUB_ITEM_REPAIR_ANY (SCRUB_ITEM_CORRUPT | \ SCRUB_ITEM_PREEN | \ @@ -96,13 +101,24 @@ scrub_item_init_file(struct scrub_item *sri, const struct xfs_bulkstat *bstat) void scrub_item_dump(struct scrub_item *sri, unsigned int group_mask, const char *tag); +static inline void +scrub_item_schedule(struct scrub_item *sri, unsigned int scrub_type) +{ + sri->sri_state[scrub_type] = SCRUB_ITEM_NEEDSCHECK; +} + +void scrub_item_schedule_group(struct scrub_item *sri, + enum xfrog_scrub_group group); +int scrub_item_check_file(struct scrub_ctx *ctx, struct scrub_item *sri, + int override_fd); + +static inline int +scrub_item_check(struct scrub_ctx *ctx, struct scrub_item *sri) +{ + return scrub_item_check_file(ctx, sri, -1); +} + void scrub_report_preen_triggers(struct scrub_ctx *ctx); -int scrub_ag_headers(struct scrub_ctx *ctx, struct scrub_item *sri); -int scrub_ag_metadata(struct scrub_ctx *ctx, struct scrub_item *sri); -int scrub_iscan_metadata(struct scrub_ctx *ctx, struct scrub_item *sri); -int scrub_summary_metadata(struct scrub_ctx *ctx, struct scrub_item *sri); -int scrub_meta_type(struct scrub_ctx *ctx, unsigned int type, - struct scrub_item *sri); bool can_scrub_fs_metadata(struct scrub_ctx *ctx); bool can_scrub_inode(struct scrub_ctx *ctx); From patchwork Tue Jul 30 01:03:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746087 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 536198BF0 for ; Tue, 30 Jul 2024 01:03:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301438; cv=none; b=bNC+R6y8ZK5NDov3HbQZpOhenW/h3ZuQGDEq7i7IaUvXpWv6uyw7xFdkAkt4u1hWHwgrdWjN6gjp2FkrIzg/oE9F5fUZTl0xJzn4vKFHT/sFXbSTdPz6e4mVIGkA/ox8pE/XD+lOzkqNCn2hAuekaG+dA8DczuK0nsVn40TZsD8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301438; c=relaxed/simple; bh=G3vN2xh6GYd6VPXdfqNhcp1LF95+GAe9XZ0GzRGl/nc=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XN6OyyqVTZaDmj/4M7WrpsDpS1F5B6V+cl7uDRzSf7on6W534NXAetsZZf9uk9eGb20uZmcUTnBH3Tpdzc4KLm1Wa2LqFcQmB707CqNKcqFQfHS6ZNxlhMUCRk53co/3YjqvcFxELHFtfxvOYsdmY008Qw43MP+0JSYW21HnYiU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eM5IVTgc; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eM5IVTgc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CC670C32786; Tue, 30 Jul 2024 01:03:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722301437; bh=G3vN2xh6GYd6VPXdfqNhcp1LF95+GAe9XZ0GzRGl/nc=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=eM5IVTgc5IsaWVb8rXIOxRn1p5gPhq0N9qUKBASt3FFUijekDNwvAMRIVMNDhif7z rhpitGCyDYCbqnBEo1Q4OvW74NtcChozDzmd5LtJRQVmJH+ITS6Z4YXsVZGBJ2tX6d rHJqKZ2uDrlXZpn7HFqKVE8QJ9B8k9dx5rRV44Gjy8wdRa6fxl6krYpzirrvAoorY4 C3RK4yxWPF9zx3BhofbcMPpqfCiVAFgef4WPm81TorwrJcqpT+7Q8gB1q94omqpLkP 4GHbs3Jj/NiRLjtwXs6WSx4ZuRG60SpMYFliStXMXSXuorI2SUulWPT0SL4goGq1+x QxCK9I5C7iSiA== Date: Mon, 29 Jul 2024 18:03:57 -0700 Subject: [PATCH 2/5] xfs_scrub: remove enum check_outcome From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229846798.1348436.2789704981653044177.stgit@frogsfrogsfrogs> In-Reply-To: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> References: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Get rid of this enumeration, and just do what we will directly. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- scrub/repair.c | 56 ++++++++++++++++++++++---------------------------- scrub/scrub.c | 63 +++++++++++++++++++++++++++++--------------------------- scrub/scrub.h | 8 ------- 3 files changed, 58 insertions(+), 69 deletions(-) diff --git a/scrub/repair.c b/scrub/repair.c index a3a8fb311..f888441aa 100644 --- a/scrub/repair.c +++ b/scrub/repair.c @@ -46,7 +46,7 @@ static const unsigned int repair_deps[XFS_SCRUB_TYPE_NR] = { #undef DEP /* Repair some metadata. */ -static enum check_outcome +static int xfs_repair_metadata( struct scrub_ctx *ctx, struct xfs_fd *xfdp, @@ -88,7 +88,7 @@ xfs_repair_metadata( } if (!is_corrupt(&meta) && repair_only) - return CHECK_RETRY; + return 0; memcpy(&oldm, &meta, sizeof(oldm)); oldm.sm_flags = sri->sri_state[scrub_type] & SCRUB_ITEM_REPAIR_ANY; @@ -112,12 +112,12 @@ xfs_repair_metadata( if (debug || verbose) str_info(ctx, descr_render(&dsc), _("Filesystem is busy, deferring repair.")); - return CHECK_RETRY; + return 0; case ESHUTDOWN: /* Filesystem is already shut down, abort. */ str_error(ctx, descr_render(&dsc), _("Filesystem is shut down, aborting.")); - return CHECK_ABORT; + return ECANCELED; case ENOTTY: case EOPNOTSUPP: /* @@ -129,7 +129,7 @@ _("Filesystem is shut down, aborting.")); if (is_unoptimized(&oldm) || debug_tweak_on("XFS_SCRUB_FORCE_REPAIR")) { scrub_item_clean_state(sri, scrub_type); - return CHECK_DONE; + return 0; } /* * If we're in no-complain mode, requeue the check for @@ -140,30 +140,30 @@ _("Filesystem is shut down, aborting.")); * again to see if another repair fixed it. */ if (!(repair_flags & XRM_FINAL_WARNING)) - return CHECK_RETRY; + return 0; fallthrough; case EINVAL: /* Kernel doesn't know how to repair this? */ str_corrupt(ctx, descr_render(&dsc), _("Don't know how to fix; offline repair required.")); scrub_item_clean_state(sri, scrub_type); - return CHECK_DONE; + return 0; case EROFS: /* Read-only filesystem, can't fix. */ if (verbose || debug || needs_repair(&oldm)) str_error(ctx, descr_render(&dsc), _("Read-only filesystem; cannot make changes.")); - return CHECK_ABORT; + return ECANCELED; case ENOENT: /* Metadata not present, just skip it. */ scrub_item_clean_state(sri, scrub_type); - return CHECK_DONE; + return 0; case ENOMEM: case ENOSPC: /* Don't care if preen fails due to low resources. */ if (is_unoptimized(&oldm) && !needs_repair(&oldm)) { scrub_item_clean_state(sri, scrub_type); - return CHECK_DONE; + return 0; } fallthrough; default: @@ -175,10 +175,10 @@ _("Read-only filesystem; cannot make changes.")); * trying to repair it, and bail out. */ if (!(repair_flags & XRM_FINAL_WARNING)) - return CHECK_RETRY; + return 0; str_liberror(ctx, error, descr_render(&dsc)); scrub_item_clean_state(sri, scrub_type); - return CHECK_DONE; + return 0; } /* @@ -201,7 +201,7 @@ _("Read-only filesystem; cannot make changes.")); * log the error loudly and don't try again. */ if (!(repair_flags & XRM_FINAL_WARNING)) - return CHECK_RETRY; + return 0; str_corrupt(ctx, descr_render(&dsc), _("Repair unsuccessful; offline repair required.")); } else if (xref_failed(&meta)) { @@ -219,7 +219,7 @@ _("Repair unsuccessful; offline repair required.")); if (verbose) str_info(ctx, descr_render(&dsc), _("Seems correct but cross-referencing failed; will keep checking.")); - return CHECK_RETRY; + return 0; } } else if (meta.sm_flags & XFS_SCRUB_OFLAG_NO_REPAIR_NEEDED) { if (verbose) @@ -242,7 +242,7 @@ _("Repair unsuccessful; offline repair required.")); } scrub_item_clean_state(sri, scrub_type); - return CHECK_DONE; + return 0; } /* @@ -543,6 +543,7 @@ repair_item_class( struct xfs_fd xfd; struct xfs_fd *xfdp = &ctx->mnt; unsigned int scrub_type; + int error = 0; if (ctx->mode < SCRUB_MODE_REPAIR) return 0; @@ -559,8 +560,6 @@ repair_item_class( } foreach_scrub_type(scrub_type) { - enum check_outcome fix; - if (scrub_excessive_errors(ctx)) return ECANCELED; @@ -576,22 +575,17 @@ repair_item_class( !repair_item_dependencies_ok(sri, scrub_type)) continue; - fix = xfs_repair_metadata(ctx, xfdp, scrub_type, sri, flags); - switch (fix) { - case CHECK_DONE: - if (!(flags & XRM_NOPROGRESS)) - progress_add(1); - continue; - case CHECK_ABORT: - return ECANCELED; - case CHECK_RETRY: - continue; - case CHECK_REPAIR: - abort(); - } + error = xfs_repair_metadata(ctx, xfdp, scrub_type, sri, flags); + if (error) + break; + + /* Maybe update progress if we fixed the problem. */ + if (!(flags & XRM_NOPROGRESS) && + !(sri->sri_state[scrub_type] & SCRUB_ITEM_REPAIR_ANY)) + progress_add(1); } - return 0; + return error; } /* diff --git a/scrub/scrub.c b/scrub/scrub.c index 5aa36a964..2c47542ee 100644 --- a/scrub/scrub.c +++ b/scrub/scrub.c @@ -78,12 +78,12 @@ scrub_warn_incomplete_scrub( } /* Do a read-only check of some metadata. */ -static enum check_outcome +static int xfs_check_metadata( struct scrub_ctx *ctx, struct xfs_fd *xfdp, struct xfs_scrub_metadata *meta, - bool is_inode) + struct scrub_item *sri) { DEFINE_DESCR(dsc, ctx, format_scrub_descr); enum xfrog_scrub_group group; @@ -106,17 +106,18 @@ xfs_check_metadata( break; case ENOENT: /* Metadata not present, just skip it. */ - return CHECK_DONE; + scrub_item_clean_state(sri, meta->sm_type); + return 0; case ESHUTDOWN: /* FS already crashed, give up. */ str_error(ctx, descr_render(&dsc), _("Filesystem is shut down, aborting.")); - return CHECK_ABORT; + return ECANCELED; case EIO: case ENOMEM: /* Abort on I/O errors or insufficient memory. */ str_liberror(ctx, error, descr_render(&dsc)); - return CHECK_ABORT; + return ECANCELED; case EDEADLOCK: case EBUSY: case EFSBADCRC: @@ -124,13 +125,16 @@ _("Filesystem is shut down, aborting.")); /* * The first two should never escape the kernel, * and the other two should be reported via sm_flags. + * Log it and move on. */ str_liberror(ctx, error, _("Kernel bug")); - return CHECK_DONE; + scrub_item_clean_state(sri, meta->sm_type); + return 0; default: - /* Operational error. */ + /* Operational error. Log it and move on. */ str_liberror(ctx, error, descr_render(&dsc)); - return CHECK_DONE; + scrub_item_clean_state(sri, meta->sm_type); + return 0; } /* @@ -153,12 +157,16 @@ _("Filesystem is shut down, aborting.")); */ if (is_corrupt(meta) || xref_disagrees(meta)) { if (ctx->mode < SCRUB_MODE_REPAIR) { + /* Dry-run mode, so log an error and forget it. */ str_corrupt(ctx, descr_render(&dsc), _("Repairs are required.")); - return CHECK_DONE; + scrub_item_clean_state(sri, meta->sm_type); + return 0; } - return CHECK_REPAIR; + /* Schedule repairs. */ + scrub_item_save_state(sri, meta->sm_type, meta->sm_flags); + return 0; } /* @@ -167,6 +175,7 @@ _("Repairs are required.")); */ if (is_unoptimized(meta)) { if (ctx->mode != SCRUB_MODE_REPAIR) { + /* Dry-run mode, so log an error and forget it. */ if (group != XFROG_SCRUB_GROUP_INODE) { /* AG or FS metadata, always warn. */ str_info(ctx, descr_render(&dsc), @@ -178,10 +187,13 @@ _("Optimization is possible.")); ctx->preen_triggers[meta->sm_type] = true; pthread_mutex_unlock(&ctx->lock); } - return CHECK_DONE; + scrub_item_clean_state(sri, meta->sm_type); + return 0; } - return CHECK_REPAIR; + /* Schedule optimizations. */ + scrub_item_save_state(sri, meta->sm_type, meta->sm_flags); + return 0; } /* @@ -191,11 +203,14 @@ _("Optimization is possible.")); * re-examine the object as repairs progress to see if the kernel will * deem it completely consistent at some point. */ - if (xref_failed(meta) && ctx->mode == SCRUB_MODE_REPAIR) - return CHECK_REPAIR; + if (xref_failed(meta) && ctx->mode == SCRUB_MODE_REPAIR) { + scrub_item_save_state(sri, meta->sm_type, meta->sm_flags); + return 0; + } /* Everything is ok. */ - return CHECK_DONE; + scrub_item_clean_state(sri, meta->sm_type); + return 0; } /* Bulk-notify user about things that could be optimized. */ @@ -235,7 +250,7 @@ scrub_meta_type( struct xfs_scrub_metadata meta = { .sm_type = type, }; - enum check_outcome fix; + int error; background_sleep(); @@ -256,24 +271,12 @@ scrub_meta_type( } /* Check the item. */ - fix = xfs_check_metadata(ctx, xfdp, &meta, false); + error = xfs_check_metadata(ctx, xfdp, &meta, sri); if (xfrog_scrubbers[type].group != XFROG_SCRUB_GROUP_INODE) progress_add(1); - switch (fix) { - case CHECK_ABORT: - return ECANCELED; - case CHECK_REPAIR: - scrub_item_save_state(sri, type, meta.sm_flags); - return 0; - case CHECK_DONE: - scrub_item_clean_state(sri, type); - return 0; - default: - /* CHECK_RETRY should never happen. */ - abort(); - } + return error; } /* Schedule scrub for all metadata of a given group. */ diff --git a/scrub/scrub.h b/scrub/scrub.h index 1ac0d8aed..24fb24449 100644 --- a/scrub/scrub.h +++ b/scrub/scrub.h @@ -8,14 +8,6 @@ enum xfrog_scrub_group; -/* Online scrub and repair. */ -enum check_outcome { - CHECK_DONE, /* no further processing needed */ - CHECK_REPAIR, /* schedule this for repairs */ - CHECK_ABORT, /* end program */ - CHECK_RETRY, /* repair failed, try again later */ -}; - /* * This flag boosts the repair priority of a scrub item when a dependent scrub * item is scheduled for repair. Use a separate flag to preserve the From patchwork Tue Jul 30 01:04:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746088 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DED9DBE40 for ; Tue, 30 Jul 2024 01:04:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301454; cv=none; b=Db1E5k11UCsB7zVVtY9kXUtr1/Sj3ghS/VkgBw1h/Tceo/kbBfpY1X4Hnx36x0jhJAQwxgt0GoEpVkNJ6t3PvJuKAy3l3EqRMjBStNebzI9d9Nyy1KaSHw17bljQypzw3+Q7VELmhXmCVKTvD3kgWFvv5GmnuGddi1XFf373rVI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301454; c=relaxed/simple; bh=OG6FPebVEnH0xUf6JT3xWyEOwPauPFZARCJyjvDaFBs=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=jlODytoSpsaf5l7SCn7W3+w3YimHzqL8V6OPSoAo3iIfXghkVhrVh6Awuz/sxPCc8ntYzJ6FCEoy8PSrvn+UOPAxRRVUJ+EqgAH83mao4dLIoZ2Ogh6XTPtsLm953ACJDxtjlmGrjewkv2h1aEMbFXMlvRkgJQWc44ibcXbLVig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ipuCMSAF; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ipuCMSAF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A7943C32786; Tue, 30 Jul 2024 01:04:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722301453; bh=OG6FPebVEnH0xUf6JT3xWyEOwPauPFZARCJyjvDaFBs=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=ipuCMSAF2aw6+opPWooc6hynEiUQhzkwQ4zE8l7+HXP+sQFl4tAtRY+/KqIScqvgS x78mBn14TVzrPsIM+IxKIEk2pO9NRwnSOopVp3Me2EjnPP/W3vmUOQGUsT+mr18/AI V0Wzi/Gwhx/gudTyJf6JIqwiTL1wN87DI+xzNORqKqmvyRp2KcSv+GbXUAwVsRnVGh U0WurMpgMv7YEU543VT07IvMllEnKfFmOTVnQ5F+afFQRmYxRsAQT84D6Ar5aRkroL S/8IKik6cvOnYaKImdNWPA/YWLjqttCsfI5Xywkv33ybMJb+U6owzIW8D7pX4/p0q0 EbvobbtSg9yaQ== Date: Mon, 29 Jul 2024 18:04:13 -0700 Subject: [PATCH 3/5] xfs_scrub: refactor scrub_meta_type out of existence From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229846813.1348436.4391986735487128685.stgit@frogsfrogsfrogs> In-Reply-To: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> References: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Remove this helper function since it's trivial now. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- scrub/scrub.c | 124 ++++++++++++++++++++++++--------------------------------- 1 file changed, 53 insertions(+), 71 deletions(-) diff --git a/scrub/scrub.c b/scrub/scrub.c index 2c47542ee..5f0cacbde 100644 --- a/scrub/scrub.c +++ b/scrub/scrub.c @@ -82,31 +82,51 @@ static int xfs_check_metadata( struct scrub_ctx *ctx, struct xfs_fd *xfdp, - struct xfs_scrub_metadata *meta, + unsigned int scrub_type, struct scrub_item *sri) { DEFINE_DESCR(dsc, ctx, format_scrub_descr); + struct xfs_scrub_metadata meta = { }; enum xfrog_scrub_group group; unsigned int tries = 0; int error; - group = xfrog_scrubbers[meta->sm_type].group; + background_sleep(); + + group = xfrog_scrubbers[scrub_type].group; + meta.sm_type = scrub_type; + switch (group) { + case XFROG_SCRUB_GROUP_AGHEADER: + case XFROG_SCRUB_GROUP_PERAG: + meta.sm_agno = sri->sri_agno; + break; + case XFROG_SCRUB_GROUP_FS: + case XFROG_SCRUB_GROUP_SUMMARY: + case XFROG_SCRUB_GROUP_ISCAN: + case XFROG_SCRUB_GROUP_NONE: + break; + case XFROG_SCRUB_GROUP_INODE: + meta.sm_ino = sri->sri_ino; + meta.sm_gen = sri->sri_gen; + break; + } + assert(!debug_tweak_on("XFS_SCRUB_NO_KERNEL")); - assert(meta->sm_type < XFS_SCRUB_TYPE_NR); - descr_set(&dsc, meta); + assert(scrub_type < XFS_SCRUB_TYPE_NR); + descr_set(&dsc, &meta); - dbg_printf("check %s flags %xh\n", descr_render(&dsc), meta->sm_flags); + dbg_printf("check %s flags %xh\n", descr_render(&dsc), meta.sm_flags); retry: - error = -xfrog_scrub_metadata(xfdp, meta); + error = -xfrog_scrub_metadata(xfdp, &meta); if (debug_tweak_on("XFS_SCRUB_FORCE_REPAIR") && !error) - meta->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; + meta.sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; switch (error) { case 0: /* No operational errors encountered. */ break; case ENOENT: /* Metadata not present, just skip it. */ - scrub_item_clean_state(sri, meta->sm_type); + scrub_item_clean_state(sri, scrub_type); return 0; case ESHUTDOWN: /* FS already crashed, give up. */ @@ -128,12 +148,12 @@ _("Filesystem is shut down, aborting.")); * Log it and move on. */ str_liberror(ctx, error, _("Kernel bug")); - scrub_item_clean_state(sri, meta->sm_type); + scrub_item_clean_state(sri, scrub_type); return 0; default: /* Operational error. Log it and move on. */ str_liberror(ctx, error, descr_render(&dsc)); - scrub_item_clean_state(sri, meta->sm_type); + scrub_item_clean_state(sri, scrub_type); return 0; } @@ -143,29 +163,29 @@ _("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) { + if (want_retry(&meta) && tries < 10) { tries++; goto retry; } /* Complain about incomplete or suspicious metadata. */ - scrub_warn_incomplete_scrub(ctx, &dsc, meta); + scrub_warn_incomplete_scrub(ctx, &dsc, &meta); /* * If we need repairs or there were discrepancies, schedule a * repair if desired, otherwise complain. */ - if (is_corrupt(meta) || xref_disagrees(meta)) { + if (is_corrupt(&meta) || xref_disagrees(&meta)) { if (ctx->mode < SCRUB_MODE_REPAIR) { /* Dry-run mode, so log an error and forget it. */ str_corrupt(ctx, descr_render(&dsc), _("Repairs are required.")); - scrub_item_clean_state(sri, meta->sm_type); + scrub_item_clean_state(sri, scrub_type); return 0; } /* Schedule repairs. */ - scrub_item_save_state(sri, meta->sm_type, meta->sm_flags); + scrub_item_save_state(sri, scrub_type, meta.sm_flags); return 0; } @@ -173,26 +193,26 @@ _("Repairs are required.")); * If we could optimize, schedule a repair if desired, * otherwise complain. */ - if (is_unoptimized(meta)) { + if (is_unoptimized(&meta)) { if (ctx->mode != SCRUB_MODE_REPAIR) { /* Dry-run mode, so log an error and forget it. */ if (group != XFROG_SCRUB_GROUP_INODE) { /* AG or FS metadata, always warn. */ str_info(ctx, descr_render(&dsc), _("Optimization is possible.")); - } else if (!ctx->preen_triggers[meta->sm_type]) { + } else if (!ctx->preen_triggers[scrub_type]) { /* File metadata, only warn once per type. */ pthread_mutex_lock(&ctx->lock); - if (!ctx->preen_triggers[meta->sm_type]) - ctx->preen_triggers[meta->sm_type] = true; + if (!ctx->preen_triggers[scrub_type]) + ctx->preen_triggers[scrub_type] = true; pthread_mutex_unlock(&ctx->lock); } - scrub_item_clean_state(sri, meta->sm_type); + scrub_item_clean_state(sri, scrub_type); return 0; } /* Schedule optimizations. */ - scrub_item_save_state(sri, meta->sm_type, meta->sm_flags); + scrub_item_save_state(sri, scrub_type, meta.sm_flags); return 0; } @@ -203,13 +223,13 @@ _("Optimization is possible.")); * re-examine the object as repairs progress to see if the kernel will * deem it completely consistent at some point. */ - if (xref_failed(meta) && ctx->mode == SCRUB_MODE_REPAIR) { - scrub_item_save_state(sri, meta->sm_type, meta->sm_flags); + if (xref_failed(&meta) && ctx->mode == SCRUB_MODE_REPAIR) { + scrub_item_save_state(sri, scrub_type, meta.sm_flags); return 0; } /* Everything is ok. */ - scrub_item_clean_state(sri, meta->sm_type); + scrub_item_clean_state(sri, scrub_type); return 0; } @@ -233,52 +253,6 @@ _("Optimizations of %s are possible."), _(xfrog_scrubbers[i].descr)); } } -/* - * Scrub a single XFS_SCRUB_TYPE_*, saving corruption reports for later. - * Do not call this function to repair file metadata. - * - * Returns 0 for success. If errors occur, this function will log them and - * return a positive error code. - */ -static int -scrub_meta_type( - struct scrub_ctx *ctx, - struct xfs_fd *xfdp, - unsigned int type, - struct scrub_item *sri) -{ - struct xfs_scrub_metadata meta = { - .sm_type = type, - }; - int error; - - background_sleep(); - - switch (xfrog_scrubbers[type].group) { - case XFROG_SCRUB_GROUP_AGHEADER: - case XFROG_SCRUB_GROUP_PERAG: - meta.sm_agno = sri->sri_agno; - break; - case XFROG_SCRUB_GROUP_FS: - case XFROG_SCRUB_GROUP_SUMMARY: - case XFROG_SCRUB_GROUP_ISCAN: - case XFROG_SCRUB_GROUP_NONE: - break; - case XFROG_SCRUB_GROUP_INODE: - meta.sm_ino = sri->sri_ino; - meta.sm_gen = sri->sri_gen; - break; - } - - /* Check the item. */ - error = xfs_check_metadata(ctx, xfdp, &meta, sri); - - if (xfrog_scrubbers[type].group != XFROG_SCRUB_GROUP_INODE) - progress_add(1); - - return error; -} - /* Schedule scrub for all metadata of a given group. */ void scrub_item_schedule_group( @@ -321,7 +295,15 @@ scrub_item_check_file( if (!(sri->sri_state[scrub_type] & SCRUB_ITEM_NEEDSCHECK)) continue; - error = scrub_meta_type(ctx, xfdp, scrub_type, sri); + error = xfs_check_metadata(ctx, xfdp, scrub_type, sri); + + /* + * Progress is counted by the inode for inode metadata; for + * everything else, it's counted for each scrub call. + */ + if (sri->sri_ino == -1ULL) + progress_add(1); + if (error) break; } From patchwork Tue Jul 30 01:04:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746089 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C173710E3 for ; Tue, 30 Jul 2024 01:04:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301469; cv=none; b=mH4f0O+2/TuWdsvSkV/YegMOVKkld/hxjPw4/Ze9vp3LEWP3a1lECnKyDUxPLF5iO//6q14+8LCn1zMJKDC0b2dd5HXIvVXuz197QPH2ybdOWayjn22ukBkz+BofKZlXkX50YkupKG5+RGL+nHImhKNxYCU50cyfnM1l1q8R9sM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301469; c=relaxed/simple; bh=oxmKAorrUZU8pgYbvCXRseLqLKXKH+XsN8VAqtT3E/g=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OwkrEu2UHJi1BMeSKJsk7voQkTlPE7NJCjT7vU0XqVSDS/OiPSSw8yfl7znoY65i0UvXYpj1aoQwX8thyXLgShv+csLO2A7rjloOSF8zXqtgMR075WhxEc+9u9+1wwYOb8p2dAJez5sw4LP8a+LIp4iCdESIFwdWfrLWhSlBzoI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ag3sAxUl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ag3sAxUl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8AC3EC32786; Tue, 30 Jul 2024 01:04:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722301469; bh=oxmKAorrUZU8pgYbvCXRseLqLKXKH+XsN8VAqtT3E/g=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=ag3sAxUlHrfJKJpXDM6AYss9bHe/Cy2DilMHv5p2ecjvVZxX3SORTzZ3SHYWWugNd Q7HkrKOKsRIcF2+pSgQSXV8sWbYk1FPytghobNymciyXV/owIyztI4hg9wWNQQ+Aoq QHdsmhz9Z6Q85dMHfF3ZbgZiIwM6ThgXmjZpkR2puTACsi4/gOtVHUTLTsusM+KxTY I/jXT7kZCh5/HE3ovPZEvQpdJCiIG7qmKnzgzQP/q5YuAWuXdlF9Qbnp+OQ0orER+o bbCuwuwnJiq2fTxdaK6mnoz9qQ7gKvcoIzdqUqZxGfgACl4kMyYf1G5s5QjXuQVewB 0/jQi109/4mPA== Date: Mon, 29 Jul 2024 18:04:28 -0700 Subject: [PATCH 4/5] xfs_scrub: hoist repair retry loop to repair_item_class From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229846828.1348436.3427780026764629216.stgit@frogsfrogsfrogs> In-Reply-To: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> References: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong For metadata repair calls, move the ioctl retry and freeze permission tracking into scrub_item. This enables us to move the repair retry loop out of xfs_repair_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 Reviewed-by: Christoph Hellwig --- scrub/repair.c | 21 ++++++++++++--------- scrub/scrub.c | 32 ++++++++++++++++++++++++++++++-- scrub/scrub.h | 6 ++++++ scrub/scrub_private.h | 14 ++++++++++++++ 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/scrub/repair.c b/scrub/repair.c index f888441aa..c427e6e95 100644 --- a/scrub/repair.c +++ b/scrub/repair.c @@ -58,7 +58,6 @@ xfs_repair_metadata( struct xfs_scrub_metadata oldm; DEFINE_DESCR(dsc, ctx, format_scrub_descr); bool repair_only; - unsigned int tries = 0; int error; /* @@ -100,7 +99,6 @@ xfs_repair_metadata( str_info(ctx, descr_render(&dsc), _("Attempting optimization.")); -retry: error = -xfrog_scrub_metadata(xfdp, &meta); switch (error) { case 0: @@ -187,10 +185,8 @@ _("Read-only filesystem; cannot make changes.")); * the repair 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; if (repair_flags & XRM_FINAL_WARNING) scrub_warn_incomplete_scrub(ctx, &dsc, &meta); @@ -541,6 +537,7 @@ repair_item_class( unsigned int flags) { struct xfs_fd xfd; + struct scrub_item old_sri; struct xfs_fd *xfdp = &ctx->mnt; unsigned int scrub_type; int error = 0; @@ -575,9 +572,15 @@ repair_item_class( !repair_item_dependencies_ok(sri, scrub_type)) continue; - error = xfs_repair_metadata(ctx, xfdp, scrub_type, sri, flags); - if (error) - break; + sri->sri_tries[scrub_type] = SCRUB_ITEM_MAX_RETRIES; + do { + memcpy(&old_sri, sri, sizeof(old_sri)); + error = xfs_repair_metadata(ctx, xfdp, scrub_type, sri, + flags); + if (error) + return error; + } while (scrub_item_call_kernel_again(sri, scrub_type, + repair_mask, &old_sri)); /* Maybe update progress if we fixed the problem. */ if (!(flags & XRM_NOPROGRESS) && diff --git a/scrub/scrub.c b/scrub/scrub.c index 5f0cacbde..8c6bf845f 100644 --- a/scrub/scrub.c +++ b/scrub/scrub.c @@ -268,6 +268,34 @@ scrub_item_schedule_group( } } +/* Decide if we call the kernel again to finish scrub/repair activity. */ +bool +scrub_item_call_kernel_again( + struct scrub_item *sri, + unsigned int scrub_type, + uint8_t work_mask, + const struct scrub_item *old) +{ + uint8_t statex; + + /* If there's nothing to do, we're done. */ + if (!(sri->sri_state[scrub_type] & work_mask)) + return false; + + /* + * We are willing to go again if the last call had any effect on the + * state of the scrub item that the caller cares about, if the freeze + * flag got set, or if the kernel asked us to try again... + */ + statex = sri->sri_state[scrub_type] ^ old->sri_state[scrub_type]; + if (statex & work_mask) + return true; + if (sri->sri_tries[scrub_type] != old->sri_tries[scrub_type]) + return true; + + return false; +} + /* Run all the incomplete scans on this scrub principal. */ int scrub_item_check_file( @@ -383,9 +411,9 @@ scrub_item_dump( unsigned int g = 1U << xfrog_scrubbers[i].group; if (g & group_mask) - printf("[%u]: type '%s' state 0x%x\n", i, + printf("[%u]: type '%s' state 0x%x tries %u\n", i, xfrog_scrubbers[i].name, - sri->sri_state[i]); + sri->sri_state[i], sri->sri_tries[i]); } fflush(stdout); } diff --git a/scrub/scrub.h b/scrub/scrub.h index 24fb24449..246c923f4 100644 --- a/scrub/scrub.h +++ b/scrub/scrub.h @@ -45,6 +45,9 @@ enum xfrog_scrub_group; SCRUB_ITEM_XFAIL | \ SCRUB_ITEM_XCORRUPT) +/* Maximum number of times we'll retry a scrub ioctl call. */ +#define SCRUB_ITEM_MAX_RETRIES 10 + struct scrub_item { /* * Information we need to call the scrub and repair ioctls. Per-AG @@ -58,6 +61,9 @@ struct scrub_item { /* Scrub item state flags, one for each XFS_SCRUB_TYPE. */ __u8 sri_state[XFS_SCRUB_TYPE_NR]; + + /* Track scrub and repair call retries for each scrub type. */ + __u8 sri_tries[XFS_SCRUB_TYPE_NR]; }; #define foreach_scrub_type(loopvar) \ diff --git a/scrub/scrub_private.h b/scrub/scrub_private.h index 53372e1f3..234b30ef2 100644 --- a/scrub/scrub_private.h +++ b/scrub/scrub_private.h @@ -89,4 +89,18 @@ scrub_item_type_boosted( return sri->sri_state[scrub_type] & SCRUB_ITEM_BOOST_REPAIR; } +/* Decide if we want to retry this operation and update bookkeeping if yes. */ +static inline bool +scrub_item_schedule_retry(struct scrub_item *sri, unsigned int scrub_type) +{ + if (sri->sri_tries[scrub_type] == 0) + return false; + sri->sri_tries[scrub_type]--; + return true; +} + +bool scrub_item_call_kernel_again(struct scrub_item *sri, + unsigned int scrub_type, uint8_t work_mask, + const struct scrub_item *old); + #endif /* XFS_SCRUB_SCRUB_PRIVATE_H_ */ From patchwork Tue Jul 30 01:04:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746090 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 762BA4A28 for ; Tue, 30 Jul 2024 01:04:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301485; cv=none; b=YC8zHDmLcnaMt34Y3VOp5L2crSEAXrJDkuE4VAmuZCQhquwPplICxTp9DWP2upk8TPLKPLD+vKdCZS02o5JZj52ThuTU1dCLyfr9FuZvubpSLwwwxJ6ytq82W9koWZ9XLNH3j040hmTPmcwQZOkVP8wZCd5s6c5CEOFS/NEjqIc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301485; c=relaxed/simple; bh=ZKSHvm0PqwCQMo+V+B4gBlm5xpkY23jRgCMEPkg7qfA=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZtKbo1hJ42nepOOzeKYleEFMf4HJXNIUcBdXExkYQDg1C+Z++1CtMCL3eBSWZcqgeDhHLJ6ZzuTnmoLI0zvDaXXoqCcDxvn6r4X2nkH5PaMJ3kS5v3rv2TeLQDUl+i5QHjeTEcUOQn2OniOGzAuhmV1LxIImxdf11Y/vpX39Gvc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mfy4jOjP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mfy4jOjP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 48996C32786; Tue, 30 Jul 2024 01:04:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722301485; bh=ZKSHvm0PqwCQMo+V+B4gBlm5xpkY23jRgCMEPkg7qfA=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=mfy4jOjP7U/PL660Irn0KVI1uKTYwyZO83rZljRUci+hucs2w1qnib+UGIClD4J9w bJ3f6AV/HxbXCEqmk5n1Ns0oKc8yx+6sCWPrhKpYaFOqPVikijTUw0gKyCA/Y0xP3l HBD3Rz+7xGSI2vRKcbwaEtItZii61DOZESuIEEZbm5qcI/Xwb9SAVTbocBPPSIf4vY Xsu5ytE0ZFyAnrpWVvofxF6Teh/cQEbxUElvqeq0q8FR1b0P+GVFKShf+2Yv9kpiz9 PqQQURTfGBj2H6o+KAqrTOsYppvIyHbDMDGhO1D8XvYlFugSwwcowExjgb7JscLqM3 o8HkvkpZ9kkug== Date: Mon, 29 Jul 2024 18:04:44 -0700 Subject: [PATCH 5/5] xfs_scrub: hoist scrub retry loop to scrub_item_check_file From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229846843.1348436.5577053768645865625.stgit@frogsfrogsfrogs> In-Reply-To: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> References: <172229846763.1348436.17732340268176889954.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong 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 Reviewed-by: Christoph Hellwig --- 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