aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-12-05 12:28:04 -0500
committerTejun Heo <tj@kernel.org>2013-12-05 12:28:04 -0500
commit7da112792753d71aed44b918395892a1fc53048a (patch)
tree7b370245a961024428a9247f8999f0f4b51c2c4f
parent5d22444f427511fe7c4733b233680309af5b071c (diff)
cgroup: attach cgroup_open_file to all cgroup files
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>
-rw-r--r--include/linux/cgroup.h33
-rw-r--r--kernel/cgroup.c50
2 files changed, 53 insertions, 30 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 53e11da6e357..c3d698a72e02 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -21,6 +21,7 @@
21#include <linux/xattr.h> 21#include <linux/xattr.h>
22#include <linux/fs.h> 22#include <linux/fs.h>
23#include <linux/percpu-refcount.h> 23#include <linux/percpu-refcount.h>
24#include <linux/seq_file.h>
24 25
25#ifdef CONFIG_CGROUPS 26#ifdef CONFIG_CGROUPS
26 27
@@ -490,6 +491,26 @@ struct cftype_set {
490}; 491};
491 492
492/* 493/*
494 * cgroupfs file entry, pointed to from leaf dentry->d_fsdata. Don't
495 * access directly.
496 */
497struct cfent {
498 struct list_head node;
499 struct dentry *dentry;
500 struct cftype *type;
501 struct cgroup_subsys_state *css;
502
503 /* file xattrs */
504 struct simple_xattrs xattrs;
505};
506
507/* seq_file->private points to the following, only ->priv is public */
508struct cgroup_open_file {
509 struct cfent *cfe;
510 void *priv;
511};
512
513/*
493 * See the comment above CGRP_ROOT_SANE_BEHAVIOR for details. This 514 * See the comment above CGRP_ROOT_SANE_BEHAVIOR for details. This
494 * function can be called as long as @cgrp is accessible. 515 * function can be called as long as @cgrp is accessible.
495 */ 516 */
@@ -504,6 +525,18 @@ static inline const char *cgroup_name(const struct cgroup *cgrp)
504 return rcu_dereference(cgrp->name)->name; 525 return rcu_dereference(cgrp->name)->name;
505} 526}
506 527
528static inline struct cgroup_subsys_state *seq_css(struct seq_file *seq)
529{
530 struct cgroup_open_file *of = seq->private;
531 return of->cfe->css;
532}
533
534static inline struct cftype *seq_cft(struct seq_file *seq)
535{
536 struct cgroup_open_file *of = seq->private;
537 return of->cfe->type;
538}
539
507int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); 540int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
508int cgroup_rm_cftypes(struct cftype *cfts); 541int cgroup_rm_cftypes(struct cftype *cfts);
509 542
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 17272893d3b8..036c05d8e572 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -41,7 +41,6 @@
41#include <linux/rcupdate.h> 41#include <linux/rcupdate.h>
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/backing-dev.h> 43#include <linux/backing-dev.h>
44#include <linux/seq_file.h>
45#include <linux/slab.h> 44#include <linux/slab.h>
46#include <linux/magic.h> 45#include <linux/magic.h>
47#include <linux/spinlock.h> 46#include <linux/spinlock.h>
@@ -130,19 +129,6 @@ static struct cgroupfs_root cgroup_dummy_root;
130/* dummy_top is a shorthand for the dummy hierarchy's top cgroup */ 129/* dummy_top is a shorthand for the dummy hierarchy's top cgroup */
131static struct cgroup * const cgroup_dummy_top = &cgroup_dummy_root.top_cgroup; 130static struct cgroup * const cgroup_dummy_top = &cgroup_dummy_root.top_cgroup;
132 131
133/*
134 * cgroupfs file entry, pointed to from leaf dentry->d_fsdata.
135 */
136struct cfent {
137 struct list_head node;
138 struct dentry *dentry;
139 struct cftype *type;
140 struct cgroup_subsys_state *css;
141
142 /* file xattrs */
143 struct simple_xattrs xattrs;
144};
145
146/* The list of hierarchy roots */ 132/* The list of hierarchy roots */
147 133
148static LIST_HEAD(cgroup_roots); 134static LIST_HEAD(cgroup_roots);
@@ -2302,9 +2288,8 @@ out_free:
2302 2288
2303static int cgroup_seqfile_show(struct seq_file *m, void *arg) 2289static int cgroup_seqfile_show(struct seq_file *m, void *arg)
2304{ 2290{
2305 struct cfent *cfe = m->private; 2291 struct cftype *cft = seq_cft(m);
2306 struct cftype *cft = cfe->type; 2292 struct cgroup_subsys_state *css = seq_css(m);
2307 struct cgroup_subsys_state *css = cfe->css;
2308 2293
2309 if (cft->read_seq_string) 2294 if (cft->read_seq_string)
2310 return cft->read_seq_string(css, cft, m); 2295 return cft->read_seq_string(css, cft, m);
@@ -2353,10 +2338,20 @@ static int cgroup_file_open(struct inode *inode, struct file *file)
2353 WARN_ON_ONCE(cfe->css && cfe->css != css); 2338 WARN_ON_ONCE(cfe->css && cfe->css != css);
2354 cfe->css = css; 2339 cfe->css = css;
2355 2340
2356 if (cft->open) 2341 if (cft->open) {
2357 err = cft->open(inode, file); 2342 err = cft->open(inode, file);
2358 else 2343 } else {
2359 err = single_open(file, cgroup_seqfile_show, cfe); 2344 struct cgroup_open_file *of;
2345
2346 err = -ENOMEM;
2347 of = kzalloc(sizeof(*of), GFP_KERNEL);
2348 if (of) {
2349 of->cfe = cfe;
2350 err = single_open(file, cgroup_seqfile_show, of);
2351 if (err)
2352 kfree(of);
2353 }
2354 }
2360 2355
2361 if (css->ss && err) 2356 if (css->ss && err)
2362 css_put(css); 2357 css_put(css);
@@ -2370,6 +2365,7 @@ static int cgroup_file_release(struct inode *inode, struct file *file)
2370 2365
2371 if (css->ss) 2366 if (css->ss)
2372 css_put(css); 2367 css_put(css);
2368 kfree(((struct seq_file *)file->private_data)->private);
2373 return single_release(inode, file); 2369 return single_release(inode, file);
2374} 2370}
2375 2371
@@ -3368,12 +3364,6 @@ struct cgroup_pidlist {
3368 struct delayed_work destroy_dwork; 3364 struct delayed_work destroy_dwork;
3369}; 3365};
3370 3366
3371/* seq_file->private points to the following */
3372struct cgroup_open_file {
3373 struct cfent *cfe;
3374 void *priv;
3375};
3376
3377/* 3367/*
3378 * The following two functions "fix" the issue where there are more pids 3368 * The following two functions "fix" the issue where there are more pids
3379 * than kmalloc will give memory for; in such cases, we use vmalloc/vfree. 3369 * 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)
3689 * next pid to display, if any 3679 * next pid to display, if any
3690 */ 3680 */
3691 struct cgroup_open_file *of = s->private; 3681 struct cgroup_open_file *of = s->private;
3692 struct cgroup *cgrp = of->cfe->css->cgroup; 3682 struct cgroup *cgrp = seq_css(s)->cgroup;
3693 struct cgroup_pidlist *l; 3683 struct cgroup_pidlist *l;
3694 enum cgroup_filetype type = of->cfe->type->private; 3684 enum cgroup_filetype type = seq_cft(s)->private;
3695 int index = 0, pid = *pos; 3685 int index = 0, pid = *pos;
3696 int *iter, ret; 3686 int *iter, ret;
3697 3687
@@ -3749,7 +3739,7 @@ static void cgroup_pidlist_stop(struct seq_file *s, void *v)
3749 if (l) 3739 if (l)
3750 mod_delayed_work(cgroup_pidlist_destroy_wq, &l->destroy_dwork, 3740 mod_delayed_work(cgroup_pidlist_destroy_wq, &l->destroy_dwork,
3751 CGROUP_PIDLIST_DESTROY_DELAY); 3741 CGROUP_PIDLIST_DESTROY_DELAY);
3752 mutex_unlock(&of->cfe->css->cgroup->pidlist_mutex); 3742 mutex_unlock(&seq_css(s)->cgroup->pidlist_mutex);
3753} 3743}
3754 3744
3755static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos) 3745static 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)
3766 if (p >= end) { 3756 if (p >= end) {
3767 return NULL; 3757 return NULL;
3768 } else { 3758 } else {
3769 *pos = cgroup_pid_fry(of->cfe->css->cgroup, *p); 3759 *pos = cgroup_pid_fry(seq_css(s)->cgroup, *p);
3770 return p; 3760 return p;
3771 } 3761 }
3772} 3762}