Skip to content

Commit

Permalink
cgroup: use cgroup_lock_live_group(parent) in cgroup_create()
Browse files Browse the repository at this point in the history
This patch makes cgroup_create() fail if @parent is marked removed.
This is to prepare for further updates to cgroup_rmdir() path.

Note that this change isn't strictly necessary.  cgroup can only be
created via mkdir and the removed marking and dentry removal happen
without releasing cgroup_mutex, so cgroup_create() can never race with
cgroup_rmdir().  Even after the scheduled updates to cgroup_rmdir(),
cgroup_mkdir() and cgroup_rmdir() are synchronized by i_mutex
rendering the added liveliness check unnecessary.

Do it anyway such that locking is contained inside cgroup proper and
we don't get nasty surprises if we ever grow another caller of
cgroup_create().

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Li Zefan <lizefan@huawei.com>
  • Loading branch information
Tejun Heo committed Nov 5, 2012
1 parent e931608 commit 976c06b
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions kernel/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -3927,15 +3927,25 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
if (!cgrp)
return -ENOMEM;

/*
* Only live parents can have children. Note that the liveliness
* check isn't strictly necessary because cgroup_mkdir() and
* cgroup_rmdir() are fully synchronized by i_mutex; however, do it
* anyway so that locking is contained inside cgroup proper and we
* don't get nasty surprises if we ever grow another caller.
*/
if (!cgroup_lock_live_group(parent)) {
err = -ENODEV;
goto err_free;
}

/* Grab a reference on the superblock so the hierarchy doesn't
* get deleted on unmount if there are child cgroups. This
* can be done outside cgroup_mutex, since the sb can't
* disappear while someone has an open control file on the
* fs */
atomic_inc(&sb->s_active);

mutex_lock(&cgroup_mutex);

init_cgroup_housekeeping(cgrp);

cgrp->parent = parent;
Expand Down Expand Up @@ -4006,7 +4016,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,

/* Release the reference count that we took on the superblock */
deactivate_super(sb);

err_free:
kfree(cgrp);
return err;
}
Expand Down

0 comments on commit 976c06b

Please sign in to comment.