diff options
author | Tejun Heo <tj@kernel.org> | 2013-12-05 12:28:04 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-12-05 12:28:04 -0500 |
commit | 896f5199631560202885715da1b2f018632084e5 (patch) | |
tree | d9528c21be24d588f8f943499e9e6ff83ef77187 | |
parent | a742c59de66ea080afa3edaf3428b3cdd5aa87cd (diff) |
cgroup: unify read path so that seq_file is always used
With the recent removal of cftype->read() and ->read_map(), only three
operations are remaining, ->read_u64(), ->read_s64() and
->read_seq_string(). Currently, the first two are handled directly
while the last is handled through seq_file.
It is trivial to serve the first two through the seq_file path too.
This patch restructures read path so that all operations are served
through cgroup_seqfile_show(). This makes all cgroup files seq_file -
single_open/release() are now used by default,
cgroup_seqfile_operations is dropped, and cgroup_file_operations uses
seq_read() for read.
This simplifies the code and makes the read path easy to convert to
use kernfs.
Note that, while cgroup_file_operations uses seq_read() for read, it
still uses generic_file_llseek() for seeking instead of seq_lseek().
This is different from cgroup_seqfile_operations but shouldn't break
anything and brings the seeking behavior aligned with kernfs.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
-rw-r--r-- | kernel/cgroup.c | 68 |
1 files changed, 15 insertions, 53 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index eb34caf98124..ce6db713bbd6 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -2295,42 +2295,6 @@ out_free: | |||
2295 | return ret ?: nbytes; | 2295 | return ret ?: nbytes; |
2296 | } | 2296 | } |
2297 | 2297 | ||
2298 | static ssize_t cgroup_read_u64(struct cgroup_subsys_state *css, | ||
2299 | struct cftype *cft, struct file *file, | ||
2300 | char __user *buf, size_t nbytes, loff_t *ppos) | ||
2301 | { | ||
2302 | char tmp[CGROUP_LOCAL_BUFFER_SIZE]; | ||
2303 | u64 val = cft->read_u64(css, cft); | ||
2304 | int len = sprintf(tmp, "%llu\n", (unsigned long long) val); | ||
2305 | |||
2306 | return simple_read_from_buffer(buf, nbytes, ppos, tmp, len); | ||
2307 | } | ||
2308 | |||
2309 | static ssize_t cgroup_read_s64(struct cgroup_subsys_state *css, | ||
2310 | struct cftype *cft, struct file *file, | ||
2311 | char __user *buf, size_t nbytes, loff_t *ppos) | ||
2312 | { | ||
2313 | char tmp[CGROUP_LOCAL_BUFFER_SIZE]; | ||
2314 | s64 val = cft->read_s64(css, cft); | ||
2315 | int len = sprintf(tmp, "%lld\n", (long long) val); | ||
2316 | |||
2317 | return simple_read_from_buffer(buf, nbytes, ppos, tmp, len); | ||
2318 | } | ||
2319 | |||
2320 | static ssize_t cgroup_file_read(struct file *file, char __user *buf, | ||
2321 | size_t nbytes, loff_t *ppos) | ||
2322 | { | ||
2323 | struct cfent *cfe = __d_cfe(file->f_dentry); | ||
2324 | struct cftype *cft = __d_cft(file->f_dentry); | ||
2325 | struct cgroup_subsys_state *css = cfe->css; | ||
2326 | |||
2327 | if (cft->read_u64) | ||
2328 | return cgroup_read_u64(css, cft, file, buf, nbytes, ppos); | ||
2329 | if (cft->read_s64) | ||
2330 | return cgroup_read_s64(css, cft, file, buf, nbytes, ppos); | ||
2331 | return -EINVAL; | ||
2332 | } | ||
2333 | |||
2334 | /* | 2298 | /* |
2335 | * seqfile ops/methods for returning structured data. Currently just | 2299 | * seqfile ops/methods for returning structured data. Currently just |
2336 | * supports string->u64 maps, but can be extended in future. | 2300 | * supports string->u64 maps, but can be extended in future. |
@@ -2342,15 +2306,17 @@ static int cgroup_seqfile_show(struct seq_file *m, void *arg) | |||
2342 | struct cftype *cft = cfe->type; | 2306 | struct cftype *cft = cfe->type; |
2343 | struct cgroup_subsys_state *css = cfe->css; | 2307 | struct cgroup_subsys_state *css = cfe->css; |
2344 | 2308 | ||
2345 | return cft->read_seq_string(css, cft, m); | 2309 | if (cft->read_seq_string) |
2346 | } | 2310 | return cft->read_seq_string(css, cft, m); |
2347 | 2311 | ||
2348 | static const struct file_operations cgroup_seqfile_operations = { | 2312 | if (cft->read_u64) |
2349 | .read = seq_read, | 2313 | seq_printf(m, "%llu\n", cft->read_u64(css, cft)); |
2350 | .write = cgroup_file_write, | 2314 | else if (cft->read_s64) |
2351 | .llseek = seq_lseek, | 2315 | seq_printf(m, "%lld\n", cft->read_s64(css, cft)); |
2352 | .release = cgroup_file_release, | 2316 | else |
2353 | }; | 2317 | return -EINVAL; |
2318 | return 0; | ||
2319 | } | ||
2354 | 2320 | ||
2355 | static int cgroup_file_open(struct inode *inode, struct file *file) | 2321 | static int cgroup_file_open(struct inode *inode, struct file *file) |
2356 | { | 2322 | { |
@@ -2387,12 +2353,10 @@ static int cgroup_file_open(struct inode *inode, struct file *file) | |||
2387 | WARN_ON_ONCE(cfe->css && cfe->css != css); | 2353 | WARN_ON_ONCE(cfe->css && cfe->css != css); |
2388 | cfe->css = css; | 2354 | cfe->css = css; |
2389 | 2355 | ||
2390 | if (cft->read_seq_string) { | 2356 | if (cft->open) |
2391 | file->f_op = &cgroup_seqfile_operations; | ||
2392 | err = single_open(file, cgroup_seqfile_show, cfe); | ||
2393 | } else if (cft->open) { | ||
2394 | err = cft->open(inode, file); | 2357 | err = cft->open(inode, file); |
2395 | } | 2358 | else |
2359 | err = single_open(file, cgroup_seqfile_show, cfe); | ||
2396 | 2360 | ||
2397 | if (css->ss && err) | 2361 | if (css->ss && err) |
2398 | css_put(css); | 2362 | css_put(css); |
@@ -2406,9 +2370,7 @@ static int cgroup_file_release(struct inode *inode, struct file *file) | |||
2406 | 2370 | ||
2407 | if (css->ss) | 2371 | if (css->ss) |
2408 | css_put(css); | 2372 | css_put(css); |
2409 | if (file->f_op == &cgroup_seqfile_operations) | 2373 | return single_release(inode, file); |
2410 | single_release(inode, file); | ||
2411 | return 0; | ||
2412 | } | 2374 | } |
2413 | 2375 | ||
2414 | /* | 2376 | /* |
@@ -2519,7 +2481,7 @@ static ssize_t cgroup_listxattr(struct dentry *dentry, char *buf, size_t size) | |||
2519 | } | 2481 | } |
2520 | 2482 | ||
2521 | static const struct file_operations cgroup_file_operations = { | 2483 | static const struct file_operations cgroup_file_operations = { |
2522 | .read = cgroup_file_read, | 2484 | .read = seq_read, |
2523 | .write = cgroup_file_write, | 2485 | .write = cgroup_file_write, |
2524 | .llseek = generic_file_llseek, | 2486 | .llseek = generic_file_llseek, |
2525 | .open = cgroup_file_open, | 2487 | .open = cgroup_file_open, |