diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 29 |
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 */ |
4045 | static void online_css(struct cgroup_subsys *ss, struct cgroup *cgrp) | 4045 | static 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); |