From patchwork Sun Dec 15 20:17:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13908965 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 875428831 for ; Sun, 15 Dec 2024 20:17:30 +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=1734293850; cv=none; b=ctk26BCBRa+rsfzM+c2X56WRsB1eCqqwPSsfGq8HFSOuCXq086UmMhLs/5V/wQaMtPWWA1TZxqwrjzUtVlJk+9C03kVCqBs7Vgk9U0GBG893G50wHEirq5KDS/fXj/cGfpjfFXm29qLSTcgz9JkJF5aKm3dbz5qJzmlTjBx2fus= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734293850; c=relaxed/simple; bh=W2efpwf1KYhsOHyF/eT+yY7EjGP6BhsW/NaEjUnHOdU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mq9Y58rShD5LLOz4i67DcxaSNR0rb6KTS+Imq1pQI2791QXM0A8Q+EBjqIf9jDVjft1wJmj9V2lnXNydd2jgSw4oNHUQtpDIuPGkQK6dQ8zsPtVjqyidy/YVUZ6EFyp85PTOTttKzcYtCvhyTA7edUs7klbzRQxydjD7JhM+Aqs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PIAfEZ+6; 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="PIAfEZ+6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EC661C4CEDD; Sun, 15 Dec 2024 20:17:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734293850; bh=W2efpwf1KYhsOHyF/eT+yY7EjGP6BhsW/NaEjUnHOdU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PIAfEZ+6YgrdGK+tO+s3psQOWUKjMz6bN2OzJ5yH0RrS+CxQYl3TgbqQi2NTZQTMG YCwE7z+ZCExK+HYgyZsrMqB0/6lT5gBGGelchiWbjUMYcwdTEblXNjVg/lVtMMjM4Y C9UdX8dCaMWlGCzvq5KFuk8JYxNnOqCwEeefvzfzYHdO+jvuMCViX/le1PBshRmyUK srvbLkwcQnLHIUpRWqpb5SkJ+Kv0pEdWAHHDX0r1JgQnBlu0/rKhISXFV7HUjzUd2t 6ZMjt+YpNGHs4uRBqYizZtns1YNvaWtRwgarcGsyXJGTOOzqGxtnvX8eIEemtffsJ4 4EU21kI3Y/gmg== From: Christian Brauner Date: Sun, 15 Dec 2024 21:17:05 +0100 Subject: [PATCH 1/3] fs: kill MNT_ONRB Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241215-vfs-6-14-mount-work-v1-1-fd55922c4af8@kernel.org> References: <20241215-vfs-6-14-mount-work-v1-0-fd55922c4af8@kernel.org> In-Reply-To: <20241215-vfs-6-14-mount-work-v1-0-fd55922c4af8@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Miklos Szeredi , Amir Goldstein , Christian Brauner X-Mailer: b4 0.15-dev-355e8 X-Developer-Signature: v=1; a=openpgp-sha256; l=5283; i=brauner@kernel.org; h=from:subject:message-id; bh=W2efpwf1KYhsOHyF/eT+yY7EjGP6BhsW/NaEjUnHOdU=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTHW4atESi8e4HbcffL89lvtsc8nn5xueCs2/GSFz7J+ xUEHzx0u6OUhUGMi0FWTJHFod0kXG45T8Vmo0wNmDmsTCBDGLg4BWAiBSyMDKc1MpgUOYTNeSW/ ex1gWhx37Dhv/2nmNzIyx1lfLPCymsnI0H1IiMdfpSfzmaRSQl2Dpozm6ZJZX6q8X60sN7nQ4vm ZAwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Move mnt->mnt_node into the union with mnt->mnt_rcu and mnt->mnt_llist instead of keeping it with mnt->mnt_list. This allows us to use RB_CLEAR_NODE(&mnt->mnt_node) in umount_tree() as well as list_empty(&mnt->mnt_node). That in turn allows us to remove MNT_ONRB. Signed-off-by: Christian Brauner --- fs/mount.h | 15 +++++++++------ fs/namespace.c | 14 ++++++-------- include/linux/mount.h | 3 +-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/fs/mount.h b/fs/mount.h index 8cda387f47c5efd9af5e2e422569446c3d51986f..e9f48e563c0fe9c4af77369423db2cc8695fa808 100644 --- a/fs/mount.h +++ b/fs/mount.h @@ -42,6 +42,7 @@ struct mount { struct dentry *mnt_mountpoint; struct vfsmount mnt; union { + struct rb_node mnt_node; /* node in the ns->mounts rbtree */ struct rcu_head mnt_rcu; struct llist_node mnt_llist; }; @@ -55,10 +56,7 @@ struct mount { struct list_head mnt_child; /* and going through their mnt_child */ struct list_head mnt_instance; /* mount instance on sb->s_mounts */ const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ - union { - struct rb_node mnt_node; /* Under ns->mounts */ - struct list_head mnt_list; - }; + struct list_head mnt_list; struct list_head mnt_expire; /* link in fs-specific expiry list */ struct list_head mnt_share; /* circular list of shared mounts */ struct list_head mnt_slave_list;/* list of slave mounts */ @@ -149,11 +147,16 @@ static inline bool is_anon_ns(struct mnt_namespace *ns) return ns->seq == 0; } +static inline bool mnt_ns_attached(const struct mount *mnt) +{ + return !RB_EMPTY_NODE(&mnt->mnt_node); +} + static inline void move_from_ns(struct mount *mnt, struct list_head *dt_list) { - WARN_ON(!(mnt->mnt.mnt_flags & MNT_ONRB)); - mnt->mnt.mnt_flags &= ~MNT_ONRB; + WARN_ON(!mnt_ns_attached(mnt)); rb_erase(&mnt->mnt_node, &mnt->mnt_ns->mounts); + RB_CLEAR_NODE(&mnt->mnt_node); list_add_tail(&mnt->mnt_list, dt_list); } diff --git a/fs/namespace.c b/fs/namespace.c index 966dcd27c81cc877837eca747babe0bc31aaf922..d67df0fce4dcd1ee5ddf9ff5fbe005bcdcd626f1 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -378,6 +378,7 @@ static struct mount *alloc_vfsmnt(const char *name) INIT_HLIST_NODE(&mnt->mnt_mp_list); INIT_LIST_HEAD(&mnt->mnt_umounting); INIT_HLIST_HEAD(&mnt->mnt_stuck_children); + RB_CLEAR_NODE(&mnt->mnt_node); mnt->mnt.mnt_idmap = &nop_mnt_idmap; } return mnt; @@ -1158,7 +1159,7 @@ static void mnt_add_to_ns(struct mnt_namespace *ns, struct mount *mnt) struct rb_node **link = &ns->mounts.rb_node; struct rb_node *parent = NULL; - WARN_ON(mnt->mnt.mnt_flags & MNT_ONRB); + WARN_ON(mnt_ns_attached(mnt)); mnt->mnt_ns = ns; while (*link) { parent = *link; @@ -1169,7 +1170,6 @@ static void mnt_add_to_ns(struct mnt_namespace *ns, struct mount *mnt) } rb_link_node(&mnt->mnt_node, parent, link); rb_insert_color(&mnt->mnt_node, &ns->mounts); - mnt->mnt.mnt_flags |= MNT_ONRB; } /* @@ -1339,7 +1339,7 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, } mnt->mnt.mnt_flags = old->mnt.mnt_flags; - mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL|MNT_ONRB); + mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL); atomic_inc(&sb->s_active); mnt->mnt.mnt_idmap = mnt_idmap_get(mnt_idmap(&old->mnt)); @@ -1797,7 +1797,7 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) /* Gather the mounts to umount */ for (p = mnt; p; p = next_mnt(p, mnt)) { p->mnt.mnt_flags |= MNT_UMOUNT; - if (p->mnt.mnt_flags & MNT_ONRB) + if (mnt_ns_attached(p)) move_from_ns(p, &tmp_list); else list_move(&p->mnt_list, &tmp_list); @@ -1946,16 +1946,14 @@ static int do_umount(struct mount *mnt, int flags) event++; if (flags & MNT_DETACH) { - if (mnt->mnt.mnt_flags & MNT_ONRB || - !list_empty(&mnt->mnt_list)) + if (mnt_ns_attached(mnt) || !list_empty(&mnt->mnt_list)) umount_tree(mnt, UMOUNT_PROPAGATE); retval = 0; } else { shrink_submounts(mnt); retval = -EBUSY; if (!propagate_mount_busy(mnt, 2)) { - if (mnt->mnt.mnt_flags & MNT_ONRB || - !list_empty(&mnt->mnt_list)) + if (mnt_ns_attached(mnt) || !list_empty(&mnt->mnt_list)) umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC); retval = 0; } diff --git a/include/linux/mount.h b/include/linux/mount.h index c34c18b4e8f36f27775c4df624890eb8e6060965..04213d8ef8376d42d83b44d5a2ce1c35ad5a942e 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -50,7 +50,7 @@ struct path; #define MNT_ATIME_MASK (MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME ) #define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \ - MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED | MNT_ONRB) + MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED) #define MNT_INTERNAL 0x4000 @@ -64,7 +64,6 @@ struct path; #define MNT_SYNC_UMOUNT 0x2000000 #define MNT_MARKED 0x4000000 #define MNT_UMOUNT 0x8000000 -#define MNT_ONRB 0x10000000 struct vfsmount { struct dentry *mnt_root; /* root of the mounted tree */ From patchwork Sun Dec 15 20:17:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13908966 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 A31368831 for ; Sun, 15 Dec 2024 20:17:31 +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=1734293851; cv=none; b=O9wnp1bAD5Ql61gURA0QYWxl2Gvz1OnNRDZAAshkMR/IfJSURbf/5RMQm1dDLVJu0XDPLHmk+3/64RE24bLxZik7N4ZiuLoEnZEFVVHg7TfFpKQ06F2ubskOvIIDP3sANEGrfpqY7EBnPtdJX2/6y1rNU9NhiNv9pH13ZJkD23w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734293851; c=relaxed/simple; bh=z0UslY2EoGwGNf0urQ8uYzTdALc1f94HxDNf4auqClc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=k2mVE7ihGR8y1zh89XWRQnIKhLOlxatsfRZP8kLl+XH+oaWsV8Qiq2sm1OPlbXfywnVU7m3lfm8gcCGmmvHNDrD7XZUUAbnqXy7C0jAMBwWv+LhNwvosfA5HU59zZmC92z0ap/IRrZQMFOC2dbr+LjjNZcczWKA9RYr2/7fAKuw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=D8GpOvdy; 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="D8GpOvdy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E9E0C4CED6; Sun, 15 Dec 2024 20:17:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734293851; bh=z0UslY2EoGwGNf0urQ8uYzTdALc1f94HxDNf4auqClc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=D8GpOvdyTGDqjWWn0clhgJ1pm3SOZZJ5cn5tCq2zIuSWEvmTseltNvARx2VW3AI+Q qTUh0HwXLMem78EvnMnt2na4g4H0rbzJti6tnOFt/qZ4kEEgr35kpukRDCkYjZv3eb IpX2mgvP8EjHXrHQuFmeXY0s6woEz3k/VA4qMEJl4Z0hcLNtkRwxvVKOUdMnQgAtRA 6x0uN+d7wF1qaT7vwaHIn8tQNA7ro19e2fdavGLogkDqdHQN2Hzk9H03Srgi84Yqks 339JPl19F0clpH8Wuc4nlGF1LsJDlvUYtbs0zh1x3aagtu60/N8yF7wWoHXA08XtcJ Lc1PqDndlqvPg== From: Christian Brauner Date: Sun, 15 Dec 2024 21:17:06 +0100 Subject: [PATCH 2/3] fs: cache first and last mount Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241215-vfs-6-14-mount-work-v1-2-fd55922c4af8@kernel.org> References: <20241215-vfs-6-14-mount-work-v1-0-fd55922c4af8@kernel.org> In-Reply-To: <20241215-vfs-6-14-mount-work-v1-0-fd55922c4af8@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Miklos Szeredi , Amir Goldstein , Christian Brauner X-Mailer: b4 0.15-dev-355e8 X-Developer-Signature: v=1; a=openpgp-sha256; l=3092; i=brauner@kernel.org; h=from:subject:message-id; bh=z0UslY2EoGwGNf0urQ8uYzTdALc1f94HxDNf4auqClc=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTHW4Yt7RSazDZjW9EXWZ01JYwa724u/pAuXzZhVnJDr iF3Sf3EjlIWBjEuBlkxRRaHdpNwueU8FZuNMjVg5rAygQxh4OIUgIk0eTD8L4qs1tvmkPmZT733 +tvaHG+/n+YtrjKKZi17j4gvdd4ZyPC/zn1KJ2NTyNvMSCet25s/6IVLaeXHmAlE5f/XeZGlOo0 dAA== X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Speed up listmount() by caching the first and last node making retrieval of the first and last mount of each mount namespace O(1). Signed-off-by: Christian Brauner --- fs/mount.h | 13 +++++++++++-- fs/namespace.c | 17 +++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/fs/mount.h b/fs/mount.h index e9f48e563c0fe9c4af77369423db2cc8695fa808..ffb613cdfeee97b99fe9419e8152c166e0a9ac83 100644 --- a/fs/mount.h +++ b/fs/mount.h @@ -8,7 +8,11 @@ struct mnt_namespace { struct ns_common ns; struct mount * root; - struct rb_root mounts; /* Protected by namespace_sem */ + struct { + struct rb_root mounts; /* Protected by namespace_sem */ + struct rb_node *mnt_last_node; /* last (rightmost) mount in the rbtree */ + struct rb_node *mnt_first_node; /* first (leftmost) mount in the rbtree */ + }; struct user_namespace *user_ns; struct ucounts *ucounts; u64 seq; /* Sequence number to prevent loops */ @@ -154,8 +158,13 @@ static inline bool mnt_ns_attached(const struct mount *mnt) static inline void move_from_ns(struct mount *mnt, struct list_head *dt_list) { + struct mnt_namespace *ns = mnt->mnt_ns; WARN_ON(!mnt_ns_attached(mnt)); - rb_erase(&mnt->mnt_node, &mnt->mnt_ns->mounts); + if (ns->mnt_last_node == &mnt->mnt_node) + ns->mnt_last_node = rb_prev(&mnt->mnt_node); + if (ns->mnt_first_node == &mnt->mnt_node) + ns->mnt_first_node = rb_next(&mnt->mnt_node); + rb_erase(&mnt->mnt_node, &ns->mounts); RB_CLEAR_NODE(&mnt->mnt_node); list_add_tail(&mnt->mnt_list, dt_list); } diff --git a/fs/namespace.c b/fs/namespace.c index d67df0fce4dcd1ee5ddf9ff5fbe005bcdcd626f1..d99a3c2c5e5c8a2e2d4e762ebda1226b882cd7f1 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1158,16 +1158,25 @@ static void mnt_add_to_ns(struct mnt_namespace *ns, struct mount *mnt) { struct rb_node **link = &ns->mounts.rb_node; struct rb_node *parent = NULL; + bool mnt_first_node = true, mnt_last_node = true; WARN_ON(mnt_ns_attached(mnt)); mnt->mnt_ns = ns; while (*link) { parent = *link; - if (mnt->mnt_id_unique < node_to_mount(parent)->mnt_id_unique) + if (mnt->mnt_id_unique < node_to_mount(parent)->mnt_id_unique) { link = &parent->rb_left; - else + mnt_last_node = false; + } else { link = &parent->rb_right; + mnt_first_node = false; + } } + + if (mnt_last_node) + ns->mnt_last_node = &mnt->mnt_node; + if (mnt_first_node) + ns->mnt_first_node = &mnt->mnt_node; rb_link_node(&mnt->mnt_node, parent, link); rb_insert_color(&mnt->mnt_node, &ns->mounts); } @@ -5562,9 +5571,9 @@ static ssize_t do_listmount(struct mnt_namespace *ns, u64 mnt_parent_id, if (!last_mnt_id) { if (reverse) - first = node_to_mount(rb_last(&ns->mounts)); + first = node_to_mount(ns->mnt_last_node); else - first = node_to_mount(rb_first(&ns->mounts)); + first = node_to_mount(ns->mnt_first_node); } else { if (reverse) first = mnt_find_id_at_reverse(ns, last_mnt_id - 1); From patchwork Sun Dec 15 20:17:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13908967 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 20C8B1C07C1 for ; Sun, 15 Dec 2024 20:17:33 +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=1734293853; cv=none; b=pbq00McS5y0a0eWpknMMYS8X7jv9hbRifLWvfErk5l7ridKlIBagvtoSD83SgCHZafugwEbrOOgMSdtYcPtDMPB4UIRSH+N1n5ZRk7NZPUAJbGSDijBCOjaGnrWziNbxVrSjMNrdVaITIBconMxHLIPw8W1/QuuqEi3j+dlsHo4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734293853; c=relaxed/simple; bh=t5ZB3S9FAPTSg7jaPhLfftiu7OGAVCaFewVNQnPC7Sk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JfTR4O03DJJ1nI1sinaa1e7EMiRljGydVmXh6c0+h2lvStJgJbPR3Rrfiec+r9HymkHUU4bUv9jRvEaTLtsrYPoRDJNEOgr56ivnHpGPFE8msUOfgsS6pieZihkzkKwOwNY11HFcrVXOvhqp3BtMLrk8mNV9KClmhqJNpz+sGyk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iwQg9BSV; 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="iwQg9BSV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EB5E3C4CECE; Sun, 15 Dec 2024 20:17:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734293853; bh=t5ZB3S9FAPTSg7jaPhLfftiu7OGAVCaFewVNQnPC7Sk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=iwQg9BSVpOryqNsgYG83Us0r5stowezKHiO8T7BozvOP7n3UuLQP3n2Fdw4vRzLV+ knt4hByHw2EmV5408C0uA9Yf2QsuNM0wtQgOGwCg94+XLJlXAgL3BA9St5RphByu/g bfZxbYZzIgVQAV6z119z1j+On37kIGOUQ4vjyzEzRtjBdopCzCrfCAwo6qaCjRoyVG nBvoT00+oa40NmC0J4YkzoNr+t2o89nilO/SahH+pamjl7d5L/9fZObAqULhRLiRTb z5Dn0Z8BdQ39SPwKWccQUvPTHNgcBSxwqz05/fLQmFQ6BB9EwQCuQenO5bhfGPvCHE ngvoxgwE7fooA== From: Christian Brauner Date: Sun, 15 Dec 2024 21:17:07 +0100 Subject: [PATCH 3/3] selftests: add listmount() iteration tests Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241215-vfs-6-14-mount-work-v1-3-fd55922c4af8@kernel.org> References: <20241215-vfs-6-14-mount-work-v1-0-fd55922c4af8@kernel.org> In-Reply-To: <20241215-vfs-6-14-mount-work-v1-0-fd55922c4af8@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Miklos Szeredi , Amir Goldstein , Christian Brauner X-Mailer: b4 0.15-dev-355e8 X-Developer-Signature: v=1; a=openpgp-sha256; l=2856; i=brauner@kernel.org; h=from:subject:message-id; bh=t5ZB3S9FAPTSg7jaPhLfftiu7OGAVCaFewVNQnPC7Sk=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTHW4ZldG9l+/Xpwq2UHnvpgHlJuj8/7g/wtfz1sm9n9 L+0I14fO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACYiVc7wTyW6OMV+/trYb8F2 jazfL7E1dj5TOrnu3TwDfrekiPj6aQy/2e+Kbk143yWT6flP+mpZ54aH6vcXX+k2tli9U1PGP7i MCQA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Add a forward and backward iteration test for listmount(). Signed-off-by: Christian Brauner --- .../selftests/filesystems/statmount/Makefile | 2 +- .../filesystems/statmount/listmount_test.c | 66 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/filesystems/statmount/Makefile b/tools/testing/selftests/filesystems/statmount/Makefile index 3af3136e35a4bc3671c292ab6abe41832a2be85d..14ee91a416509c7c4070fc3115c66bcfd9166011 100644 --- a/tools/testing/selftests/filesystems/statmount/Makefile +++ b/tools/testing/selftests/filesystems/statmount/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-or-later CFLAGS += -Wall -O2 -g $(KHDR_INCLUDES) -TEST_GEN_PROGS := statmount_test statmount_test_ns +TEST_GEN_PROGS := statmount_test statmount_test_ns listmount_test include ../../lib.mk diff --git a/tools/testing/selftests/filesystems/statmount/listmount_test.c b/tools/testing/selftests/filesystems/statmount/listmount_test.c new file mode 100644 index 0000000000000000000000000000000000000000..15f0834f7557c8771be9adbfe7968421c505a1ea --- /dev/null +++ b/tools/testing/selftests/filesystems/statmount/listmount_test.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright (c) 2024 Christian Brauner + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#include "statmount.h" +#include "../../kselftest_harness.h" + +#ifndef LISTMOUNT_REVERSE +#define LISTMOUNT_REVERSE (1 << 0) /* List later mounts first */ +#endif + +#define LISTMNT_BUFFER 10 + +/* Check that all mount ids are in increasing order. */ +TEST(listmount_forward) +{ + uint64_t list[LISTMNT_BUFFER], last_mnt_id = 0; + + for (;;) { + ssize_t nr_mounts; + + nr_mounts = listmount(LSMT_ROOT, 0, last_mnt_id, + list, LISTMNT_BUFFER, 0); + ASSERT_GE(nr_mounts, 0); + if (nr_mounts == 0) + break; + + for (size_t cur = 0; cur < nr_mounts; cur++) { + if (cur < nr_mounts - 1) + ASSERT_LT(list[cur], list[cur + 1]); + last_mnt_id = list[cur]; + } + } +} + +/* Check that all mount ids are in decreasing order. */ +TEST(listmount_backward) +{ + uint64_t list[LISTMNT_BUFFER], last_mnt_id = 0; + + for (;;) { + ssize_t nr_mounts; + + nr_mounts = listmount(LSMT_ROOT, 0, last_mnt_id, + list, LISTMNT_BUFFER, LISTMOUNT_REVERSE); + ASSERT_GE(nr_mounts, 0); + if (nr_mounts == 0) + break; + + for (size_t cur = 0; cur < nr_mounts; cur++) { + if (cur < nr_mounts - 1) + ASSERT_GT(list[cur], list[cur + 1]); + last_mnt_id = list[cur]; + } + } +} + +TEST_HARNESS_MAIN