diff --git a/kernel/cgroup.c b/kernel/cgroup.c index acdcddf8ab82..ef019c075d5d 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -3468,6 +3468,13 @@ struct cgroup_pidlist { struct delayed_work destroy_dwork; }; +/* seq_file->private points to the following */ +struct cgroup_pidlist_open_file { + enum cgroup_filetype type; + struct cgroup *cgrp; + struct cgroup_pidlist *pidlist; +}; + /* * The following two functions "fix" the issue where there are more pids * than kmalloc will give memory for; in such cases, we use vmalloc/vfree. @@ -3739,7 +3746,8 @@ 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 * next pid to display, if any */ - struct cgroup_pidlist *l = s->private; + struct cgroup_pidlist_open_file *of = s->private; + struct cgroup_pidlist *l = of->pidlist; int index = 0, pid = *pos; int *iter; @@ -3769,13 +3777,15 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos) static void cgroup_pidlist_stop(struct seq_file *s, void *v) { - struct cgroup_pidlist *l = s->private; - up_read(&l->rwsem); + struct cgroup_pidlist_open_file *of = s->private; + + up_read(&of->pidlist->rwsem); } static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos) { - struct cgroup_pidlist *l = s->private; + struct cgroup_pidlist_open_file *of = s->private; + struct cgroup_pidlist *l = of->pidlist; pid_t *p = v; pid_t *end = l->list + l->length; /* @@ -3820,11 +3830,11 @@ static void cgroup_release_pid_array(struct cgroup_pidlist *l) static int cgroup_pidlist_release(struct inode *inode, struct file *file) { - struct cgroup_pidlist *l; + struct cgroup_pidlist_open_file *of; - l = ((struct seq_file *)file->private_data)->private; - cgroup_release_pid_array(l); - return seq_release(inode, file); + of = ((struct seq_file *)file->private_data)->private; + cgroup_release_pid_array(of->pidlist); + return seq_release_private(inode, file); } static const struct file_operations cgroup_pidlist_operations = { @@ -3843,6 +3853,7 @@ static const struct file_operations cgroup_pidlist_operations = { static int cgroup_pidlist_open(struct file *file, enum cgroup_filetype type) { struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); + struct cgroup_pidlist_open_file *of; struct cgroup_pidlist *l; int retval; @@ -3853,12 +3864,16 @@ static int cgroup_pidlist_open(struct file *file, enum cgroup_filetype type) /* configure file information */ file->f_op = &cgroup_pidlist_operations; - retval = seq_open(file, &cgroup_pidlist_seq_operations); - if (retval) { + of = __seq_open_private(file, &cgroup_pidlist_seq_operations, + sizeof(*of)); + if (!of) { cgroup_release_pid_array(l); - return retval; + return -ENOMEM; } - ((struct seq_file *)file->private_data)->private = l; + + of->type = type; + of->cgrp = cgrp; + of->pidlist = l; return 0; } static int cgroup_tasks_open(struct inode *unused, struct file *file)