]> Pileus Git - ~andy/linux/commitdiff
pid_namespace: make freeing struct pid_namespace rcu-delayed
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 3 Oct 2013 17:28:06 +0000 (13:28 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 25 Oct 2013 03:43:29 +0000 (23:43 -0400)
makes procfs ->premission() instances safety in RCU mode independent
from vfsmount_lock.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
include/linux/pid_namespace.h
kernel/pid_namespace.c

index e2772666f004ef2d83b3493fb6f93b2625fb12f4..7246ef3d4455880f682f5d648fb75079f6c6d61c 100644 (file)
@@ -23,6 +23,7 @@ struct bsd_acct_struct;
 struct pid_namespace {
        struct kref kref;
        struct pidmap pidmap[PIDMAP_ENTRIES];
+       struct rcu_head rcu;
        int last_pid;
        unsigned int nr_hashed;
        struct task_struct *child_reaper;
index 42086551a24a19d9563148ee1810e30e68cccbbe..06c62de9c71191a68e5ea5b97bcb3a46b707a60d 100644 (file)
@@ -132,6 +132,12 @@ out:
        return ERR_PTR(err);
 }
 
+static void delayed_free_pidns(struct rcu_head *p)
+{
+       kmem_cache_free(pid_ns_cachep,
+                       container_of(p, struct pid_namespace, rcu));
+}
+
 static void destroy_pid_namespace(struct pid_namespace *ns)
 {
        int i;
@@ -140,7 +146,7 @@ static void destroy_pid_namespace(struct pid_namespace *ns)
        for (i = 0; i < PIDMAP_ENTRIES; i++)
                kfree(ns->pidmap[i].page);
        put_user_ns(ns->user_ns);
-       kmem_cache_free(pid_ns_cachep, ns);
+       call_rcu(&ns->rcu, delayed_free_pidns);
 }
 
 struct pid_namespace *copy_pid_ns(unsigned long flags,