diff mbox series

[22/23] cgroup: Add cgroup namespaces into ns_idr

Message ID 159611047870.535980.3790860133632973446.stgit@localhost.localdomain (mailing list archive)
State New, archived
Headers show
Series proc: Introduce /proc/namespaces/ directory to expose namespaces lineary | expand

Commit Message

Kirill Tkhai July 30, 2020, 12:01 p.m. UTC
Now they are exposed in /proc/namespace/ directory.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 include/linux/cgroup.h    |    1 +
 kernel/cgroup/namespace.c |   23 +++++++++++++++++++----
 2 files changed, 20 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 451c2d26a5db..38913d91fa92 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -858,6 +858,7 @@  struct cgroup_namespace {
 	struct user_namespace	*user_ns;
 	struct ucounts		*ucounts;
 	struct css_set          *root_cset;
+	struct rcu_head		rcu;
 };
 
 extern struct cgroup_namespace init_cgroup_ns;
diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c
index f5e8828c109c..64393bbafb2c 100644
--- a/kernel/cgroup/namespace.c
+++ b/kernel/cgroup/namespace.c
@@ -39,11 +39,12 @@  static struct cgroup_namespace *alloc_cgroup_ns(void)
 
 void free_cgroup_ns(struct cgroup_namespace *ns)
 {
+	ns_idr_unregister(&ns->ns);
 	put_css_set(ns->root_cset);
 	dec_cgroup_namespaces(ns->ucounts);
 	put_user_ns(ns->user_ns);
 	ns_free_inum(&ns->ns);
-	kfree(ns);
+	kfree_rcu(ns, rcu);
 }
 EXPORT_SYMBOL(free_cgroup_ns);
 
@@ -54,6 +55,7 @@  struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
 	struct cgroup_namespace *new_ns;
 	struct ucounts *ucounts;
 	struct css_set *cset;
+	int err;
 
 	BUG_ON(!old_ns);
 
@@ -78,16 +80,28 @@  struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
 
 	new_ns = alloc_cgroup_ns();
 	if (IS_ERR(new_ns)) {
-		put_css_set(cset);
-		dec_cgroup_namespaces(ucounts);
-		return new_ns;
+		err = PTR_ERR(new_ns);
+		goto err_put_css_set;
 	}
 
 	new_ns->user_ns = get_user_ns(user_ns);
 	new_ns->ucounts = ucounts;
 	new_ns->root_cset = cset;
 
+	err = ns_idr_register(&new_ns->ns);
+	if (err < 0)
+		goto err_put_user_ns;
+
 	return new_ns;
+
+err_put_user_ns:
+	put_user_ns(new_ns->user_ns);
+	ns_free_inum(&new_ns->ns);
+	kfree(new_ns);
+err_put_css_set:
+	put_css_set(cset);
+	dec_cgroup_namespaces(ucounts);
+	return ERR_PTR(err);
 }
 
 static inline struct cgroup_namespace *to_cg_ns(struct ns_common *ns)
@@ -152,6 +166,7 @@  const struct proc_ns_operations cgroupns_operations = {
 
 static __init int cgroup_namespaces_init(void)
 {
+	WARN_ON(ns_idr_register(&init_cgroup_ns.ns) < 0);
 	return 0;
 }
 subsys_initcall(cgroup_namespaces_init);