Commit 5d22444f authored by Tejun Heo's avatar Tejun Heo

cgroup: generalize cgroup_pidlist_open_file

In preparation of conversion to kernfs, cgroup file handling is
updated so that it can be easily mapped to kernfs.  This patch renames
cgroup_pidlist_open_file to cgroup_open_file and updates it so that it
only contains a field to identify the specific file, ->cfe, and an
opaque ->priv pointer.  When cgroup is converted to kernfs, this will
be replaced by kernfs_open_file which contains about the same
information.

As whether the file is "cgroup.procs" or "tasks" should now be
determined from cgroup_open_file->cfe, the cftype->private for the two
files now carry the file type and cgroup_pidlist_start() reads the
type through cfe->type->private.  This makes the distinction between
cgroup_tasks_open() and cgroup_procs_open() unnecessary.
cgroup_pidlist_open() is now directly used as the open method.

This patch doesn't make any behavior changes.

v2: Refreshed on top of the updated "cgroup: introduce struct
    cgroup_pidlist_open_file".
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarLi Zefan <lizefan@huawei.com>
parent 896f5199
...@@ -3369,10 +3369,9 @@ struct cgroup_pidlist { ...@@ -3369,10 +3369,9 @@ struct cgroup_pidlist {
}; };
/* seq_file->private points to the following */ /* seq_file->private points to the following */
struct cgroup_pidlist_open_file { struct cgroup_open_file {
enum cgroup_filetype type; struct cfent *cfe;
struct cgroup *cgrp; void *priv;
struct cgroup_pidlist *pidlist;
}; };
/* /*
...@@ -3689,33 +3688,35 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos) ...@@ -3689,33 +3688,35 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
* after a seek to the start). Use a binary-search to find the * after a seek to the start). Use a binary-search to find the
* next pid to display, if any * next pid to display, if any
*/ */
struct cgroup_pidlist_open_file *of = s->private; struct cgroup_open_file *of = s->private;
struct cgroup *cgrp = of->cgrp; struct cgroup *cgrp = of->cfe->css->cgroup;
struct cgroup_pidlist *l; struct cgroup_pidlist *l;
enum cgroup_filetype type = of->cfe->type->private;
int index = 0, pid = *pos; int index = 0, pid = *pos;
int *iter, ret; int *iter, ret;
mutex_lock(&cgrp->pidlist_mutex); mutex_lock(&cgrp->pidlist_mutex);
/* /*
* !NULL @of->pidlist indicates that this isn't the first start() * !NULL @of->priv indicates that this isn't the first start()
* after open. If the matching pidlist is around, we can use that. * after open. If the matching pidlist is around, we can use that.
* Look for it. Note that @of->pidlist can't be used directly. It * Look for it. Note that @of->priv can't be used directly. It
* could already have been destroyed. * could already have been destroyed.
*/ */
if (of->pidlist) if (of->priv)
of->pidlist = cgroup_pidlist_find(cgrp, of->type); of->priv = cgroup_pidlist_find(cgrp, type);
/* /*
* Either this is the first start() after open or the matching * Either this is the first start() after open or the matching
* pidlist has been destroyed inbetween. Create a new one. * pidlist has been destroyed inbetween. Create a new one.
*/ */
if (!of->pidlist) { if (!of->priv) {
ret = pidlist_array_load(of->cgrp, of->type, &of->pidlist); ret = pidlist_array_load(cgrp, type,
(struct cgroup_pidlist **)&of->priv);
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);
} }
l = of->pidlist; l = of->priv;
if (pid) { if (pid) {
int end = l->length; int end = l->length;
...@@ -3742,19 +3743,19 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos) ...@@ -3742,19 +3743,19 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
static void cgroup_pidlist_stop(struct seq_file *s, void *v) static void cgroup_pidlist_stop(struct seq_file *s, void *v)
{ {
struct cgroup_pidlist_open_file *of = s->private; struct cgroup_open_file *of = s->private;
struct cgroup_pidlist *l = of->priv;
if (of->pidlist) if (l)
mod_delayed_work(cgroup_pidlist_destroy_wq, mod_delayed_work(cgroup_pidlist_destroy_wq, &l->destroy_dwork,
&of->pidlist->destroy_dwork,
CGROUP_PIDLIST_DESTROY_DELAY); CGROUP_PIDLIST_DESTROY_DELAY);
mutex_unlock(&of->cgrp->pidlist_mutex); mutex_unlock(&of->cfe->css->cgroup->pidlist_mutex);
} }
static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos) static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
{ {
struct cgroup_pidlist_open_file *of = s->private; struct cgroup_open_file *of = s->private;
struct cgroup_pidlist *l = of->pidlist; struct cgroup_pidlist *l = of->priv;
pid_t *p = v; pid_t *p = v;
pid_t *end = l->list + l->length; pid_t *end = l->list + l->length;
/* /*
...@@ -3765,7 +3766,7 @@ static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos) ...@@ -3765,7 +3766,7 @@ static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
if (p >= end) { if (p >= end) {
return NULL; return NULL;
} else { } else {
*pos = cgroup_pid_fry(of->cgrp, *p); *pos = cgroup_pid_fry(of->cfe->css->cgroup, *p);
return p; return p;
} }
} }
...@@ -3799,10 +3800,10 @@ static const struct file_operations cgroup_pidlist_operations = { ...@@ -3799,10 +3800,10 @@ static const struct file_operations cgroup_pidlist_operations = {
* in the cgroup. * in the cgroup.
*/ */
/* helper function for the two below it */ /* helper function for the two below it */
static int cgroup_pidlist_open(struct file *file, enum cgroup_filetype type) static int cgroup_pidlist_open(struct inode *unused, struct file *file)
{ {
struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); struct cfent *cfe = __d_cfe(file->f_dentry);
struct cgroup_pidlist_open_file *of; struct cgroup_open_file *of;
/* configure file information */ /* configure file information */
file->f_op = &cgroup_pidlist_operations; file->f_op = &cgroup_pidlist_operations;
...@@ -3812,18 +3813,9 @@ static int cgroup_pidlist_open(struct file *file, enum cgroup_filetype type) ...@@ -3812,18 +3813,9 @@ static int cgroup_pidlist_open(struct file *file, enum cgroup_filetype type)
if (!of) if (!of)
return -ENOMEM; return -ENOMEM;
of->type = type; of->cfe = cfe;
of->cgrp = cgrp;
return 0; return 0;
} }
static int cgroup_tasks_open(struct inode *unused, struct file *file)
{
return cgroup_pidlist_open(file, CGROUP_FILE_TASKS);
}
static int cgroup_procs_open(struct inode *unused, struct file *file)
{
return cgroup_pidlist_open(file, CGROUP_FILE_PROCS);
}
static u64 cgroup_read_notify_on_release(struct cgroup_subsys_state *css, static u64 cgroup_read_notify_on_release(struct cgroup_subsys_state *css,
struct cftype *cft) struct cftype *cft)
...@@ -3878,7 +3870,8 @@ static int cgroup_clone_children_write(struct cgroup_subsys_state *css, ...@@ -3878,7 +3870,8 @@ static int cgroup_clone_children_write(struct cgroup_subsys_state *css,
static struct cftype cgroup_base_files[] = { static struct cftype cgroup_base_files[] = {
{ {
.name = "cgroup.procs", .name = "cgroup.procs",
.open = cgroup_procs_open, .open = cgroup_pidlist_open,
.private = CGROUP_FILE_PROCS,
.write_u64 = cgroup_procs_write, .write_u64 = cgroup_procs_write,
.mode = S_IRUGO | S_IWUSR, .mode = S_IRUGO | S_IWUSR,
}, },
...@@ -3902,7 +3895,8 @@ static struct cftype cgroup_base_files[] = { ...@@ -3902,7 +3895,8 @@ static struct cftype cgroup_base_files[] = {
{ {
.name = "tasks", .name = "tasks",
.flags = CFTYPE_INSANE, /* use "procs" instead */ .flags = CFTYPE_INSANE, /* use "procs" instead */
.open = cgroup_tasks_open, .open = cgroup_pidlist_open,
.private = CGROUP_FILE_TASKS,
.write_u64 = cgroup_tasks_write, .write_u64 = cgroup_tasks_write,
.mode = S_IRUGO | S_IWUSR, .mode = S_IRUGO | S_IWUSR,
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment