···1717 };1818 struct user_namespace *user_ns;1919 struct ucounts *ucounts;2020- u64 seq; /* Sequence number to prevent loops */2121- union {2222- wait_queue_head_t poll;2323- struct rcu_head mnt_ns_rcu;2424- };2020+ wait_queue_head_t poll;2521 u64 seq_origin; /* Sequence number of origin mount namespace */2622 u64 event;2723#ifdef CONFIG_FSNOTIFY···2630#endif2731 unsigned int nr_mounts; /* # of mounts in the namespace */2832 unsigned int pending_mounts;2929- struct rb_node mnt_ns_tree_node; /* node in the mnt_ns_tree */3030- struct list_head mnt_ns_list; /* entry in the sequential list of mounts namespace */3133 refcount_t passive; /* number references not pinning @mounts */3234} __randomize_layout;3335···167173168174static inline bool is_anon_ns(struct mnt_namespace *ns)169175{170170- return ns->seq == 0;176176+ return ns->ns.ns_id == 0;171177}172178173179static inline bool anon_ns_root(const struct mount *m)
+29-110
fs/namespace.c
···3333#include <linux/shmem_fs.h>3434#include <linux/mnt_idmapping.h>3535#include <linux/pidfs.h>3636+#include <linux/nstree.h>36373738#include "pnode.h"3839#include "internal.h"···8180static HLIST_HEAD(unmounted); /* protected by namespace_sem */8281static LIST_HEAD(ex_mountpoints); /* protected by namespace_sem */8382static struct mnt_namespace *emptied_ns; /* protected by namespace_sem */8484-static DEFINE_SEQLOCK(mnt_ns_tree_lock);85838684#ifdef CONFIG_FSNOTIFY8785LIST_HEAD(notify_list); /* protected by namespace_sem */8886#endif8989-static struct rb_root mnt_ns_tree = RB_ROOT; /* protected by mnt_ns_tree_lock */9090-static LIST_HEAD(mnt_ns_list); /* protected by mnt_ns_tree_lock */91879288enum mount_kattr_flags_t {9389 MOUNT_KATTR_RECURSE = (1 << 0),···117119118120static inline struct mnt_namespace *node_to_mnt_ns(const struct rb_node *node)119121{122122+ struct ns_common *ns;123123+120124 if (!node)121125 return NULL;122122- return rb_entry(node, struct mnt_namespace, mnt_ns_tree_node);123123-}124124-125125-static int mnt_ns_cmp(struct rb_node *a, const struct rb_node *b)126126-{127127- struct mnt_namespace *ns_a = node_to_mnt_ns(a);128128- struct mnt_namespace *ns_b = node_to_mnt_ns(b);129129- u64 seq_a = ns_a->seq;130130- u64 seq_b = ns_b->seq;131131-132132- if (seq_a < seq_b)133133- return -1;134134- if (seq_a > seq_b)135135- return 1;136136- return 0;137137-}138138-139139-static inline void mnt_ns_tree_write_lock(void)140140-{141141- write_seqlock(&mnt_ns_tree_lock);142142-}143143-144144-static inline void mnt_ns_tree_write_unlock(void)145145-{146146- write_sequnlock(&mnt_ns_tree_lock);147147-}148148-149149-static void mnt_ns_tree_add(struct mnt_namespace *ns)150150-{151151- struct rb_node *node, *prev;152152-153153- mnt_ns_tree_write_lock();154154- node = rb_find_add_rcu(&ns->mnt_ns_tree_node, &mnt_ns_tree, mnt_ns_cmp);155155- /*156156- * If there's no previous entry simply add it after the157157- * head and if there is add it after the previous entry.158158- */159159- prev = rb_prev(&ns->mnt_ns_tree_node);160160- if (!prev)161161- list_add_rcu(&ns->mnt_ns_list, &mnt_ns_list);162162- else163163- list_add_rcu(&ns->mnt_ns_list, &node_to_mnt_ns(prev)->mnt_ns_list);164164- mnt_ns_tree_write_unlock();165165-166166- WARN_ON_ONCE(node);126126+ ns = rb_entry(node, struct ns_common, ns_tree_node);127127+ return container_of(ns, struct mnt_namespace, ns);167128}168129169130static void mnt_ns_release(struct mnt_namespace *ns)···138181139182static void mnt_ns_release_rcu(struct rcu_head *rcu)140183{141141- mnt_ns_release(container_of(rcu, struct mnt_namespace, mnt_ns_rcu));184184+ mnt_ns_release(container_of(rcu, struct mnt_namespace, ns.ns_rcu));142185}143186144187static void mnt_ns_tree_remove(struct mnt_namespace *ns)145188{146189 /* remove from global mount namespace list */147147- if (!RB_EMPTY_NODE(&ns->mnt_ns_tree_node)) {148148- mnt_ns_tree_write_lock();149149- rb_erase(&ns->mnt_ns_tree_node, &mnt_ns_tree);150150- list_bidir_del_rcu(&ns->mnt_ns_list);151151- mnt_ns_tree_write_unlock();152152- }190190+ if (ns_tree_active(ns))191191+ ns_tree_remove(ns);153192154154- call_rcu(&ns->mnt_ns_rcu, mnt_ns_release_rcu);155155-}156156-157157-static int mnt_ns_find(const void *key, const struct rb_node *node)158158-{159159- const u64 mnt_ns_id = *(u64 *)key;160160- const struct mnt_namespace *ns = node_to_mnt_ns(node);161161-162162- if (mnt_ns_id < ns->seq)163163- return -1;164164- if (mnt_ns_id > ns->seq)165165- return 1;166166- return 0;193193+ call_rcu(&ns->ns.ns_rcu, mnt_ns_release_rcu);167194}168195169196/*···166225 */167226static struct mnt_namespace *lookup_mnt_ns(u64 mnt_ns_id)168227{169169- struct mnt_namespace *ns;170170- struct rb_node *node;171171- unsigned int seq;228228+ struct mnt_namespace *mnt_ns;229229+ struct ns_common *ns;172230173231 guard(rcu)();174174- do {175175- seq = read_seqbegin(&mnt_ns_tree_lock);176176- node = rb_find_rcu(&mnt_ns_id, &mnt_ns_tree, mnt_ns_find);177177- if (node)178178- break;179179- } while (read_seqretry(&mnt_ns_tree_lock, seq));180180-181181- if (!node)232232+ ns = ns_tree_lookup_rcu(mnt_ns_id, CLONE_NEWNS);233233+ if (!ns)182234 return NULL;183235184236 /*185237 * The last reference count is put with RCU delay so we can186238 * unconditonally acquire a reference here.187239 */188188- ns = node_to_mnt_ns(node);189189- refcount_inc(&ns->passive);190190- return ns;240240+ mnt_ns = container_of(ns, struct mnt_namespace, ns);241241+ refcount_inc(&mnt_ns->passive);242242+ return mnt_ns;191243}192244193245static inline void lock_mount_hash(void)···9511017 return false;95210189531019 seq = mnt->mnt_ns->seq_origin;954954- return !seq || (seq == current->nsproxy->mnt_ns->seq);10201020+ return !seq || (seq == current->nsproxy->mnt_ns->ns.ns_id);9551021}95610229571023/*···2086215220872153struct mnt_namespace *get_sequential_mnt_ns(struct mnt_namespace *mntns, bool previous)20882154{21552155+ struct ns_common *ns;21562156+20892157 guard(rcu)();2090215820912159 for (;;) {20922092- struct list_head *list;21602160+ ns = ns_tree_adjoined_rcu(mntns, previous);21612161+ if (IS_ERR(ns))21622162+ return ERR_CAST(ns);2093216320942094- if (previous)20952095- list = rcu_dereference(list_bidir_prev_rcu(&mntns->mnt_ns_list));20962096- else20972097- list = rcu_dereference(list_next_rcu(&mntns->mnt_ns_list));20982098- if (list_is_head(list, &mnt_ns_list))20992099- return ERR_PTR(-ENOENT);21002100-21012101- mntns = list_entry_rcu(list, struct mnt_namespace, mnt_ns_list);21642164+ mntns = to_mnt_ns(ns);2102216521032166 /*21042167 * The last passive reference count is put with RCU···21352204 if (!mnt_ns)21362205 return false;2137220621382138- return current->nsproxy->mnt_ns->seq >= mnt_ns->seq;22072207+ return current->nsproxy->mnt_ns->ns.ns_id >= mnt_ns->ns.ns_id;21392208}2140220921412210struct mount *copy_tree(struct mount *src_root, struct dentry *dentry,···30113080 if (is_anon_ns(src_mnt_ns))30123081 ns->seq_origin = src_mnt_ns->seq_origin;30133082 else30143014- ns->seq_origin = src_mnt_ns->seq;30833083+ ns->seq_origin = src_mnt_ns->ns.ns_id;30153084 }3016308530173086 mnt = __do_loopback(path, recursive);···40874156 mnt_ns_tree_remove(ns);40884157}4089415840904090-/*40914091- * Assign a sequence number so we can detect when we attempt to bind40924092- * mount a reference to an older mount namespace into the current40934093- * mount namespace, preventing reference counting loops. A 64bit40944094- * number incrementing at 10Ghz will take 12,427 years to wrap which40954095- * is effectively never, so we can ignore the possibility.40964096- */40974097-static atomic64_t mnt_ns_seq = ATOMIC64_INIT(1);40984098-40994159static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns, bool anon)41004160{41014161 struct mnt_namespace *new_ns;···41104188 return ERR_PTR(ret);41114189 }41124190 if (!anon)41134113- new_ns->seq = atomic64_inc_return(&mnt_ns_seq);41914191+ ns_tree_gen_id(&new_ns->ns);41144192 refcount_set(&new_ns->passive, 1);41154193 new_ns->mounts = RB_ROOT;41164116- INIT_LIST_HEAD(&new_ns->mnt_ns_list);41174117- RB_CLEAR_NODE(&new_ns->mnt_ns_tree_node);41184194 init_waitqueue_head(&new_ns->poll);41194195 new_ns->user_ns = get_user_ns(user_ns);41204196 new_ns->ucounts = ucounts;···41984278 if (pwdmnt)41994279 mntput(pwdmnt);4200428042014201- mnt_ns_tree_add(new_ns);42814281+ ns_tree_add_raw(new_ns);42024282 return new_ns;42034283}42044284···53175397static void statmount_mnt_ns_id(struct kstatmount *s, struct mnt_namespace *ns)53185398{53195399 s->sm.mask |= STATMOUNT_MNT_NS_ID;53205320- s->sm.mnt_ns_id = ns->seq;54005400+ s->sm.mnt_ns_id = ns->ns.ns_id;53215401}5322540253235403static int statmount_mnt_opts(struct kstatmount *s, struct seq_file *seq)···60226102 ns = alloc_mnt_ns(&init_user_ns, true);60236103 if (IS_ERR(ns))60246104 panic("Can't allocate initial namespace");60256025- ns->seq = atomic64_inc_return(&mnt_ns_seq);60266105 ns->ns.inum = PROC_MNT_INIT_INO;60276106 m = real_mount(mnt);60286107 ns->root = m;···60366117 set_fs_pwd(current->fs, &root);60376118 set_fs_root(current->fs, &root);6038611960396039- mnt_ns_tree_add(ns);61206120+ ns_tree_add(ns);60406121}6041612260426123void __init mnt_init(void)
+2-2
fs/nsfs.c
···139139 * the size value will be set to the size the kernel knows about.140140 */141141 kinfo->size = min(usize, sizeof(*kinfo));142142- kinfo->mnt_ns_id = mnt_ns->seq;142142+ kinfo->mnt_ns_id = mnt_ns->ns.ns_id;143143 kinfo->nr_mounts = READ_ONCE(mnt_ns->nr_mounts);144144 /* Subtract the root mount of the mount namespace. */145145 if (kinfo->nr_mounts)···221221222222 mnt_ns = container_of(ns, struct mnt_namespace, ns);223223 idp = (__u64 __user *)arg;224224- id = mnt_ns->seq;224224+ id = mnt_ns->ns.ns_id;225225 return put_user(id, idp);226226 }227227 case NS_GET_PID_FROM_PIDNS: