Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 339340
b: refs/heads/master
c: 42809dd
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo committed Nov 19, 2012
1 parent 05d9432 commit 4e9bcf0
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 02ae7486d05ae6df8395409a4945b2420f1e35c2
refs/heads/master: 42809dd4225b2f3127a4804314a1b33608620d96
40 changes: 25 additions & 15 deletions trunk/kernel/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ static DEFINE_SPINLOCK(hierarchy_id_lock);
*/
static int need_forkexit_callback __read_mostly;

static int cgroup_destroy_locked(struct cgroup *cgrp);

#ifdef CONFIG_PROVE_LOCKING
int cgroup_lock_is_held(void)
{
Expand Down Expand Up @@ -4209,22 +4211,20 @@ static int cgroup_has_css_refs(struct cgroup *cgrp)
return 0;
}

static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
static int cgroup_destroy_locked(struct cgroup *cgrp)
__releases(&cgroup_mutex) __acquires(&cgroup_mutex)
{
struct cgroup *cgrp = dentry->d_fsdata;
struct dentry *d;
struct cgroup *parent;
struct dentry *d = cgrp->dentry;
struct cgroup *parent = cgrp->parent;
DEFINE_WAIT(wait);
struct cgroup_event *event, *tmp;
struct cgroup_subsys *ss;

/* the vfs holds both inode->i_mutex already */
mutex_lock(&cgroup_mutex);
parent = cgrp->parent;
if (atomic_read(&cgrp->count) || !list_empty(&cgrp->children)) {
mutex_unlock(&cgroup_mutex);
lockdep_assert_held(&d->d_inode->i_mutex);
lockdep_assert_held(&cgroup_mutex);

if (atomic_read(&cgrp->count) || !list_empty(&cgrp->children))
return -EBUSY;
}

/*
* Block new css_tryget() by deactivating refcnt and mark @cgrp
Expand All @@ -4243,7 +4243,9 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
/*
* Tell subsystems to initate destruction. pre_destroy() should be
* called with cgroup_mutex unlocked. See 3fa59dfbc3 ("cgroup: fix
* potential deadlock in pre_destroy") for details.
* potential deadlock in pre_destroy") for details. This temporary
* unlocking should go away once cgroup_mutex is unexported from
* controllers.
*/
mutex_unlock(&cgroup_mutex);
for_each_subsys(cgrp->root, ss)
Expand All @@ -4268,11 +4270,9 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)

/* delete this cgroup from parent->children */
list_del_rcu(&cgrp->sibling);

list_del_init(&cgrp->allcg_node);

d = dget(cgrp->dentry);

dget(d);
cgroup_d_remove_dir(d);
dput(d);

Expand All @@ -4293,10 +4293,20 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
}
spin_unlock(&cgrp->event_list_lock);

mutex_unlock(&cgroup_mutex);
return 0;
}

static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
{
int ret;

mutex_lock(&cgroup_mutex);
ret = cgroup_destroy_locked(dentry->d_fsdata);
mutex_unlock(&cgroup_mutex);

return ret;
}

static void __init_or_module cgroup_init_cftsets(struct cgroup_subsys *ss)
{
INIT_LIST_HEAD(&ss->cftsets);
Expand Down

0 comments on commit 4e9bcf0

Please sign in to comment.