aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 027b66e66698..c389f4258681 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4041,14 +4041,18 @@ static void init_cgroup_css(struct cgroup_subsys_state *css,
4041 INIT_WORK(&css->dput_work, css_dput_fn); 4041 INIT_WORK(&css->dput_work, css_dput_fn);
4042} 4042}
4043 4043
4044/* invoke ->post_create() on a new CSS and mark it online */ 4044/* invoke ->post_create() on a new CSS and mark it online if successful */
4045static void online_css(struct cgroup_subsys *ss, struct cgroup *cgrp) 4045static int online_css(struct cgroup_subsys *ss, struct cgroup *cgrp)
4046{ 4046{
4047 int ret = 0;
4048
4047 lockdep_assert_held(&cgroup_mutex); 4049 lockdep_assert_held(&cgroup_mutex);
4048 4050
4049 if (ss->post_create) 4051 if (ss->post_create)
4050 ss->post_create(cgrp); 4052 ret = ss->post_create(cgrp);
4051 cgrp->subsys[ss->subsys_id]->flags |= CSS_ONLINE; 4053 if (!ret)
4054 cgrp->subsys[ss->subsys_id]->flags |= CSS_ONLINE;
4055 return ret;
4052} 4056}
4053 4057
4054/* if the CSS is online, invoke ->pre_destory() on it and mark it offline */ 4058/* if the CSS is online, invoke ->pre_destory() on it and mark it offline */
@@ -4174,12 +4178,15 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4174 list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children); 4178 list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children);
4175 root->number_of_cgroups++; 4179 root->number_of_cgroups++;
4176 4180
4177 for_each_subsys(root, ss) { 4181 /* each css holds a ref to the cgroup's dentry */
4178 /* each css holds a ref to the cgroup's dentry */ 4182 for_each_subsys(root, ss)
4179 dget(dentry); 4183 dget(dentry);
4180 4184
4181 /* creation succeeded, notify subsystems */ 4185 /* creation succeeded, notify subsystems */
4182 online_css(ss, cgrp); 4186 for_each_subsys(root, ss) {
4187 err = online_css(ss, cgrp);
4188 if (err)
4189 goto err_destroy;
4183 } 4190 }
4184 4191
4185 err = cgroup_populate_dir(cgrp, true, root->subsys_mask); 4192 err = cgroup_populate_dir(cgrp, true, root->subsys_mask);
@@ -4393,7 +4400,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
4393 BUG_ON(!list_empty(&init_task.tasks)); 4400 BUG_ON(!list_empty(&init_task.tasks));
4394 4401
4395 ss->active = 1; 4402 ss->active = 1;
4396 online_css(ss, dummytop); 4403 BUG_ON(online_css(ss, dummytop));
4397 4404
4398 mutex_unlock(&cgroup_mutex); 4405 mutex_unlock(&cgroup_mutex);
4399 4406
@@ -4500,7 +4507,9 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
4500 write_unlock(&css_set_lock); 4507 write_unlock(&css_set_lock);
4501 4508
4502 ss->active = 1; 4509 ss->active = 1;
4503 online_css(ss, dummytop); 4510 ret = online_css(ss, dummytop);
4511 if (ret)
4512 goto err_unload;
4504 4513
4505 /* success! */ 4514 /* success! */
4506 mutex_unlock(&cgroup_mutex); 4515 mutex_unlock(&cgroup_mutex);