History

user: Use generic ns_common::count

Switch over user namespaces to use the newly introduced common lifetime counter. Currently every namespace type has its own lifetime counter which is stored in the specific namespace struct. The lifetime counters are used identically for all namespaces types. Namespaces may of course have additional unrelated counters and these are not altered. This introduces a common lifetime counter into struct ns_common. The ns_common struct encompasses information that all namespaces share. That should include the lifetime counter since its common for all of them. It also allows us to unify the type of the counters across all namespaces. Most of them use refcount_t but one uses atomic_t and at least one uses kref. Especially the last one doesn't make much sense since it's just a wrapper around refcount_t since 2016 and actually complicates cleanup operations by having to use container_of() to cast the correct namespace struct out of struct ns_common. Having the lifetime counter for the namespaces in one place reduces maintenance cost. Not just because after switching all namespaces over we will have removed more code than we added but also because the logic is more easily understandable and we indicate to the user that the basic lifetime requirements for all namespaces are currently identical.

Kirill Tkhai committed 6 years ago

Commit 265cbd61 parent 8eb71d93 files · +5 −6Browse files

Unified · Split

3 files
  1. include/linux/user_namespace.h +2 −3
  2. kernel/user.c +1 −1
  3. kernel/user_namespace.c +2 −2
include/linux/user_namespace.h+2−3
@@ -57,7 +57,6 @@ struct user_namespace { · 56 unmodified lines
5757 struct uid_gid_map uid_map;
5858 struct uid_gid_map gid_map;
5959 struct uid_gid_map projid_map;
60− atomic_t count;
6160 struct user_namespace *parent;
6261 int level;
6362 kuid_t owner;
@@ -109,7 +108,7 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type); · 45 unmodified lines
109108 static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
110109 {
111110 if (ns)
112− atomic_inc(&ns->count);
111+ refcount_inc(&ns->ns.count);
113112 return ns;
114113 }
115114
@@ -119,7 +118,7 @@ extern void __put_user_ns(struct user_namespace *ns); · 3 unmodified lines
119118
120119 static inline void put_user_ns(struct user_namespace *ns)
121120 {
122− if (ns && atomic_dec_and_test(&ns->count))
121+ if (ns && refcount_dec_and_test(&ns->ns.count))
123122 __put_user_ns(ns);
124123 }
125124
kernel/user.c+1−1
@@ -55,7 +55,7 @@ struct user_namespace init_user_ns = { · 54 unmodified lines
5555 },
5656 },
5757 },
58− .count = ATOMIC_INIT(3),
58+ .ns.count = REFCOUNT_INIT(3),
5959 .owner = GLOBAL_ROOT_UID,
6060 .group = GLOBAL_ROOT_GID,
6161 .ns.inum = PROC_USER_INIT_INO,
kernel/user_namespace.c+2−2
@@ -111,7 +111,7 @@ int create_user_ns(struct cred *new) · 110 unmodified lines
111111 goto fail_free;
112112 ns->ns.ops = &userns_operations;
113113
114− atomic_set(&ns->count, 1);
114+ refcount_set(&ns->ns.count, 1);
115115 /* Leave the new->user_ns reference with the new user namespace. */
116116 ns->parent = parent_ns;
117117 ns->level = parent_ns->level + 1;
@@ -197,7 +197,7 @@ static void free_user_ns(struct work_struct *work) · 79 unmodified lines
197197 kmem_cache_free(user_ns_cachep, ns);
198198 dec_user_namespaces(ucounts);
199199 ns = parent;
200− } while (atomic_dec_and_test(&parent->count));
200+ } while (refcount_dec_and_test(&parent->ns.count));
201201 }
202202
203203 void __put_user_ns(struct user_namespace *ns)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t