u64 ns_id;
struct /* global namespace rbtree and list */ {
struct rb_node ns_unified_tree_node;
+ struct list_head ns_unified_list_node;
};
struct /* per type rbtree and list */ {
struct rb_node ns_tree_node;
.ns_list_node = LIST_HEAD_INIT(nsname.ns.ns_list_node), \
.ns_owner_entry = LIST_HEAD_INIT(nsname.ns.ns_owner_entry), \
.ns_owner = LIST_HEAD_INIT(nsname.ns.ns_owner), \
+ .ns_unified_list_node = LIST_HEAD_INIT(nsname.ns.ns_unified_list_node), \
}
#define ns_common_init(__ns) \
RB_CLEAR_NODE(&ns->ns_unified_tree_node);
RB_CLEAR_NODE(&ns->ns_owner_tree_node);
INIT_LIST_HEAD(&ns->ns_list_node);
+ INIT_LIST_HEAD(&ns->ns_unified_list_node);
ns->ns_owner_tree = RB_ROOT;
INIT_LIST_HEAD(&ns->ns_owner);
INIT_LIST_HEAD(&ns->ns_owner_entry);
static __cacheline_aligned_in_smp DEFINE_SEQLOCK(ns_tree_lock);
static struct rb_root ns_unified_tree = RB_ROOT; /* protected by ns_tree_lock */
+static LIST_HEAD(ns_unified_list); /* protected by ns_tree_lock */
/**
* struct ns_tree - Namespace tree
else
list_add_rcu(&ns->ns_list_node, &node_to_ns(prev)->ns_list_node);
+ /* Add to unified tree and list */
rb_find_add_rcu(&ns->ns_unified_tree_node, &ns_unified_tree, ns_cmp_unified);
+ prev = rb_prev(&ns->ns_unified_tree_node);
+ if (!prev)
+ list_add_rcu(&ns->ns_unified_list_node, &ns_unified_list);
+ else
+ list_add_rcu(&ns->ns_unified_list_node, &node_to_ns_unified(prev)->ns_unified_list_node);
if (ops) {
struct user_namespace *user_ns;
write_seqlock(&ns_tree_lock);
rb_erase(&ns->ns_tree_node, &ns_tree->ns_tree);
- rb_erase(&ns->ns_unified_tree_node, &ns_unified_tree);
RB_CLEAR_NODE(&ns->ns_tree_node);
list_bidir_del_rcu(&ns->ns_list_node);
+ rb_erase(&ns->ns_unified_tree_node, &ns_unified_tree);
+ RB_CLEAR_NODE(&ns->ns_unified_tree_node);
+
+ list_bidir_del_rcu(&ns->ns_unified_list_node);
+
/* Remove from owner's rbtree if this namespace has an owner */
if (ops) {
user_ns = ops->owner(ns);