From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org, Josef Bacik <josef@toxicpanda.com>,
Jeff Layton <jlayton@kernel.org>
Cc: "Jann Horn" <jannh@google.com>, "Mike Yuan" <me@yhndnzj.com>,
"Zbigniew Jędrzejewski-Szmek" <zbyszek@in.waw.pl>,
"Lennart Poettering" <mzxreary@0pointer.de>,
"Daan De Meyer" <daan.j.demeyer@gmail.com>,
"Aleksa Sarai" <cyphar@cyphar.com>,
"Amir Goldstein" <amir73il@gmail.com>,
"Tejun Heo" <tj@kernel.org>,
"Johannes Weiner" <hannes@cmpxchg.org>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Alexander Viro" <viro@zeniv.linux.org.uk>,
"Jan Kara" <jack@suse.cz>,
linux-kernel@vger.kernel.org, cgroups@vger.kernel.org,
bpf@vger.kernel.org, "Eric Dumazet" <edumazet@google.com>,
"Jakub Kicinski" <kuba@kernel.org>,
netdev@vger.kernel.org, "Arnd Bergmann" <arnd@arndb.de>,
"Christian Brauner" <brauner@kernel.org>
Subject: [PATCH RFC DRAFT 13/50] nstree: assign fixed ids to the initial namespaces
Date: Tue, 21 Oct 2025 13:43:19 +0200 [thread overview]
Message-ID: <20251021-work-namespace-nstree-listns-v1-13-ad44261a8a5b@kernel.org> (raw)
In-Reply-To: <20251021-work-namespace-nstree-listns-v1-0-ad44261a8a5b@kernel.org>
The initial set of namespace comes with fixed inode numbers making it
easy for userspace to identify them solely based on that information.
This has long preceeded anything here.
Similarly, let's assign fixed namespace ids for the initial namespaces.
Kill the cookie and use a sequentially increasing number. This has the
nice side-effect that the owning user namespace will always have a
namespace id that is smaller than any of it's descendant namespaces.
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
fs/namespace.c | 2 +-
include/linux/nstree.h | 26 ++++++++++++++++++++++----
include/uapi/linux/nsfs.h | 14 ++++++++++++++
kernel/nstree.c | 13 ++++++++-----
net/core/net_namespace.c | 2 +-
5 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 87116def5ee3..5d8a80e1e944 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -4094,7 +4094,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns, bool a
return ERR_PTR(ret);
}
if (!anon)
- ns_tree_gen_id(&new_ns->ns);
+ ns_tree_gen_id(new_ns);
refcount_set(&new_ns->passive, 1);
new_ns->mounts = RB_ROOT;
init_waitqueue_head(&new_ns->poll);
diff --git a/include/linux/nstree.h b/include/linux/nstree.h
index 8b8636690473..96ee71622517 100644
--- a/include/linux/nstree.h
+++ b/include/linux/nstree.h
@@ -8,6 +8,7 @@
#include <linux/seqlock.h>
#include <linux/rculist.h>
#include <linux/cookie.h>
+#include <uapi/linux/nsfs.h>
extern struct ns_tree cgroup_ns_tree;
extern struct ns_tree ipc_ns_tree;
@@ -29,7 +30,22 @@ extern struct ns_tree uts_ns_tree;
struct user_namespace *: &(user_ns_tree), \
struct uts_namespace *: &(uts_ns_tree))
-u64 ns_tree_gen_id(struct ns_common *ns);
+#define ns_init_id(__ns) \
+ _Generic((__ns), \
+ struct cgroup_namespace *: CGROUP_NS_INIT_ID, \
+ struct ipc_namespace *: IPC_NS_INIT_ID, \
+ struct mnt_namespace *: MNT_NS_INIT_ID, \
+ struct net *: NET_NS_INIT_ID, \
+ struct pid_namespace *: PID_NS_INIT_ID, \
+ struct time_namespace *: TIME_NS_INIT_ID, \
+ struct user_namespace *: USER_NS_INIT_ID, \
+ struct uts_namespace *: UTS_NS_INIT_ID)
+
+#define ns_tree_gen_id(__ns) \
+ __ns_tree_gen_id(to_ns_common(__ns), \
+ (((__ns) == ns_init_ns(__ns)) ? ns_init_id(__ns) : 0))
+
+u64 __ns_tree_gen_id(struct ns_common *ns, u64 id);
void __ns_tree_add_raw(struct ns_common *ns, struct ns_tree *ns_tree);
void __ns_tree_remove(struct ns_common *ns, struct ns_tree *ns_tree);
struct ns_common *ns_tree_lookup_rcu(u64 ns_id, int ns_type);
@@ -37,9 +53,9 @@ struct ns_common *__ns_tree_adjoined_rcu(struct ns_common *ns,
struct ns_tree *ns_tree,
bool previous);
-static inline void __ns_tree_add(struct ns_common *ns, struct ns_tree *ns_tree)
+static inline void __ns_tree_add(struct ns_common *ns, struct ns_tree *ns_tree, u64 id)
{
- ns_tree_gen_id(ns);
+ __ns_tree_gen_id(ns, id);
__ns_tree_add_raw(ns, ns_tree);
}
@@ -59,7 +75,9 @@ static inline void __ns_tree_add(struct ns_common *ns, struct ns_tree *ns_tree)
* This function assigns a new id to the namespace and adds it to the
* appropriate namespace tree and list.
*/
-#define ns_tree_add(__ns) __ns_tree_add(to_ns_common(__ns), to_ns_tree(__ns))
+#define ns_tree_add(__ns) \
+ __ns_tree_add(to_ns_common(__ns), to_ns_tree(__ns), \
+ (((__ns) == ns_init_ns(__ns)) ? ns_init_id(__ns) : 0))
/**
* ns_tree_remove - Remove a namespace from a namespace tree
diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h
index e098759ec917..f8bc2aad74d6 100644
--- a/include/uapi/linux/nsfs.h
+++ b/include/uapi/linux/nsfs.h
@@ -67,4 +67,18 @@ struct nsfs_file_handle {
#define NSFS_FILE_HANDLE_SIZE_VER0 16 /* sizeof first published struct */
#define NSFS_FILE_HANDLE_SIZE_LATEST sizeof(struct nsfs_file_handle) /* sizeof latest published struct */
+enum init_ns_id {
+ IPC_NS_INIT_ID = 1ULL,
+ UTS_NS_INIT_ID = 2ULL,
+ USER_NS_INIT_ID = 3ULL,
+ PID_NS_INIT_ID = 4ULL,
+ CGROUP_NS_INIT_ID = 5ULL,
+ TIME_NS_INIT_ID = 6ULL,
+ NET_NS_INIT_ID = 7ULL,
+ MNT_NS_INIT_ID = 8ULL,
+#ifdef __KERNEL__
+ NS_LAST_INIT_ID = MNT_NS_INIT_ID,
+#endif
+};
+
#endif /* __LINUX_NSFS_H */
diff --git a/kernel/nstree.c b/kernel/nstree.c
index d21df06b6747..de5ceda44637 100644
--- a/kernel/nstree.c
+++ b/kernel/nstree.c
@@ -68,8 +68,6 @@ struct ns_tree time_ns_tree = {
.type = CLONE_NEWTIME,
};
-DEFINE_COOKIE(namespace_cookie);
-
static inline struct ns_common *node_to_ns(const struct rb_node *node)
{
if (!node)
@@ -278,15 +276,20 @@ struct ns_common *__ns_tree_adjoined_rcu(struct ns_common *ns,
/**
* ns_tree_gen_id - generate a new namespace id
* @ns: namespace to generate id for
+ * @id: if non-zero, this is the initial namespace and this is a fixed id
*
* Generates a new namespace id and assigns it to the namespace. All
* namespaces types share the same id space and thus can be compared
* directly. IOW, when two ids of two namespace are equal, they are
* identical.
*/
-u64 ns_tree_gen_id(struct ns_common *ns)
+u64 __ns_tree_gen_id(struct ns_common *ns, u64 id)
{
- guard(preempt)();
- ns->ns_id = gen_cookie_next(&namespace_cookie);
+ static atomic64_t namespace_cookie = ATOMIC64_INIT(NS_LAST_INIT_ID + 1);
+
+ if (id)
+ ns->ns_id = id;
+ else
+ ns->ns_id = atomic64_inc_return(&namespace_cookie);
return ns->ns_id;
}
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index f30fb78f020c..a76b9b9709d6 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -439,7 +439,7 @@ static __net_init int setup_net(struct net *net)
LIST_HEAD(net_exit_list);
int error = 0;
- net->net_cookie = ns_tree_gen_id(&net->ns);
+ net->net_cookie = ns_tree_gen_id(net);
list_for_each_entry(ops, &pernet_list, list) {
error = ops_init(ops, net);
--
2.47.3
next prev parent reply other threads:[~2025-10-21 11:44 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-21 11:43 [PATCH RFC DRAFT 00/50] nstree: listns() Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 01/50] libfs: allow to specify s_d_flags Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 02/50] nsfs: use inode_just_drop() Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 03/50] nsfs: raise DCACHE_DONTCACHE explicitly Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 04/50] pidfs: " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 05/50] nsfs: raise SB_I_NODEV and SB_I_NOEXEC Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 06/50] nstree: simplify return Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 07/50] ns: initialize ns_list_node for initial namespaces Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 08/50] ns: add __ns_ref_read() Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 09/50] ns: add active reference count Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 10/50] ns: use anonymous struct to group list member Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 11/50] nstree: introduce a unified tree Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 12/50] nstree: allow lookup solely based on inode Christian Brauner
2025-10-21 11:43 ` Christian Brauner [this message]
2025-10-21 11:43 ` [PATCH RFC DRAFT 14/50] ns: maintain list of owned namespaces Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 15/50] nstree: add listns() Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 16/50] arch: hookup listns() system call Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 17/50] nsfs: update tools header Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 18/50] selftests/filesystems: remove CLONE_NEWPIDNS from setup_userns() helper Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 19/50] selftests/namespaces: first active reference count tests Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 20/50] selftests/namespaces: second " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 21/50] selftests/namespaces: third " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 22/50] selftests/namespaces: fourth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 23/50] selftests/namespaces: fifth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 24/50] selftests/namespaces: sixth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 25/50] selftests/namespaces: seventh " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 26/50] selftests/namespaces: eigth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 27/50] selftests/namespaces: ninth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 28/50] selftests/namespaces: tenth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 29/50] selftests/namespaces: eleventh " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 30/50] selftests/namespaces: twelth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 31/50] selftests/namespaces: thirteenth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 32/50] selftests/namespaces: fourteenth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 33/50] selftests/namespaces: fifteenth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 34/50] selftests/namespaces: add listns() wrapper Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 35/50] selftests/namespaces: first listns() test Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 36/50] selftests/namespaces: second " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 37/50] selftests/namespaces: third " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 38/50] selftests/namespaces: fourth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 39/50] selftests/namespaces: fifth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 40/50] selftests/namespaces: sixth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 41/50] selftests/namespaces: seventh " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 42/50] selftests/namespaces: ninth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 43/50] " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 44/50] selftests/namespaces: first listns() permission test Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 45/50] selftests/namespaces: second " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 46/50] selftests/namespaces: third " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 47/50] selftests/namespaces: fourth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 48/50] selftests/namespaces: fifth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 49/50] selftests/namespaces: sixth " Christian Brauner
2025-10-21 11:43 ` [PATCH RFC DRAFT 50/50] selftests/namespaces: seventh " Christian Brauner
2025-10-21 14:34 ` [PATCH RFC DRAFT 00/50] nstree: listns() Josef Bacik
2025-10-22 8:34 ` Christian Brauner
2025-10-21 14:41 ` [syzbot ci] " syzbot ci
2025-10-22 11:00 ` [PATCH RFC DRAFT 00/50] " Ferenc Fejes
2025-10-24 14:50 ` Christian Brauner
2025-10-27 10:49 ` Ferenc Fejes
2025-10-22 11:28 ` Jeff Layton
2025-10-24 14:54 ` Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251021-work-namespace-nstree-listns-v1-13-ad44261a8a5b@kernel.org \
--to=brauner@kernel.org \
--cc=amir73il@gmail.com \
--cc=arnd@arndb.de \
--cc=bpf@vger.kernel.org \
--cc=cgroups@vger.kernel.org \
--cc=cyphar@cyphar.com \
--cc=daan.j.demeyer@gmail.com \
--cc=edumazet@google.com \
--cc=hannes@cmpxchg.org \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=jlayton@kernel.org \
--cc=josef@toxicpanda.com \
--cc=kuba@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=me@yhndnzj.com \
--cc=mzxreary@0pointer.de \
--cc=netdev@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=tj@kernel.org \
--cc=viro@zeniv.linux.org.uk \
--cc=zbyszek@in.waw.pl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).