From mboxrd@z Thu Jan 1 00:00:00 1970 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 CF924C4332F for ; Sat, 31 Dec 2022 01:14:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231444AbiLaBOt (ORCPT ); Fri, 30 Dec 2022 20:14:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42728 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236028AbiLaBOt (ORCPT ); Fri, 30 Dec 2022 20:14:49 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EBDC416588 for ; Fri, 30 Dec 2022 17:14:47 -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 A6E83B81DF6 for ; Sat, 31 Dec 2022 01:14:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 659FBC433D2; Sat, 31 Dec 2022 01:14:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449285; bh=YEV0+AiqRUjObvId+A7boSTmqXbCQxz3pohZMzXjKG8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=no1g9A5UbbAdosDrTzIL0h3MEcjRilOjFrkvBVGyi+OHrUHHkSTWigqVV7t9sYzlF X2GpKI35Vm6CihY4ozE3LfgIC9sGETmqA+YoCtIyagcsvamY0XA9bkgbv0qBsBiyo8 7Iw289uuoF8u+q4FHOZ/Qvm4GYTzBdrRUoqjG7qsqdCvTuDv/jo9m6VWKM2Odrjddl JaB3OtZMQSVoraJOHPs/LIno3Ea71aIX2nCMaglHhG+DwxhLlXwj8fgnkjdLatmJID W0XNnP1YyHlU9TngS4RD+4uA9Vh/K4PsuNi4JdUU9EMI7uY6LtploUAjAvTa1oTm6D CSWj4vw0Y8g2Q== Subject: [PATCH 17/23] xfs: allow bulkstat to return metadata directories From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:27 -0800 Message-ID: <167243864698.708110.4545282663895217938.stgit@magnolia> In-Reply-To: <167243864431.708110.1688096566212843499.stgit@magnolia> References: <167243864431.708110.1688096566212843499.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Allow the V5 bulkstat ioctl to return information about metadata directory files so that xfs_scrub can find and scrub them, since they are otherwise ordinary directories. (Metadata files of course require per-file scrub code and hence do not need exposure.) Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_fs.h | 10 +++++++++- fs/xfs/xfs_ioctl.c | 7 +++++++ fs/xfs/xfs_itable.c | 32 ++++++++++++++++++++++++++++---- fs/xfs/xfs_itable.h | 3 +++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 7de31a6692ae..6e0c45fcfeeb 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -485,9 +485,17 @@ struct xfs_bulk_ireq { */ #define XFS_BULK_IREQ_NREXT64 (1U << 2) +/* + * Allow bulkstat to return information about metadata directories. This + * enables xfs_scrub to find them for scanning, as they are otherwise ordinary + * directories. + */ +#define XFS_BULK_IREQ_METADIR (1U << 31) + #define XFS_BULK_IREQ_FLAGS_ALL (XFS_BULK_IREQ_AGNO | \ XFS_BULK_IREQ_SPECIAL | \ - XFS_BULK_IREQ_NREXT64) + XFS_BULK_IREQ_NREXT64 | \ + XFS_BULK_IREQ_METADIR) /* Operate on the root directory inode. */ #define XFS_BULK_IREQ_SPECIAL_ROOT (1) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 615fd1e4a611..37af6b7e6dbe 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -819,6 +819,10 @@ xfs_bulk_ireq_setup( if (hdr->flags & XFS_BULK_IREQ_NREXT64) breq->flags |= XFS_IBULK_NREXT64; + /* Caller wants to see metadata directories in bulkstat output. */ + if (hdr->flags & XFS_BULK_IREQ_METADIR) + breq->flags |= XFS_IBULK_METADIR; + return 0; } @@ -909,6 +913,9 @@ xfs_ioc_inumbers( if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr))) return -EFAULT; + if (hdr.flags & XFS_BULK_IREQ_METADIR) + return -EINVAL; + error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->inumbers); if (error == -ECANCELED) goto out_teardown; diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 7a967cc78010..37b15da0bb5c 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -36,6 +36,16 @@ struct xfs_bstat_chunk { struct xfs_bulkstat *buf; }; +static inline bool +want_metadir( + struct xfs_inode *ip, + struct xfs_ibulk *breq) +{ + return xfs_is_metadata_inode(ip) && + S_ISDIR(VFS_I(ip)->i_mode) && + (breq->flags & XFS_IBULK_METADIR); +} + /* * Fill out the bulkstat info for a single inode and report it somewhere. * @@ -69,9 +79,6 @@ xfs_bulkstat_one_int( vfsuid_t vfsuid; vfsgid_t vfsgid; - if (xfs_internal_inum(mp, ino)) - goto out_advance; - error = xfs_iget(mp, tp, ino, (XFS_IGET_DONTCACHE | XFS_IGET_UNTRUSTED), XFS_ILOCK_SHARED, &ip); @@ -86,8 +93,25 @@ xfs_bulkstat_one_int( vfsuid = i_uid_into_vfsuid(mnt_userns, inode); vfsgid = i_gid_into_vfsgid(mnt_userns, inode); + /* If we want metadata directories, push out the bare minimum. */ + if (want_metadir(ip, bc->breq)) { + memset(buf, 0, sizeof(*buf)); + buf->bs_ino = ino; + buf->bs_gen = inode->i_generation; + buf->bs_mode = inode->i_mode & S_IFMT; + xfs_bulkstat_health(ip, buf); + buf->bs_version = XFS_BULKSTAT_VERSION_V5; + xfs_iunlock(ip, XFS_ILOCK_SHARED); + xfs_irele(ip); + + error = bc->formatter(bc->breq, buf); + if (!error || error == -ECANCELED) + goto out_advance; + goto out; + } + /* If this is a private inode, don't leak its details to userspace. */ - if (IS_PRIVATE(inode)) { + if (IS_PRIVATE(inode) || xfs_internal_inum(mp, ino)) { xfs_iunlock(ip, XFS_ILOCK_SHARED); xfs_irele(ip); error = -EINVAL; diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h index e2d0eba43f35..bd04445e88e5 100644 --- a/fs/xfs/xfs_itable.h +++ b/fs/xfs/xfs_itable.h @@ -22,6 +22,9 @@ struct xfs_ibulk { /* Fill out the bs_extents64 field if set. */ #define XFS_IBULK_NREXT64 (1U << 1) +/* Signal that we can return metadata directories. */ +#define XFS_IBULK_METADIR (1U << 2) + /* * Advance the user buffer pointer by one record of the given size. If the * buffer is now full, return the appropriate error code.