cgroup: factor out cgroup_create() out of cgroup_mkdir()

We're in the process of refactoring cgroup and css management paths to
separate them out to eventually allow cgroups which aren't visible
through cgroup fs.  This patch factors out cgroup_create() out of
cgroup_mkdir().  cgroup_create() contains all internal object creation
and initialization.  cgroup_mkdir() uses cgroup_create() to create the
internal cgroup and adds interface directory and file creation.

This patch doesn't cause any behavior differences.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Zefan Li <lizefan@huawei.com>
This commit is contained in:
Tejun Heo 2016-03-03 09:57:58 -05:00
parent 195e9b6c4b
commit a5bca21520

View file

@ -4888,33 +4888,19 @@ err_free_css:
return ERR_PTR(err); return ERR_PTR(err);
} }
static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, static struct cgroup *cgroup_create(struct cgroup *parent)
umode_t mode)
{ {
struct cgroup *parent, *cgrp, *tcgrp; struct cgroup_root *root = parent->root;
struct cgroup_root *root;
struct cgroup_subsys *ss; struct cgroup_subsys *ss;
struct kernfs_node *kn; struct cgroup *cgrp, *tcgrp;
int level, ssid, ret; int level = parent->level + 1;
int ssid, ret;
/* Do not accept '\n' to prevent making /proc/<pid>/cgroup unparsable.
*/
if (strchr(name, '\n'))
return -EINVAL;
parent = cgroup_kn_lock_live(parent_kn);
if (!parent)
return -ENODEV;
root = parent->root;
level = parent->level + 1;
/* allocate the cgroup and its ID, 0 is reserved for the root */ /* allocate the cgroup and its ID, 0 is reserved for the root */
cgrp = kzalloc(sizeof(*cgrp) + cgrp = kzalloc(sizeof(*cgrp) +
sizeof(cgrp->ancestor_ids[0]) * (level + 1), GFP_KERNEL); sizeof(cgrp->ancestor_ids[0]) * (level + 1), GFP_KERNEL);
if (!cgrp) { if (!cgrp)
ret = -ENOMEM; return ERR_PTR(-ENOMEM);
goto out_unlock;
}
ret = percpu_ref_init(&cgrp->self.refcnt, css_release, 0, GFP_KERNEL); ret = percpu_ref_init(&cgrp->self.refcnt, css_release, 0, GFP_KERNEL);
if (ret) if (ret)
@ -4978,6 +4964,40 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
cgroup_refresh_subtree_ss_mask(cgrp); cgroup_refresh_subtree_ss_mask(cgrp);
} }
return cgrp;
out_cancel_ref:
percpu_ref_exit(&cgrp->self.refcnt);
out_free_cgrp:
kfree(cgrp);
return ERR_PTR(ret);
out_destroy:
cgroup_destroy_locked(cgrp);
return ERR_PTR(ret);
}
static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
umode_t mode)
{
struct cgroup *parent, *cgrp;
struct cgroup_subsys *ss;
struct kernfs_node *kn;
int ssid, ret;
/* do not accept '\n' to prevent making /proc/<pid>/cgroup unparsable */
if (strchr(name, '\n'))
return -EINVAL;
parent = cgroup_kn_lock_live(parent_kn);
if (!parent)
return -ENODEV;
cgrp = cgroup_create(parent);
if (IS_ERR(cgrp)) {
ret = PTR_ERR(cgrp);
goto out_unlock;
}
/* create the directory */ /* create the directory */
kn = kernfs_create_dir(parent->kn, name, mode, cgrp); kn = kernfs_create_dir(parent->kn, name, mode, cgrp);
if (IS_ERR(kn)) { if (IS_ERR(kn)) {
@ -5012,17 +5032,11 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
ret = 0; ret = 0;
goto out_unlock; goto out_unlock;
out_cancel_ref: out_destroy:
percpu_ref_exit(&cgrp->self.refcnt); cgroup_destroy_locked(cgrp);
out_free_cgrp:
kfree(cgrp);
out_unlock: out_unlock:
cgroup_kn_unlock(parent_kn); cgroup_kn_unlock(parent_kn);
return ret; return ret;
out_destroy:
cgroup_destroy_locked(cgrp);
goto out_unlock;
} }
/* /*