cgroup: add cgroup_v1v2_get_from_[fd/file]()

Add cgroup_v1v2_get_from_fd() and cgroup_v1v2_get_from_file() that
support both cgroup1 and cgroup2.

Signed-off-by: Yosry Ahmed <yosryahmed@google.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
Yosry Ahmed 2022-10-11 00:33:58 +00:00 committed by Tejun Heo
parent 03db771615
commit a6d1ce5951
2 changed files with 45 additions and 6 deletions

View file

@ -106,6 +106,7 @@ struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,
struct cgroup *cgroup_get_from_path(const char *path);
struct cgroup *cgroup_get_from_fd(int fd);
struct cgroup *cgroup_v1v2_get_from_fd(int fd);
int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);

View file

@ -6224,16 +6224,36 @@ void cgroup_fork(struct task_struct *child)
INIT_LIST_HEAD(&child->cg_list);
}
static struct cgroup *cgroup_get_from_file(struct file *f)
/**
* cgroup_v1v2_get_from_file - get a cgroup pointer from a file pointer
* @f: file corresponding to cgroup_dir
*
* Find the cgroup from a file pointer associated with a cgroup directory.
* Returns a pointer to the cgroup on success. ERR_PTR is returned if the
* cgroup cannot be found.
*/
static struct cgroup *cgroup_v1v2_get_from_file(struct file *f)
{
struct cgroup_subsys_state *css;
struct cgroup *cgrp;
css = css_tryget_online_from_dir(f->f_path.dentry, NULL);
if (IS_ERR(css))
return ERR_CAST(css);
cgrp = css->cgroup;
return css->cgroup;
}
/**
* cgroup_get_from_file - same as cgroup_v1v2_get_from_file, but only supports
* cgroup2.
*/
static struct cgroup *cgroup_get_from_file(struct file *f)
{
struct cgroup *cgrp = cgroup_v1v2_get_from_file(f);
if (IS_ERR(cgrp))
return ERR_CAST(cgrp);
if (!cgroup_on_dfl(cgrp)) {
cgroup_put(cgrp);
return ERR_PTR(-EBADF);
@ -6734,14 +6754,14 @@ EXPORT_SYMBOL_GPL(cgroup_get_from_path);
/**
* cgroup_get_from_fd - get a cgroup pointer from a fd
* @fd: fd obtained by open(cgroup2_dir)
* @fd: fd obtained by open(cgroup_dir)
*
* Find the cgroup from a fd which should be obtained
* by opening a cgroup directory. Returns a pointer to the
* cgroup on success. ERR_PTR is returned if the cgroup
* cannot be found.
*/
struct cgroup *cgroup_get_from_fd(int fd)
struct cgroup *cgroup_v1v2_get_from_fd(int fd)
{
struct cgroup *cgrp;
struct file *f;
@ -6750,10 +6770,28 @@ struct cgroup *cgroup_get_from_fd(int fd)
if (!f)
return ERR_PTR(-EBADF);
cgrp = cgroup_get_from_file(f);
cgrp = cgroup_v1v2_get_from_file(f);
fput(f);
return cgrp;
}
/**
* cgroup_get_from_fd - same as cgroup_v1v2_get_from_fd, but only supports
* cgroup2.
*/
struct cgroup *cgroup_get_from_fd(int fd)
{
struct cgroup *cgrp = cgroup_v1v2_get_from_fd(fd);
if (IS_ERR(cgrp))
return ERR_CAST(cgrp);
if (!cgroup_on_dfl(cgrp)) {
cgroup_put(cgrp);
return ERR_PTR(-EBADF);
}
return cgrp;
}
EXPORT_SYMBOL_GPL(cgroup_get_from_fd);
static u64 power_of_ten(int power)