aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-11-05 12:16:59 -0500
committerTejun Heo <tj@kernel.org>2012-11-05 12:16:59 -0500
commit976c06bcccc50573997609fa7ec842479bd96ffb (patch)
tree451f67b3cb6e4b3eb52a1df56d9018eb447960f1 /kernel
parente93160803ffda2e67d9ff9cacb63bb6868c8398f (diff)
cgroup: use cgroup_lock_live_group(parent) in cgroup_create()
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>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cgroup.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index c194f9e4fc7b..f22e3cd1978b 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -3927,6 +3927,18 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
3927 if (!cgrp) 3927 if (!cgrp)
3928 return -ENOMEM; 3928 return -ENOMEM;
3929 3929
3930 /*
3931 * Only live parents can have children. Note that the liveliness
3932 * check isn't strictly necessary because cgroup_mkdir() and
3933 * cgroup_rmdir() are fully synchronized by i_mutex; however, do it
3934 * anyway so that locking is contained inside cgroup proper and we
3935 * don't get nasty surprises if we ever grow another caller.
3936 */
3937 if (!cgroup_lock_live_group(parent)) {
3938 err = -ENODEV;
3939 goto err_free;
3940 }
3941
3930 /* Grab a reference on the superblock so the hierarchy doesn't 3942 /* Grab a reference on the superblock so the hierarchy doesn't
3931 * get deleted on unmount if there are child cgroups. This 3943 * get deleted on unmount if there are child cgroups. This
3932 * can be done outside cgroup_mutex, since the sb can't 3944 * can be done outside cgroup_mutex, since the sb can't
@@ -3934,8 +3946,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
3934 * fs */ 3946 * fs */
3935 atomic_inc(&sb->s_active); 3947 atomic_inc(&sb->s_active);
3936 3948
3937 mutex_lock(&cgroup_mutex);
3938
3939 init_cgroup_housekeeping(cgrp); 3949 init_cgroup_housekeeping(cgrp);
3940 3950
3941 cgrp->parent = parent; 3951 cgrp->parent = parent;
@@ -4006,7 +4016,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4006 4016
4007 /* Release the reference count that we took on the superblock */ 4017 /* Release the reference count that we took on the superblock */
4008 deactivate_super(sb); 4018 deactivate_super(sb);
4009 4019err_free:
4010 kfree(cgrp); 4020 kfree(cgrp);
4011 return err; 4021 return err;
4012} 4022}