cgroup: introduce struct cgroup_pidlist_open_file
authorTejun Heo <tj@kernel.org>
Fri, 29 Nov 2013 15:42:58 +0000 (10:42 -0500)
committerTejun Heo <tj@kernel.org>
Fri, 29 Nov 2013 15:42:58 +0000 (10:42 -0500)
For pidlist files, seq_file->private pointed to the loaded
cgroup_pidlist; however, pidlist loading is planned to be moved to
cgroup_pidlist_start() for kernfs conversion and seq_file->private
needs to carry more information from open to allow that.

This patch introduces struct cgroup_pidlist_open_file which contains
type, cgrp and pidlist and updates pidlist seq_file->private to point
to it using seq_open_private() and seq_release_private().  Note that
this eventually will be replaced by kernfs_open_file.

While this patch makes more information available to seq_file
operations, they don't use it yet and this patch doesn't introduce any
behavior changes except for allocation of the extra private struct.

v2: use __seq_open_private() instead of seq_open_private() for brevity
    as suggested by Li.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
kernel/cgroup.c

index acdcddf8ab8207eaff53e541aa23c164f3c0a734..ef019c075d5daecf0d76a560c9a8ddcc4042e14b 100644 (file)
@@ -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)