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
57 struct uid_gid_map uid_map;57 struct uid_gid_map uid_map;
58 struct uid_gid_map gid_map;58 struct uid_gid_map gid_map;
59 struct uid_gid_map projid_map;59 struct uid_gid_map projid_map;
60 atomic_t count;
61 struct user_namespace *parent;60 struct user_namespace *parent;
62 int level;61 int level;
63 kuid_t owner;62 kuid_t owner;
@@ -109,7 +108,7 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type); · 45 unmodified lines
109static inline struct user_namespace *get_user_ns(struct user_namespace *ns)108static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
110{109{
111 if (ns)110 if (ns)
112 atomic_inc(&ns->count);111 refcount_inc(&ns->ns.count);
113 return ns;112 return ns;
114}113}
115 114
@@ -119,7 +118,7 @@ extern void __put_user_ns(struct user_namespace *ns); · 3 unmodified lines
119 118
120static inline void put_user_ns(struct user_namespace *ns)119static inline void put_user_ns(struct user_namespace *ns)
121{120{
122 if (ns && atomic_dec_and_test(&ns->count))121 if (ns && refcount_dec_and_test(&ns->ns.count))
123 __put_user_ns(ns);122 __put_user_ns(ns);
124}123}
125 124
kernel/user.c+1−1
@@ -55,7 +55,7 @@ struct user_namespace init_user_ns = { · 54 unmodified lines
55 },55 },
56 },56 },
57 },57 },
58 .count = ATOMIC_INIT(3),58 .ns.count = REFCOUNT_INIT(3),
59 .owner = GLOBAL_ROOT_UID,59 .owner = GLOBAL_ROOT_UID,
60 .group = GLOBAL_ROOT_GID,60 .group = GLOBAL_ROOT_GID,
61 .ns.inum = PROC_USER_INIT_INO,61 .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
111 goto fail_free;111 goto fail_free;
112 ns->ns.ops = &userns_operations;112 ns->ns.ops = &userns_operations;
113 113
114 atomic_set(&ns->count, 1);114 refcount_set(&ns->ns.count, 1);
115 /* Leave the new->user_ns reference with the new user namespace. */115 /* Leave the new->user_ns reference with the new user namespace. */
116 ns->parent = parent_ns;116 ns->parent = parent_ns;
117 ns->level = parent_ns->level + 1;117 ns->level = parent_ns->level + 1;
@@ -197,7 +197,7 @@ static void free_user_ns(struct work_struct *work) · 79 unmodified lines
197 kmem_cache_free(user_ns_cachep, ns);197 kmem_cache_free(user_ns_cachep, ns);
198 dec_user_namespaces(ucounts);198 dec_user_namespaces(ucounts);
199 ns = parent;199 ns = parent;
200 } while (atomic_dec_and_test(&parent->count));200 } while (refcount_dec_and_test(&parent->ns.count));
201}201}
202 202
203void __put_user_ns(struct user_namespace *ns)203void __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