]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
cgroup: attach cgroup_open_file to all cgroup files
authorTejun Heo <tj@kernel.org>
Thu, 5 Dec 2013 17:28:04 +0000 (12:28 -0500)
committerTejun Heo <tj@kernel.org>
Thu, 5 Dec 2013 17:28:04 +0000 (12:28 -0500)
In preparation of conversion to kernfs, cgroup file handling is
updated so that it can be easily mapped to kernfs.  This patch
attaches cgroup_open_file, which used to be attached to pidlist files,
to all cgroup files, introduces seq_css/cft() accessors to determine
the cgroup_subsys_state and cftype associated with a given cgroup
seq_file, exports them as public interface.

This doesn't cause any behavior changes but unifies cgroup file
handling across different file types and will help converting them to
kernfs seq_show() interface.

v2: Li pointed out that the original patch was using
    single_open_size() incorrectly assuming that the size param is
    private data size.  Fix it by allocating @of separately and
    passing it to single_open() and explicitly freeing it in the
    release path.  This isn't the prettiest but this path is gonna be
    restructured by the following patches pretty soon.

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

index 53e11da6e357b6471c11b54cad9ef62b1c920d05..c3d698a72e02bb23d62b5b393c1d75f0fb2932e2 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/xattr.h>
 #include <linux/fs.h>
 #include <linux/percpu-refcount.h>
+#include <linux/seq_file.h>
 
 #ifdef CONFIG_CGROUPS
 
@@ -489,6 +490,26 @@ struct cftype_set {
        struct cftype                   *cfts;
 };
 
+/*
+ * cgroupfs file entry, pointed to from leaf dentry->d_fsdata.  Don't
+ * access directly.
+ */
+struct cfent {
+       struct list_head                node;
+       struct dentry                   *dentry;
+       struct cftype                   *type;
+       struct cgroup_subsys_state      *css;
+
+       /* file xattrs */
+       struct simple_xattrs            xattrs;
+};
+
+/* seq_file->private points to the following, only ->priv is public */
+struct cgroup_open_file {
+       struct cfent                    *cfe;
+       void                            *priv;
+};
+
 /*
  * See the comment above CGRP_ROOT_SANE_BEHAVIOR for details.  This
  * function can be called as long as @cgrp is accessible.
@@ -504,6 +525,18 @@ static inline const char *cgroup_name(const struct cgroup *cgrp)
        return rcu_dereference(cgrp->name)->name;
 }
 
+static inline struct cgroup_subsys_state *seq_css(struct seq_file *seq)
+{
+       struct cgroup_open_file *of = seq->private;
+       return of->cfe->css;
+}
+
+static inline struct cftype *seq_cft(struct seq_file *seq)
+{
+       struct cgroup_open_file *of = seq->private;
+       return of->cfe->type;
+}
+
 int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
 int cgroup_rm_cftypes(struct cftype *cfts);
 
index 17272893d3b8b0544970c0cb36eda63d2f40dba7..036c05d8e572e992b2d6a00944159fc6d7ac4530 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
 #include <linux/backing-dev.h>
-#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/magic.h>
 #include <linux/spinlock.h>
@@ -130,19 +129,6 @@ static struct cgroupfs_root cgroup_dummy_root;
 /* dummy_top is a shorthand for the dummy hierarchy's top cgroup */
 static struct cgroup * const cgroup_dummy_top = &cgroup_dummy_root.top_cgroup;
 
-/*
- * cgroupfs file entry, pointed to from leaf dentry->d_fsdata.
- */
-struct cfent {
-       struct list_head                node;
-       struct dentry                   *dentry;
-       struct cftype                   *type;
-       struct cgroup_subsys_state      *css;
-
-       /* file xattrs */
-       struct simple_xattrs            xattrs;
-};
-
 /* The list of hierarchy roots */
 
 static LIST_HEAD(cgroup_roots);
@@ -2302,9 +2288,8 @@ out_free:
 
 static int cgroup_seqfile_show(struct seq_file *m, void *arg)
 {
-       struct cfent *cfe = m->private;
-       struct cftype *cft = cfe->type;
-       struct cgroup_subsys_state *css = cfe->css;
+       struct cftype *cft = seq_cft(m);
+       struct cgroup_subsys_state *css = seq_css(m);
 
        if (cft->read_seq_string)
                return cft->read_seq_string(css, cft, m);
@@ -2353,10 +2338,20 @@ static int cgroup_file_open(struct inode *inode, struct file *file)
        WARN_ON_ONCE(cfe->css && cfe->css != css);
        cfe->css = css;
 
-       if (cft->open)
+       if (cft->open) {
                err = cft->open(inode, file);
-       else
-               err = single_open(file, cgroup_seqfile_show, cfe);
+       } else {
+               struct cgroup_open_file *of;
+
+               err = -ENOMEM;
+               of = kzalloc(sizeof(*of), GFP_KERNEL);
+               if (of) {
+                       of->cfe = cfe;
+                       err = single_open(file, cgroup_seqfile_show, of);
+                       if (err)
+                               kfree(of);
+               }
+       }
 
        if (css->ss && err)
                css_put(css);
@@ -2370,6 +2365,7 @@ static int cgroup_file_release(struct inode *inode, struct file *file)
 
        if (css->ss)
                css_put(css);
+       kfree(((struct seq_file *)file->private_data)->private);
        return single_release(inode, file);
 }
 
@@ -3368,12 +3364,6 @@ struct cgroup_pidlist {
        struct delayed_work destroy_dwork;
 };
 
-/* seq_file->private points to the following */
-struct cgroup_open_file {
-       struct cfent                    *cfe;
-       void                            *priv;
-};
-
 /*
  * 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.
@@ -3689,9 +3679,9 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
         * next pid to display, if any
         */
        struct cgroup_open_file *of = s->private;
-       struct cgroup *cgrp = of->cfe->css->cgroup;
+       struct cgroup *cgrp = seq_css(s)->cgroup;
        struct cgroup_pidlist *l;
-       enum cgroup_filetype type = of->cfe->type->private;
+       enum cgroup_filetype type = seq_cft(s)->private;
        int index = 0, pid = *pos;
        int *iter, ret;
 
@@ -3749,7 +3739,7 @@ static void cgroup_pidlist_stop(struct seq_file *s, void *v)
        if (l)
                mod_delayed_work(cgroup_pidlist_destroy_wq, &l->destroy_dwork,
                                 CGROUP_PIDLIST_DESTROY_DELAY);
-       mutex_unlock(&of->cfe->css->cgroup->pidlist_mutex);
+       mutex_unlock(&seq_css(s)->cgroup->pidlist_mutex);
 }
 
 static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
@@ -3766,7 +3756,7 @@ static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
        if (p >= end) {
                return NULL;
        } else {
-               *pos = cgroup_pid_fry(of->cfe->css->cgroup, *p);
+               *pos = cgroup_pid_fry(seq_css(s)->cgroup, *p);
                return p;
        }
 }