]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/cgroup.c
cgroup: fix potential deadlock in pre_destroy
[linux-2.6-omap-h63xx.git] / kernel / cgroup.c
index 35eebd5510c2165c6f8daa2cef1fecab9187d6d0..1a06be61dcd02810fabe8c0ca40d3f60be676488 100644 (file)
@@ -2472,10 +2472,7 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
                mutex_unlock(&cgroup_mutex);
                return -EBUSY;
        }
-
-       parent = cgrp->parent;
-       root = cgrp->root;
-       sb = root->sb;
+       mutex_unlock(&cgroup_mutex);
 
        /*
         * Call pre_destroy handlers of subsys. Notify subsystems
@@ -2483,7 +2480,14 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
         */
        cgroup_call_pre_destroy(cgrp);
 
-       if (cgroup_has_css_refs(cgrp)) {
+       mutex_lock(&cgroup_mutex);
+       parent = cgrp->parent;
+       root = cgrp->root;
+       sb = root->sb;
+
+       if (atomic_read(&cgrp->count)
+           || !list_empty(&cgrp->children)
+           || cgroup_has_css_refs(cgrp)) {
                mutex_unlock(&cgroup_mutex);
                return -EBUSY;
        }
@@ -2497,7 +2501,6 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
        list_del(&cgrp->sibling);
        spin_lock(&cgrp->dentry->d_lock);
        d = dget(cgrp->dentry);
-       cgrp->dentry = NULL;
        spin_unlock(&d->d_lock);
 
        cgroup_d_remove_dir(d);