css->flags |= CSS_ROOT;
BUG_ON(cgroup_css(cgrp, ss->subsys_id));
- rcu_assign_pointer(cgrp->subsys[ss->subsys_id], css);
}
/* invoke ->css_online() on a new CSS and mark it online if successful */
if (ss->css_online)
ret = ss->css_online(css);
- if (!ret)
+ if (!ret) {
css->flags |= CSS_ONLINE;
+ rcu_assign_pointer(css->cgroup->subsys[ss->subsys_id], css);
+ }
return ret;
}
static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
umode_t mode)
{
+ struct cgroup_subsys_state *css_ar[CGROUP_SUBSYS_COUNT] = { };
struct cgroup *cgrp;
struct cgroup_name *name;
struct cgroupfs_root *root = parent->root;
err = PTR_ERR(css);
goto err_free_all;
}
+ css_ar[ss->subsys_id] = css;
err = percpu_ref_init(&css->refcnt, css_release);
- if (err) {
- ss->css_free(css);
+ if (err)
goto err_free_all;
- }
init_css(css, ss, cgrp);
/* each css holds a ref to the cgroup's dentry and the parent css */
for_each_root_subsys(root, ss) {
- struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id);
+ struct cgroup_subsys_state *css = css_ar[ss->subsys_id];
dget(dentry);
percpu_ref_get(&css->parent->refcnt);
/* creation succeeded, notify subsystems */
for_each_root_subsys(root, ss) {
- struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id);
+ struct cgroup_subsys_state *css = css_ar[ss->subsys_id];
err = online_css(css);
if (err)
err_free_all:
for_each_root_subsys(root, ss) {
- struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id);
+ struct cgroup_subsys_state *css = css_ar[ss->subsys_id];
if (css) {
percpu_ref_cancel_init(&css->refcnt);
* need to invoke fork callbacks here. */
BUG_ON(!list_empty(&init_task.tasks));
- BUG_ON(online_css(cgroup_css(cgroup_dummy_top, ss->subsys_id)));
+ BUG_ON(online_css(css));
mutex_unlock(&cgroup_mutex);
}
write_unlock(&css_set_lock);
- ret = online_css(cgroup_css(cgroup_dummy_top, ss->subsys_id));
+ ret = online_css(css);
if (ret)
goto err_unload;