]> 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 046c1609606bc627059aa6cd5df687fa86f15d3b..1a06be61dcd02810fabe8c0ca40d3f60be676488 100644 (file)
@@ -2104,7 +2104,7 @@ static void *cgroup_tasks_start(struct seq_file *s, loff_t *pos)
        down_read(&cgrp->pids_mutex);
        if (pid) {
                int end = cgrp->pids_length;
-               int i;
+
                while (index < end) {
                        int mid = (index + end) / 2;
                        if (cgrp->tasks_pids[mid] == pid) {
@@ -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);