diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-18 21:54:49 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-18 21:54:49 +0100 |
commit | d110ec3a1e1f522e2e9dfceb9c36d6590c26d2d4 (patch) | |
tree | 86b2f8f1d22b74b05239525c55bd42e3db6afc03 /kernel/cgroup.c | |
parent | rcu: fix rcutorture behavior during reboot (diff) | |
parent | Merge branch 'i2c-fixes' of git://aeryn.fluff.org.uk/bjdooks/linux (diff) | |
download | linux-d110ec3a1e1f522e2e9dfceb9c36d6590c26d2d4.tar.xz linux-d110ec3a1e1f522e2e9dfceb9c36d6590c26d2d4.zip |
Merge branch 'linus' into core/rcu
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 35eebd5510c2..8185a0f09594 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -702,7 +702,7 @@ static int rebind_subsystems(struct cgroupfs_root *root, * any child cgroups exist. This is theoretically supportable * but involves complex error handling, so it's being left until * later */ - if (!list_empty(&cgrp->children)) + if (root->number_of_cgroups > 1) return -EBUSY; /* Process each subsystem */ @@ -2039,10 +2039,13 @@ int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry) struct cgroup *cgrp; struct cgroup_iter it; struct task_struct *tsk; + /* - * Validate dentry by checking the superblock operations + * Validate dentry by checking the superblock operations, + * and make sure it's a directory. */ - if (dentry->d_sb->s_op != &cgroup_ops) + if (dentry->d_sb->s_op != &cgroup_ops || + !S_ISDIR(dentry->d_inode->i_mode)) goto err; ret = 0; @@ -2472,10 +2475,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 +2483,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 +2504,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); |