Commit 42809dd4 authored by Tejun Heo's avatar Tejun Heo

cgroup: separate out cgroup_destroy_locked()

Separate out cgroup_destroy_locked() from cgroup_destroy().  This will
be later used in cgroup_create() failure path.

While at it, add lockdep asserts on i_mutex and cgroup_mutex, and move
@d and @parent assignments to their declarations.

This patch doesn't introduce any functional difference.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarLi Zefan <lizefan@huawei.com>
parent 02ae7486
...@@ -242,6 +242,8 @@ static DEFINE_SPINLOCK(hierarchy_id_lock); ...@@ -242,6 +242,8 @@ static DEFINE_SPINLOCK(hierarchy_id_lock);
*/ */
static int need_forkexit_callback __read_mostly; static int need_forkexit_callback __read_mostly;
static int cgroup_destroy_locked(struct cgroup *cgrp);
#ifdef CONFIG_PROVE_LOCKING #ifdef CONFIG_PROVE_LOCKING
int cgroup_lock_is_held(void) int cgroup_lock_is_held(void)
{ {
...@@ -4209,22 +4211,20 @@ static int cgroup_has_css_refs(struct cgroup *cgrp) ...@@ -4209,22 +4211,20 @@ static int cgroup_has_css_refs(struct cgroup *cgrp)
return 0; 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 = cgrp->dentry;
struct dentry *d; struct cgroup *parent = cgrp->parent;
struct cgroup *parent;
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
struct cgroup_event *event, *tmp; struct cgroup_event *event, *tmp;
struct cgroup_subsys *ss; struct cgroup_subsys *ss;
/* the vfs holds both inode->i_mutex already */ lockdep_assert_held(&d->d_inode->i_mutex);
mutex_lock(&cgroup_mutex); lockdep_assert_held(&cgroup_mutex);
parent = cgrp->parent;
if (atomic_read(&cgrp->count) || !list_empty(&cgrp->children)) { if (atomic_read(&cgrp->count) || !list_empty(&cgrp->children))
mutex_unlock(&cgroup_mutex);
return -EBUSY; return -EBUSY;
}
/* /*
* Block new css_tryget() by deactivating refcnt and mark @cgrp * Block new css_tryget() by deactivating refcnt and mark @cgrp
...@@ -4243,7 +4243,9 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) ...@@ -4243,7 +4243,9 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
/* /*
* Tell subsystems to initate destruction. pre_destroy() should be * Tell subsystems to initate destruction. pre_destroy() should be
* called with cgroup_mutex unlocked. See 3fa59dfbc3 ("cgroup: fix * 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); mutex_unlock(&cgroup_mutex);
for_each_subsys(cgrp->root, ss) for_each_subsys(cgrp->root, ss)
...@@ -4268,11 +4270,9 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) ...@@ -4268,11 +4270,9 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
/* delete this cgroup from parent->children */ /* delete this cgroup from parent->children */
list_del_rcu(&cgrp->sibling); list_del_rcu(&cgrp->sibling);
list_del_init(&cgrp->allcg_node); list_del_init(&cgrp->allcg_node);
d = dget(cgrp->dentry); dget(d);
cgroup_d_remove_dir(d); cgroup_d_remove_dir(d);
dput(d); dput(d);
...@@ -4293,10 +4293,20 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) ...@@ -4293,10 +4293,20 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
} }
spin_unlock(&cgrp->event_list_lock); spin_unlock(&cgrp->event_list_lock);
mutex_unlock(&cgroup_mutex);
return 0; 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) static void __init_or_module cgroup_init_cftsets(struct cgroup_subsys *ss)
{ {
INIT_LIST_HEAD(&ss->cftsets); INIT_LIST_HEAD(&ss->cftsets);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment