Lines Matching +full:node +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0-only
68 * ns_tree_node_init - Initialize a namespace tree node
69 * @node: The node to initialize
71 * Initializes both the rbtree node and list entry.
73 void ns_tree_node_init(struct ns_tree_node *node) in ns_tree_node_init() argument
75 RB_CLEAR_NODE(&node->ns_node); in ns_tree_node_init()
76 INIT_LIST_HEAD(&node->ns_list_entry); in ns_tree_node_init()
80 * ns_tree_root_init - Initialize a namespace tree root
87 root->ns_rb = RB_ROOT; in ns_tree_root_init()
88 INIT_LIST_HEAD(&root->ns_list_head); in ns_tree_root_init()
92 * ns_tree_node_empty - Check if a namespace tree node is empty
93 * @node: The node to check
95 * Returns true if the node is not in any tree.
97 bool ns_tree_node_empty(const struct ns_tree_node *node) in ns_tree_node_empty() argument
99 return RB_EMPTY_NODE(&node->ns_node); in ns_tree_node_empty()
103 * ns_tree_node_add - Add a node to a namespace tree
104 * @node: The node to add
108 * Adds the node to both the rbtree and the list, maintaining sorted order.
112 * Returns: NULL if insertion succeeded, existing node if duplicate found
114 struct rb_node *ns_tree_node_add(struct ns_tree_node *node, in ns_tree_node_add() argument
121 ret = rb_find_add_rcu(&node->ns_node, &root->ns_rb, cmp); in ns_tree_node_add()
124 prev = rb_prev(&node->ns_node); in ns_tree_node_add()
126 /* No previous node, add at head */ in ns_tree_node_add()
127 list_add_rcu(&node->ns_list_entry, &root->ns_list_head); in ns_tree_node_add()
129 /* Add after previous node */ in ns_tree_node_add()
132 list_add_rcu(&node->ns_list_entry, &prev_node->ns_list_entry); in ns_tree_node_add()
139 * ns_tree_node_del - Remove a node from a namespace tree
140 * @node: The node to remove
143 * Removes the node from both the rbtree and the list atomically.
145 void ns_tree_node_del(struct ns_tree_node *node, struct ns_tree_root *root) in ns_tree_node_del() argument
147 rb_erase(&node->ns_node, &root->ns_rb); in ns_tree_node_del()
148 RB_CLEAR_NODE(&node->ns_node); in ns_tree_node_del()
149 list_bidir_del_rcu(&node->ns_list_entry); in ns_tree_node_del()
152 static inline struct ns_common *node_to_ns(const struct rb_node *node) in node_to_ns() argument
154 if (!node) in node_to_ns()
156 return rb_entry(node, struct ns_common, ns_tree_node.ns_node); in node_to_ns()
159 static inline struct ns_common *node_to_ns_unified(const struct rb_node *node) in node_to_ns_unified() argument
161 if (!node) in node_to_ns_unified()
163 return rb_entry(node, struct ns_common, ns_unified_node.ns_node); in node_to_ns_unified()
166 static inline struct ns_common *node_to_ns_owner(const struct rb_node *node) in node_to_ns_owner() argument
168 if (!node) in node_to_ns_owner()
170 return rb_entry(node, struct ns_common, ns_owner_node.ns_node); in node_to_ns_owner()
176 return -1; in ns_id_cmp()
184 return ns_id_cmp(node_to_ns(a)->ns_id, node_to_ns(b)->ns_id); in ns_cmp()
189 return ns_id_cmp(node_to_ns_unified(a)->ns_id, node_to_ns_unified(b)->ns_id); in ns_cmp_unified()
194 return ns_id_cmp(node_to_ns_owner(a)->ns_id, node_to_ns_owner(b)->ns_id); in ns_cmp_owner()
199 struct rb_node *node; in __ns_tree_add_raw() local
200 const struct proc_ns_operations *ops = ns->ops; in __ns_tree_add_raw()
202 VFS_WARN_ON_ONCE(!ns->ns_id); in __ns_tree_add_raw()
206 /* Add to per-type tree and list */ in __ns_tree_add_raw()
207 node = ns_tree_node_add(&ns->ns_tree_node, ns_tree, ns_cmp); in __ns_tree_add_raw()
210 ns_tree_node_add(&ns->ns_unified_node, &ns_unified_root, ns_cmp_unified); in __ns_tree_add_raw()
216 VFS_WARN_ON_ONCE(!ops->owner); in __ns_tree_add_raw()
217 user_ns = ops->owner(ns); in __ns_tree_add_raw()
219 struct ns_common *owner = &user_ns->ns; in __ns_tree_add_raw()
220 VFS_WARN_ON_ONCE(owner->ns_type != CLONE_NEWUSER); in __ns_tree_add_raw()
223 ns_tree_node_add(&ns->ns_owner_node, &owner->ns_owner_root, ns_cmp_owner); in __ns_tree_add_raw()
230 VFS_WARN_ON_ONCE(node); in __ns_tree_add_raw()
235 const struct proc_ns_operations *ops = ns->ops; in __ns_tree_remove()
238 VFS_WARN_ON_ONCE(ns_tree_node_empty(&ns->ns_tree_node)); in __ns_tree_remove()
239 VFS_WARN_ON_ONCE(list_empty(&ns->ns_tree_node.ns_list_entry)); in __ns_tree_remove()
243 /* Remove from per-type tree and list */ in __ns_tree_remove()
244 ns_tree_node_del(&ns->ns_tree_node, ns_tree); in __ns_tree_remove()
247 ns_tree_node_del(&ns->ns_unified_node, &ns_unified_root); in __ns_tree_remove()
251 user_ns = ops->owner(ns); in __ns_tree_remove()
253 struct ns_common *owner = &user_ns->ns; in __ns_tree_remove()
254 ns_tree_node_del(&ns->ns_owner_node, &owner->ns_owner_root); in __ns_tree_remove()
262 static int ns_find(const void *key, const struct rb_node *node) in ns_find() argument
265 const struct ns_common *ns = node_to_ns(node); in ns_find()
267 if (ns_id < ns->ns_id) in ns_find()
268 return -1; in ns_find()
269 if (ns_id > ns->ns_id) in ns_find()
274 static int ns_find_unified(const void *key, const struct rb_node *node) in ns_find_unified() argument
277 const struct ns_common *ns = node_to_ns_unified(node); in ns_find_unified()
279 if (ns_id < ns->ns_id) in ns_find_unified()
280 return -1; in ns_find_unified()
281 if (ns_id > ns->ns_id) in ns_find_unified()
312 struct rb_node *node; in __ns_unified_tree_lookup_rcu() local
317 node = rb_find_rcu(&ns_id, &ns_unified_root.ns_rb, ns_find_unified); in __ns_unified_tree_lookup_rcu()
318 if (node) in __ns_unified_tree_lookup_rcu()
322 return node_to_ns_unified(node); in __ns_unified_tree_lookup_rcu()
328 struct rb_node *node; in __ns_tree_lookup_rcu() local
337 node = rb_find_rcu(&ns_id, &ns_tree->ns_rb, ns_find); in __ns_tree_lookup_rcu()
338 if (node) in __ns_tree_lookup_rcu()
342 return node_to_ns(node); in __ns_tree_lookup_rcu()
356 * __ns_tree_adjoined_rcu - find the next/previous namespace in the same
363 * there is no next/previous namespace, -ENOENT is returned.
373 list = rcu_dereference(list_bidir_prev_rcu(&ns->ns_tree_node.ns_list_entry)); in __ns_tree_adjoined_rcu()
375 list = rcu_dereference(list_next_rcu(&ns->ns_tree_node.ns_list_entry)); in __ns_tree_adjoined_rcu()
376 if (list_is_head(list, &ns_tree->ns_list_head)) in __ns_tree_adjoined_rcu()
377 return ERR_PTR(-ENOENT); in __ns_tree_adjoined_rcu()
383 * __ns_tree_gen_id - generate a new namespace id
384 * @ns: namespace to generate id for
385 * @id: if non-zero, this is the initial namespace and this is a fixed id
387 * Generates a new namespace id and assigns it to the namespace. All
388 * namespaces types share the same id space and thus can be compared
392 u64 __ns_tree_gen_id(struct ns_common *ns, u64 id) in __ns_tree_gen_id() argument
396 if (id) in __ns_tree_gen_id()
397 ns->ns_id = id; in __ns_tree_gen_id()
399 ns->ns_id = atomic64_inc_return(&namespace_cookie); in __ns_tree_gen_id()
400 return ns->ns_id; in __ns_tree_gen_id()
416 if (kls->user_ns_id != LISTNS_CURRENT_USER) in __free_klistns_free()
417 put_user_ns(kls->user_ns); in __free_klistns_free()
418 if (kls->first_ns && kls->first_ns->ops) in __free_klistns_free()
419 kls->first_ns->ops->put(kls->first_ns); in __free_klistns_free()
432 ret = get_user(usize, &req->size); in copy_ns_id_req()
434 return -EFAULT; in copy_ns_id_req()
436 return -E2BIG; in copy_ns_id_req()
438 return -EINVAL; in copy_ns_id_req()
443 if (kreq->spare != 0) in copy_ns_id_req()
444 return -EINVAL; in copy_ns_id_req()
445 if (kreq->ns_type & ~NS_ALL) in copy_ns_id_req()
446 return -EOPNOTSUPP; in copy_ns_id_req()
453 kls->last_ns_id = kreq->ns_id; in prepare_klistns()
454 kls->user_ns_id = kreq->user_ns_id; in prepare_klistns()
455 kls->nr_ns_ids = nr_ns_ids; in prepare_klistns()
456 kls->ns_type = kreq->ns_type; in prepare_klistns()
457 kls->uns_ids = ns_ids; in prepare_klistns()
462 * Lookup a namespace owned by owner with id >= ns_id.
463 * Returns the namespace with the smallest id that is >= ns_id.
468 struct rb_node *node; in lookup_ns_owner_at() local
470 VFS_WARN_ON_ONCE(owner->ns_type != CLONE_NEWUSER); in lookup_ns_owner_at()
474 node = owner->ns_owner_root.ns_rb.rb_node; in lookup_ns_owner_at()
475 while (node) { in lookup_ns_owner_at()
478 ns = node_to_ns_owner(node); in lookup_ns_owner_at()
479 if (ns_id <= ns->ns_id) { in lookup_ns_owner_at()
481 if (ns_id == ns->ns_id) in lookup_ns_owner_at()
483 node = node->rb_left; in lookup_ns_owner_at()
485 node = node->rb_right; in lookup_ns_owner_at()
512 return !kls->ns_type || (kls->ns_type & ns->ns_type); in ns_requested()
518 if (kls->user_ns && kls->userns_capable) in may_list_ns()
527 if (ns && ns->ops) in ns_put()
528 ns->ops->put(ns); in ns_put()
553 u64 __user *ns_ids = kls->uns_ids; in do_listns_userns()
554 size_t nr_ns_ids = kls->nr_ns_ids; in do_listns_userns()
559 VFS_WARN_ON_ONCE(!kls->user_ns_id); in do_listns_userns()
561 if (kls->user_ns_id == LISTNS_CURRENT_USER) in do_listns_userns()
563 else if (kls->user_ns_id) in do_listns_userns()
564 ns = lookup_ns_id(kls->user_ns_id, CLONE_NEWUSER); in do_listns_userns()
566 return -EINVAL; in do_listns_userns()
567 kls->user_ns = to_user_ns(ns); in do_listns_userns()
573 if (kls->last_ns_id) { in do_listns_userns()
574 kls->first_ns = lookup_ns_owner_at(kls->last_ns_id + 1, ns); in do_listns_userns()
575 if (!kls->first_ns) in do_listns_userns()
576 return -ENOENT; in do_listns_userns()
577 first_ns = kls->first_ns; in do_listns_userns()
581 head = &to_ns_common(kls->user_ns)->ns_owner_root.ns_list_head; in do_listns_userns()
582 kls->userns_capable = may_see_all_namespaces(); in do_listns_userns()
587 first_ns = list_entry_rcu(head->next, typeof(*first_ns), ns_owner_node.ns_list_entry); in do_listns_userns()
605 if (put_user(valid->ns_id, ns_ids + ret)) { in do_listns_userns()
607 return -EFAULT; in do_listns_userns()
610 nr_ns_ids--; in do_listns_userns()
622 * Lookup a namespace with id >= ns_id in either the unified tree or a type-specific tree.
623 * Returns the namespace with the smallest id that is >= ns_id.
629 struct rb_node *node; in lookup_ns_id_at() local
640 node = ns_tree->ns_rb.rb_node; in lookup_ns_id_at()
642 node = ns_unified_root.ns_rb.rb_node; in lookup_ns_id_at()
644 while (node) { in lookup_ns_id_at()
648 ns = node_to_ns(node); in lookup_ns_id_at()
650 ns = node_to_ns_unified(node); in lookup_ns_id_at()
652 if (ns_id <= ns->ns_id) { in lookup_ns_id_at()
654 ret = node_to_ns(node); in lookup_ns_id_at()
656 ret = node_to_ns_unified(node); in lookup_ns_id_at()
657 if (ns_id == ns->ns_id) in lookup_ns_id_at()
659 node = node->rb_left; in lookup_ns_id_at()
661 node = node->rb_right; in lookup_ns_id_at()
674 return list_entry_rcu(head->next, struct ns_common, ns_tree_node.ns_list_entry); in first_ns_common()
675 return list_entry_rcu(head->next, struct ns_common, ns_unified_node.ns_list_entry); in first_ns_common()
682 …return list_entry_rcu(ns->ns_tree_node.ns_list_entry.next, struct ns_common, ns_tree_node.ns_list_… in next_ns_common()
683 …return list_entry_rcu(ns->ns_unified_node.ns_list_entry.next, struct ns_common, ns_unified_node.ns… in next_ns_common()
691 return &ns->ns_tree_node.ns_list_entry == head; in ns_common_is_head()
692 return &ns->ns_unified_node.ns_list_entry == head; in ns_common_is_head()
697 u64 __user *ns_ids = kls->uns_ids; in do_listns()
698 size_t nr_ns_ids = kls->nr_ns_ids; in do_listns()
705 if (hweight32(kls->ns_type) == 1) in do_listns()
706 ns_type = kls->ns_type; in do_listns()
713 return -EINVAL; in do_listns()
716 if (kls->last_ns_id) { in do_listns()
717 kls->first_ns = lookup_ns_id_at(kls->last_ns_id + 1, ns_type); in do_listns()
718 if (!kls->first_ns) in do_listns()
719 return -ENOENT; in do_listns()
720 first_ns = kls->first_ns; in do_listns()
725 head = &ns_tree->ns_list_head; in do_listns()
747 if (put_user(valid->ns_id, ns_ids + ret)) { in do_listns()
749 return -EFAULT; in do_listns()
752 nr_ns_ids--; in do_listns()
772 return -EINVAL; in SYSCALL_DEFINE4()
775 return -EOVERFLOW; in SYSCALL_DEFINE4()
778 return -EFAULT; in SYSCALL_DEFINE4()