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>
This commit is contained in:
parent
a742c59de6
commit
896f519963
@ -2295,42 +2295,6 @@ out_free:
|
||||
return ret ?: nbytes;
|
||||
}
|
||||
|
||||
static ssize_t cgroup_read_u64(struct cgroup_subsys_state *css,
|
||||
struct cftype *cft, struct file *file,
|
||||
char __user *buf, size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
char tmp[CGROUP_LOCAL_BUFFER_SIZE];
|
||||
u64 val = cft->read_u64(css, cft);
|
||||
int len = sprintf(tmp, "%llu\n", (unsigned long long) val);
|
||||
|
||||
return simple_read_from_buffer(buf, nbytes, ppos, tmp, len);
|
||||
}
|
||||
|
||||
static ssize_t cgroup_read_s64(struct cgroup_subsys_state *css,
|
||||
struct cftype *cft, struct file *file,
|
||||
char __user *buf, size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
char tmp[CGROUP_LOCAL_BUFFER_SIZE];
|
||||
s64 val = cft->read_s64(css, cft);
|
||||
int len = sprintf(tmp, "%lld\n", (long long) val);
|
||||
|
||||
return simple_read_from_buffer(buf, nbytes, ppos, tmp, len);
|
||||
}
|
||||
|
||||
static ssize_t cgroup_file_read(struct file *file, char __user *buf,
|
||||
size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
struct cfent *cfe = __d_cfe(file->f_dentry);
|
||||
struct cftype *cft = __d_cft(file->f_dentry);
|
||||
struct cgroup_subsys_state *css = cfe->css;
|
||||
|
||||
if (cft->read_u64)
|
||||
return cgroup_read_u64(css, cft, file, buf, nbytes, ppos);
|
||||
if (cft->read_s64)
|
||||
return cgroup_read_s64(css, cft, file, buf, nbytes, ppos);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* seqfile ops/methods for returning structured data. Currently just
|
||||
* 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)
|
||||
struct cftype *cft = cfe->type;
|
||||
struct cgroup_subsys_state *css = cfe->css;
|
||||
|
||||
return cft->read_seq_string(css, cft, m);
|
||||
}
|
||||
if (cft->read_seq_string)
|
||||
return cft->read_seq_string(css, cft, m);
|
||||
|
||||
static const struct file_operations cgroup_seqfile_operations = {
|
||||
.read = seq_read,
|
||||
.write = cgroup_file_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = cgroup_file_release,
|
||||
};
|
||||
if (cft->read_u64)
|
||||
seq_printf(m, "%llu\n", cft->read_u64(css, cft));
|
||||
else if (cft->read_s64)
|
||||
seq_printf(m, "%lld\n", cft->read_s64(css, cft));
|
||||
else
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cgroup_file_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
@ -2387,12 +2353,10 @@ static int cgroup_file_open(struct inode *inode, struct file *file)
|
||||
WARN_ON_ONCE(cfe->css && cfe->css != css);
|
||||
cfe->css = css;
|
||||
|
||||
if (cft->read_seq_string) {
|
||||
file->f_op = &cgroup_seqfile_operations;
|
||||
err = single_open(file, cgroup_seqfile_show, cfe);
|
||||
} else if (cft->open) {
|
||||
if (cft->open)
|
||||
err = cft->open(inode, file);
|
||||
}
|
||||
else
|
||||
err = single_open(file, cgroup_seqfile_show, cfe);
|
||||
|
||||
if (css->ss && err)
|
||||
css_put(css);
|
||||
@ -2406,9 +2370,7 @@ static int cgroup_file_release(struct inode *inode, struct file *file)
|
||||
|
||||
if (css->ss)
|
||||
css_put(css);
|
||||
if (file->f_op == &cgroup_seqfile_operations)
|
||||
single_release(inode, file);
|
||||
return 0;
|
||||
return single_release(inode, file);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2519,7 +2481,7 @@ static ssize_t cgroup_listxattr(struct dentry *dentry, char *buf, size_t size)
|
||||
}
|
||||
|
||||
static const struct file_operations cgroup_file_operations = {
|
||||
.read = cgroup_file_read,
|
||||
.read = seq_read,
|
||||
.write = cgroup_file_write,
|
||||
.llseek = generic_file_llseek,
|
||||
.open = cgroup_file_open,
|
||||
|
Loading…
Reference in New Issue
Block a user