From patchwork Fri Dec 30 22:17:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085061 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64833C4332F for ; Sat, 31 Dec 2022 00:09:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235791AbiLaAJl (ORCPT ); Fri, 30 Dec 2022 19:09:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235673AbiLaAJj (ORCPT ); Fri, 30 Dec 2022 19:09:39 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12DB31E3CA for ; Fri, 30 Dec 2022 16:09:39 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id C1BC9B81DF6 for ; Sat, 31 Dec 2022 00:09:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6C250C433D2; Sat, 31 Dec 2022 00:09:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672445376; bh=jkJrPfaiuHL8SBWQKChxqj0T+/zKQ1+mSK3c1KjOeyE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=PFUFj/S7XsxESHLJt6oVQZdglQlh4Y7khhHSOYvpyCIn9cR58i4kFRUzmezx7d41e qcBcLVD6SNu6DCUmHqHHpnNVJj0blegShv2hj2XmgCth9+uNk0S/JEegIl/+aUIOCZ KYVBXXsQLu9IaGMZvP6Cp59lnyEHxQkRiFshJmiIxznrpBEbw7wrXIKn2mUf25bo7Y qgl/xibNXMf7NWl8uCtllqjwl8CDlR1jOesL5KzF27tZmy018vAacC2K+gkXUjNRkT prJ7kWfAGdxl4rBt00BpGrFRw0a5pPukvas23/sA7CbPxCMq50HYk64jUJ9Qkq330t 92hiNbc7XGM9g== Subject: [PATCH 1/3] xfs: report inode link count health From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:35 -0800 Message-ID: <167243865515.709394.17529757205831816215.stgit@magnolia> In-Reply-To: <167243865502.709394.13215707195694339795.stgit@magnolia> References: <167243865502.709394.13215707195694339795.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Report the health of inode link counts. Signed-off-by: Darrick J. Wong --- libxfs/xfs_fs.h | 1 + libxfs/xfs_health.h | 4 +++- spaceman/health.c | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 6612c89944d..2f9f13ba75b 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -196,6 +196,7 @@ struct xfs_fsop_geom { #define XFS_FSOP_GEOM_SICK_RT_BITMAP (1 << 4) /* realtime bitmap */ #define XFS_FSOP_GEOM_SICK_RT_SUMMARY (1 << 5) /* realtime summary */ #define XFS_FSOP_GEOM_SICK_QUOTACHECK (1 << 6) /* quota counts */ +#define XFS_FSOP_GEOM_SICK_NLINKS (1 << 7) /* inode link counts */ /* Output for XFS_FS_COUNTS */ typedef struct xfs_fsop_counts { diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h index 1dea286bb15..5571f6cb253 100644 --- a/libxfs/xfs_health.h +++ b/libxfs/xfs_health.h @@ -42,6 +42,7 @@ struct xfs_fsop_geom; #define XFS_SICK_FS_GQUOTA (1 << 2) /* group quota */ #define XFS_SICK_FS_PQUOTA (1 << 3) /* project quota */ #define XFS_SICK_FS_QUOTACHECK (1 << 4) /* quota counts */ +#define XFS_SICK_FS_NLINKS (1 << 5) /* inode link counts */ /* Observable health issues for realtime volume metadata. */ #define XFS_SICK_RT_BITMAP (1 << 0) /* realtime bitmap */ @@ -74,7 +75,8 @@ struct xfs_fsop_geom; XFS_SICK_FS_UQUOTA | \ XFS_SICK_FS_GQUOTA | \ XFS_SICK_FS_PQUOTA | \ - XFS_SICK_FS_QUOTACHECK) + XFS_SICK_FS_QUOTACHECK | \ + XFS_SICK_FS_NLINKS) #define XFS_SICK_RT_PRIMARY (XFS_SICK_RT_BITMAP | \ XFS_SICK_RT_SUMMARY) diff --git a/spaceman/health.c b/spaceman/health.c index 3318f9d1a7f..88b12c0b0ea 100644 --- a/spaceman/health.c +++ b/spaceman/health.c @@ -76,6 +76,10 @@ static const struct flag_map fs_flags[] = { .mask = XFS_FSOP_GEOM_SICK_QUOTACHECK, .descr = "quota counts", }, + { + .mask = XFS_FSOP_GEOM_SICK_NLINKS, + .descr = "inode link counts", + }, {0}, }; From patchwork Fri Dec 30 22:17:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085062 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 52AC8C4332F for ; Sat, 31 Dec 2022 00:09:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235863AbiLaAJy (ORCPT ); Fri, 30 Dec 2022 19:09:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54194 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231164AbiLaAJx (ORCPT ); Fri, 30 Dec 2022 19:09:53 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 03D5F1E3C3 for ; Fri, 30 Dec 2022 16:09:53 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 911A361CD5 for ; Sat, 31 Dec 2022 00:09:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id ED187C433EF; Sat, 31 Dec 2022 00:09:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672445392; bh=Wnfm5jaRBmblsWfXoifqnQ0vy1UiSF7rMCg5jv7M3xU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=MnwP9tmeZageuCxrKy7mKh2pLmXwU72mm/jAgiDDfTyMvM8KPoX6NcqQtH6Ll8rGc sXl2YkRRyo/a42vVUI7N8SAN80ai5svRM+qhq+BZgtyRF9AILZCk9/UgBji4zN+6US TPC9sC0HVZ0yHTtaY89TZ2tU/VsvH23WHIegYk+BXqua3K/oyFxlvNlh/sNukpMpQQ D0YqGk8ZakKREQXi97a1itZZU4el+NmxlTnN48Ivh4x3LVwDWWwbLfBJdAJtc7OozQ PqUYekewt6RSKDG2jmIzwlQc3QL87N4Bcu5GDRqB4Oo+bxBMzRrM7XbIzFJwbUQsNV TcVrXLZ7wKXEg== Subject: [PATCH 2/3] xfs: teach scrub to check file nlinks From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:35 -0800 Message-ID: <167243865528.709394.5932602557148789175.stgit@magnolia> In-Reply-To: <167243865502.709394.13215707195694339795.stgit@magnolia> References: <167243865502.709394.13215707195694339795.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Copy-pasta the online quotacheck code to check inode link counts too. Signed-off-by: Darrick J. Wong --- libfrog/scrub.c | 5 +++++ libxfs/xfs_da_format.h | 11 +++++++++++ libxfs/xfs_dir2.c | 6 ++++++ libxfs/xfs_dir2.h | 1 + libxfs/xfs_fs.h | 3 ++- man/man2/ioctl_xfs_scrub_metadata.2 | 4 ++++ repair/phase6.c | 4 ---- 7 files changed, 29 insertions(+), 5 deletions(-) diff --git a/libfrog/scrub.c b/libfrog/scrub.c index 3718d56eae3..95daa78ba65 100644 --- a/libfrog/scrub.c +++ b/libfrog/scrub.c @@ -139,6 +139,11 @@ const struct xfrog_scrub_descr xfrog_scrubbers[XFS_SCRUB_TYPE_NR] = { .descr = "quota counters", .group = XFROG_SCRUB_GROUP_ISCAN, }, + [XFS_SCRUB_TYPE_NLINKS] = { + .name = "nlinks", + .descr = "inode link counts", + .group = XFROG_SCRUB_GROUP_ISCAN, + }, }; /* Invoke the scrub ioctl. Returns zero or negative error code. */ diff --git a/libxfs/xfs_da_format.h b/libxfs/xfs_da_format.h index 25e2841084e..9d332415e0b 100644 --- a/libxfs/xfs_da_format.h +++ b/libxfs/xfs_da_format.h @@ -159,6 +159,17 @@ struct xfs_da3_intnode { #define XFS_DIR3_FT_MAX 9 +#define XFS_DIR3_FTYPE_STR \ + { XFS_DIR3_FT_UNKNOWN, "unknown" }, \ + { XFS_DIR3_FT_REG_FILE, "file" }, \ + { XFS_DIR3_FT_DIR, "directory" }, \ + { XFS_DIR3_FT_CHRDEV, "char" }, \ + { XFS_DIR3_FT_BLKDEV, "block" }, \ + { XFS_DIR3_FT_FIFO, "fifo" }, \ + { XFS_DIR3_FT_SOCK, "sock" }, \ + { XFS_DIR3_FT_SYMLINK, "symlink" }, \ + { XFS_DIR3_FT_WHT, "whiteout" } + /* * Byte offset in data block and shortform entry. */ diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index d6a192963f5..033b6e4c475 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -24,6 +24,12 @@ const struct xfs_name xfs_name_dotdot = { .type = XFS_DIR3_FT_DIR, }; +const struct xfs_name xfs_name_dot = { + .name = (unsigned char *)".", + .len = 1, + .type = XFS_DIR3_FT_DIR, +}; + /* * Convert inode mode to directory entry filetype */ diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index dd39f17dd9a..15a36cf7ae8 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -22,6 +22,7 @@ struct xfs_dir3_icfree_hdr; struct xfs_dir3_icleaf_hdr; extern const struct xfs_name xfs_name_dotdot; +extern const struct xfs_name xfs_name_dot; /* * Convert inode mode to directory entry filetype diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 2f9f13ba75b..3885c56078f 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -710,9 +710,10 @@ struct xfs_scrub_metadata { #define XFS_SCRUB_TYPE_PQUOTA 23 /* project quotas */ #define XFS_SCRUB_TYPE_FSCOUNTERS 24 /* fs summary counters */ #define XFS_SCRUB_TYPE_QUOTACHECK 25 /* quota counters */ +#define XFS_SCRUB_TYPE_NLINKS 26 /* inode link counts */ /* Number of scrub subcommands. */ -#define XFS_SCRUB_TYPE_NR 26 +#define XFS_SCRUB_TYPE_NR 27 /* i: Repair this metadata. */ #define XFS_SCRUB_IFLAG_REPAIR (1u << 0) diff --git a/man/man2/ioctl_xfs_scrub_metadata.2 b/man/man2/ioctl_xfs_scrub_metadata.2 index 42bf1e1cac5..db238de1bb5 100644 --- a/man/man2/ioctl_xfs_scrub_metadata.2 +++ b/man/man2/ioctl_xfs_scrub_metadata.2 @@ -164,6 +164,10 @@ Examine all user, group, or project quota records for corruption. .B XFS_SCRUB_TYPE_FSCOUNTERS Examine all filesystem summary counters (free blocks, inode count, free inode count) for errors. + +.TP +.B XFS_SCRUB_TYPE_NLINKS +Scan all inodes in the filesystem to verify each file's link count. .RE .PD 1 diff --git a/repair/phase6.c b/repair/phase6.c index 0be2c9c9705..a7f658d4267 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -23,10 +23,6 @@ static struct cred zerocr; static struct fsxattr zerofsx; static xfs_ino_t orphanage_ino; -static struct xfs_name xfs_name_dot = {(unsigned char *)".", - 1, - XFS_DIR3_FT_DIR}; - /* * Data structures used to keep track of directories where the ".." * entries are updated. These must be rebuilt after the initial pass From patchwork Fri Dec 30 22:17:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085063 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9517C4332F for ; Sat, 31 Dec 2022 00:10:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235673AbiLaAKM (ORCPT ); Fri, 30 Dec 2022 19:10:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54276 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231164AbiLaAKL (ORCPT ); Fri, 30 Dec 2022 19:10:11 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0608A1CB3E for ; Fri, 30 Dec 2022 16:10:10 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id BB9C9B81DF6 for ; Sat, 31 Dec 2022 00:10:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7EFD9C433EF; Sat, 31 Dec 2022 00:10:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672445407; bh=mXsZqKDDRl/pVY3Gs0yBZiSTdtMqQl6sJxUXiZotcJo=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=pTcUiD4GGIwj+BNx6G1lijDvzSwHd7EAfFgJ1ty2zsU+aqux/2HecMwyDD0HQrbM/ Nsomc4KLekBGE8teAP21mDmyhqQzUBwgXTuYudqNRJdsGJPHoeXmliAqG1FFyJ7XWY WS8kYDYS9IZzZdek4CX8rKTdZDtRLi3Woi2RzZbUzxIRRbDNtOa8rDEG0/zlHw2qUi XgBthKv9CQCaMvXrqfdFSwK44ISOuB7JuRPkfAN7iEJLndUir2o+YRlD69GEUQ4Tf9 7p8ENfpF9CVCO1vNkI0u2qctwD4Uq6QhEsC9OrmxITjG6wk1DeyJqcWJFpYv4Ov3PZ mWW2gdSp6cW9Q== Subject: [PATCH 3/3] xfs_scrub: use multiple threads to run in-kernel metadata scrubs that scan inodes From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:35 -0800 Message-ID: <167243865542.709394.18210123102047724459.stgit@magnolia> In-Reply-To: <167243865502.709394.13215707195694339795.stgit@magnolia> References: <167243865502.709394.13215707195694339795.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Instead of running the inode link count and quotacheck scanners in serial, run them in parallel, with a slight delay to stagger the work to reduce inode resource contention. Signed-off-by: Darrick J. Wong --- scrub/phase5.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- scrub/scrub.c | 18 ++++--- scrub/scrub.h | 1 3 files changed, 138 insertions(+), 17 deletions(-) diff --git a/scrub/phase5.c b/scrub/phase5.c index 123e3751ca1..622e58138db 100644 --- a/scrub/phase5.c +++ b/scrub/phase5.c @@ -383,12 +383,137 @@ check_fs_label( return error; } +typedef int (*iscan_item_fn)(struct scrub_ctx *, struct action_list *); + +struct iscan_item { + struct action_list alist; + bool *abortedp; + iscan_item_fn scrub_fn; +}; + +/* Run one inode-scan scrubber in this thread. */ +static void +iscan_worker( + struct workqueue *wq, + xfs_agnumber_t nr, + void *arg) +{ + struct timespec tv; + struct iscan_item *item = arg; + struct scrub_ctx *ctx = wq->wq_ctx; + int ret; + + /* + * Delay each successive iscan by a second so that the threads are less + * likely to contend on the inode buffers. + */ + if (nr) { + tv.tv_sec = nr; + tv.tv_nsec = 0; + nanosleep(&tv, NULL); + } + + ret = item->scrub_fn(ctx, &item->alist); + if (ret) { + str_liberror(ctx, ret, _("checking iscan metadata")); + *item->abortedp = true; + goto out; + } + + ret = action_list_process(ctx, ctx->mnt.fd, &item->alist, + ALP_COMPLAIN_IF_UNFIXED | ALP_NOPROGRESS); + if (ret) { + str_liberror(ctx, ret, _("repairing iscan metadata")); + *item->abortedp = true; + goto out; + } + +out: + free(item); + return; +} + +/* Queue one inode-scan scrubber. */ +static int +queue_iscan( + struct workqueue *wq, + bool *abortedp, + xfs_agnumber_t nr, + iscan_item_fn scrub_fn) +{ + struct iscan_item *item; + struct scrub_ctx *ctx = wq->wq_ctx; + int ret; + + item = malloc(sizeof(struct iscan_item)); + if (!item) { + ret = ENOMEM; + str_liberror(ctx, ret, _("setting up iscan")); + return ret; + } + action_list_init(&item->alist); + item->scrub_fn = scrub_fn; + item->abortedp = abortedp; + + ret = -workqueue_add(wq, iscan_worker, nr, item); + if (ret) + str_liberror(ctx, ret, _("queuing iscan work")); + + return ret; +} + +/* Run multiple inode-scan scrubbers at the same time. */ +static int +run_kernel_iscan_scrubbers( + struct scrub_ctx *ctx) +{ + struct workqueue wq_iscan; + unsigned int nr_threads = scrub_nproc_workqueue(ctx); + xfs_agnumber_t nr = 0; + bool aborted = false; + int ret, ret2; + + ret = -workqueue_create(&wq_iscan, (struct xfs_mount *)ctx, + nr_threads); + if (ret) { + str_liberror(ctx, ret, _("setting up iscan workqueue")); + return ret; + } + + /* + * The nlinks scanner is much faster than quotacheck because it only + * walks directories, so we start it first. + */ + ret = queue_iscan(&wq_iscan, &aborted, nr, scrub_nlinks); + if (ret) + goto wait; + + if (nr_threads > 1) + nr++; + + ret = queue_iscan(&wq_iscan, &aborted, nr, scrub_quotacheck); + if (ret) + goto wait; + +wait: + ret2 = -workqueue_terminate(&wq_iscan); + if (ret2) { + str_liberror(ctx, ret2, _("joining iscan workqueue")); + if (!ret) + ret = ret2; + } + if (aborted && !ret) + ret = ECANCELED; + + workqueue_destroy(&wq_iscan); + return ret; +} + /* Check directory connectivity. */ int phase5_func( struct scrub_ctx *ctx) { - struct action_list alist; bool aborted = false; int ret; @@ -397,12 +522,7 @@ phase5_func( * after we've checked all inodes and repaired anything that could get * in the way of a scan. */ - action_list_init(&alist); - ret = scrub_iscan_metadata(ctx, &alist); - if (ret) - return ret; - ret = action_list_process(ctx, ctx->mnt.fd, &alist, - ALP_COMPLAIN_IF_UNFIXED | ALP_NOPROGRESS); + ret = run_kernel_iscan_scrubbers(ctx); if (ret) return ret; @@ -435,7 +555,7 @@ phase5_estimate( int *rshift) { *items = scrub_estimate_iscan_work(ctx); - *nr_threads = scrub_nproc(ctx); + *nr_threads = scrub_nproc(ctx) * 2; *rshift = 0; return 0; } diff --git a/scrub/scrub.c b/scrub/scrub.c index f2dd9bb9d0b..fe5c8ade5d8 100644 --- a/scrub/scrub.c +++ b/scrub/scrub.c @@ -422,15 +422,6 @@ scrub_summary_metadata( return scrub_group(ctx, XFROG_SCRUB_GROUP_SUMMARY, 0, alist); } -/* Scrub all metadata requiring a full inode scan. */ -int -scrub_iscan_metadata( - struct scrub_ctx *ctx, - struct action_list *alist) -{ - return scrub_group(ctx, XFROG_SCRUB_GROUP_ISCAN, 0, alist); -} - /* Scrub /only/ the superblock summary counters. */ int scrub_fs_counters( @@ -449,6 +440,15 @@ scrub_quotacheck( return scrub_meta_type(ctx, XFS_SCRUB_TYPE_QUOTACHECK, 0, alist); } +/* Scrub /only/ the file link counters. */ +int +scrub_nlinks( + struct scrub_ctx *ctx, + struct action_list *alist) +{ + return scrub_meta_type(ctx, XFS_SCRUB_TYPE_NLINKS, 0, alist); +} + /* How many items do we have to check? */ unsigned int scrub_estimate_ag_work( diff --git a/scrub/scrub.h b/scrub/scrub.h index 42b91fbc3ed..430ad0fbd83 100644 --- a/scrub/scrub.h +++ b/scrub/scrub.h @@ -28,6 +28,7 @@ int scrub_iscan_metadata(struct scrub_ctx *ctx, struct action_list *alist); int scrub_summary_metadata(struct scrub_ctx *ctx, struct action_list *alist); int scrub_fs_counters(struct scrub_ctx *ctx, struct action_list *alist); int scrub_quotacheck(struct scrub_ctx *ctx, struct action_list *alist); +int scrub_nlinks(struct scrub_ctx *ctx, struct action_list *alist); bool can_scrub_fs_metadata(struct scrub_ctx *ctx); bool can_scrub_inode(struct scrub_ctx *ctx);