提交 b1929db4 编写于 作者: T Tejun Heo

cgroup: allow ->post_create() to fail

There could be cases where controllers want to do initialization
operations which may fail from ->post_create().  This patch makes
->post_create() return -errno to indicate failure and online_css()
relay such failures.
Signed-off-by: NTejun Heo <tj@kernel.org>
Acked-by: NLi Zefan <lizefan@huawei.com>
Cc: Glauber Costa <glommer@parallels.com>
上级 4b8b47eb
...@@ -440,7 +440,7 @@ int cgroup_taskset_size(struct cgroup_taskset *tset); ...@@ -440,7 +440,7 @@ int cgroup_taskset_size(struct cgroup_taskset *tset);
struct cgroup_subsys { struct cgroup_subsys {
struct cgroup_subsys_state *(*create)(struct cgroup *cgrp); struct cgroup_subsys_state *(*create)(struct cgroup *cgrp);
void (*post_create)(struct cgroup *cgrp); int (*post_create)(struct cgroup *cgrp);
void (*pre_destroy)(struct cgroup *cgrp); void (*pre_destroy)(struct cgroup *cgrp);
void (*destroy)(struct cgroup *cgrp); void (*destroy)(struct cgroup *cgrp);
int (*can_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset); int (*can_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
......
...@@ -4041,14 +4041,18 @@ static void init_cgroup_css(struct cgroup_subsys_state *css, ...@@ -4041,14 +4041,18 @@ static void init_cgroup_css(struct cgroup_subsys_state *css,
INIT_WORK(&css->dput_work, css_dput_fn); INIT_WORK(&css->dput_work, css_dput_fn);
} }
/* invoke ->post_create() on a new CSS and mark it online */ /* invoke ->post_create() on a new CSS and mark it online if successful */
static void online_css(struct cgroup_subsys *ss, struct cgroup *cgrp) static int online_css(struct cgroup_subsys *ss, struct cgroup *cgrp)
{ {
int ret = 0;
lockdep_assert_held(&cgroup_mutex); lockdep_assert_held(&cgroup_mutex);
if (ss->post_create) if (ss->post_create)
ss->post_create(cgrp); ret = ss->post_create(cgrp);
cgrp->subsys[ss->subsys_id]->flags |= CSS_ONLINE; if (!ret)
cgrp->subsys[ss->subsys_id]->flags |= CSS_ONLINE;
return ret;
} }
/* if the CSS is online, invoke ->pre_destory() on it and mark it offline */ /* 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,12 +4178,15 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children); list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children);
root->number_of_cgroups++; root->number_of_cgroups++;
for_each_subsys(root, ss) { /* each css holds a ref to the cgroup's dentry */
/* each css holds a ref to the cgroup's dentry */ for_each_subsys(root, ss)
dget(dentry); dget(dentry);
/* creation succeeded, notify subsystems */ /* creation succeeded, notify subsystems */
online_css(ss, cgrp); for_each_subsys(root, ss) {
err = online_css(ss, cgrp);
if (err)
goto err_destroy;
} }
err = cgroup_populate_dir(cgrp, true, root->subsys_mask); err = cgroup_populate_dir(cgrp, true, root->subsys_mask);
...@@ -4393,7 +4400,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss) ...@@ -4393,7 +4400,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
BUG_ON(!list_empty(&init_task.tasks)); BUG_ON(!list_empty(&init_task.tasks));
ss->active = 1; ss->active = 1;
online_css(ss, dummytop); BUG_ON(online_css(ss, dummytop));
mutex_unlock(&cgroup_mutex); mutex_unlock(&cgroup_mutex);
...@@ -4500,7 +4507,9 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss) ...@@ -4500,7 +4507,9 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
write_unlock(&css_set_lock); write_unlock(&css_set_lock);
ss->active = 1; ss->active = 1;
online_css(ss, dummytop); ret = online_css(ss, dummytop);
if (ret)
goto err_unload;
/* success! */ /* success! */
mutex_unlock(&cgroup_mutex); mutex_unlock(&cgroup_mutex);
......
...@@ -112,7 +112,7 @@ static struct cgroup_subsys_state *freezer_create(struct cgroup *cgroup) ...@@ -112,7 +112,7 @@ static struct cgroup_subsys_state *freezer_create(struct cgroup *cgroup)
* parent's freezing state while holding both parent's and our * parent's freezing state while holding both parent's and our
* freezer->lock. * freezer->lock.
*/ */
static void freezer_post_create(struct cgroup *cgroup) static int freezer_post_create(struct cgroup *cgroup)
{ {
struct freezer *freezer = cgroup_freezer(cgroup); struct freezer *freezer = cgroup_freezer(cgroup);
struct freezer *parent = parent_freezer(freezer); struct freezer *parent = parent_freezer(freezer);
...@@ -136,6 +136,8 @@ static void freezer_post_create(struct cgroup *cgroup) ...@@ -136,6 +136,8 @@ static void freezer_post_create(struct cgroup *cgroup)
spin_unlock(&freezer->lock); spin_unlock(&freezer->lock);
if (parent) if (parent)
spin_unlock_irq(&parent->lock); spin_unlock_irq(&parent->lock);
return 0;
} }
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册