在 Linux 内核中可写 seq_file
Writable seq_file in Linux Kernel
我正在 运行 对 seq_file
进行一些实验,对此有些困惑。
我分析了seq_file.c and judging by seq_printf
implementation the internal char *buf
of the struct seq_file
is used entirely to store a formatted string to copy to a user in seq_read
. But there is seq_write
function defined in in seq_file.c中常用函数的实现,可以写入缓冲区。
问题: 是否可以重用 struct seq_file
的内部缓冲区并将其用于写入来自用户还是仅用于数据格式化?
我目前使用另一个缓冲区来写入数据,struct seq_file
仅用于数据格式化:
static char buf[4096];
static char *limit = buf;
void *pfsw_seq_start(struct seq_file *m, loff_t *pos){
if(*pos >= limit - buf) {
return NULL;
}
char *data = buf + *pos;
*pos = limit - buf;
return data;
}
void pfsw_seq_stop(struct seq_file *m, void *v){ }
void *pfsw_seq_next(struct seq_file *m, void *v, loff_t *pos){ return NULL; }
int pfsw_seq_show(struct seq_file *m, void *v){
seq_printf(m, "Data: %s\n", (char *) v);
return 0;
}
ssize_t pfsw_seq_write(struct file *filp, const char __user * user_data, size_t sz, loff_t *off){
if(*off < 0 || *off > sizeof buf){
return -EINVAL;
}
size_t space_left_from_off = sizeof buf - (size_t) *off;
size_t bytes_to_write = space_left_from_off <= sz ? space_left_from_off : sz;
if(copy_from_user(buf + *off, user_data, bytes_to_write)){
return -EAGAIN;
}
*off += bytes_to_write;
if(*off > limit - buf){
limit = buf + *off;
}
return bytes_to_write;
}
所以我定义struct file_operations
为
static const struct seq_operations seq_ops = {
.start = pfsw_seq_start,
.stop = pfsw_seq_stop,
.next = pfsw_seq_next,
.show = pfsw_seq_show
};
int pfsw_seq_open(struct inode *ino, struct file *filp){
return seq_open(filp, &seq_ops);
}
static const struct file_operations fops = {
.open = pfsw_seq_open,
.read = seq_read,
.write = pfsw_seq_write,
.release = seq_release,
};
您要找的帮手是simple_write_to_buffer。
给定缓冲区指针及其可用大小,帮助程序处理传递给 .write
函数的所有参数:
ssize_t pfsw_write(struct file *filp, const char __user * user_data, size_t sz, loff_t *off)
{
// This performs the most work.
ssize_t res = simple_write_to_buffer(buf, sizeof(buf), off, user_data, sz);
// Optionally, you may update the buffer's actual size.
// NOTE: In the simple form this doesn't work with **concurrent** writing.
if ((res > 0) && *off > buf_size) {
buf_size = *off;
}
return res;
}
simple_write_to_buffer
助手的 "pair" 是 simple_read_from_buffer
。该助手可用于 .read
方法的实现:
ssize_t pfsw_read(struct file filp*, char __user * user_data, size_t sz, loff_t *off)
{
// Here the helper does the whole work.
//
// 'buf_size' could be 'sizeof(buf)' in case of the buffer of the fixed size.
// Alternatively, you need to take care about concurrency;
// see the comments in the 'pfsw_write' function.
return simple_read_from_buffer(buf, buf_size, off, user_data, sz);
}
子系统seq_file
仅用于实现读取文件(.read
函数)。
虽然 seq_read
是 .read
函数的实际 实现 ,但 seq_write
只是一个 帮助程序 用于 struct seq_operations
中的 .show
函数。
有关 seq_file
和写入文件的相关问题,请参见 。
我正在 运行 对 seq_file
进行一些实验,对此有些困惑。
我分析了seq_file.c and judging by seq_printf
implementation the internal char *buf
of the struct seq_file
is used entirely to store a formatted string to copy to a user in seq_read
. But there is seq_write
function defined in in seq_file.c中常用函数的实现,可以写入缓冲区。
问题: 是否可以重用 struct seq_file
的内部缓冲区并将其用于写入来自用户还是仅用于数据格式化?
我目前使用另一个缓冲区来写入数据,struct seq_file
仅用于数据格式化:
static char buf[4096];
static char *limit = buf;
void *pfsw_seq_start(struct seq_file *m, loff_t *pos){
if(*pos >= limit - buf) {
return NULL;
}
char *data = buf + *pos;
*pos = limit - buf;
return data;
}
void pfsw_seq_stop(struct seq_file *m, void *v){ }
void *pfsw_seq_next(struct seq_file *m, void *v, loff_t *pos){ return NULL; }
int pfsw_seq_show(struct seq_file *m, void *v){
seq_printf(m, "Data: %s\n", (char *) v);
return 0;
}
ssize_t pfsw_seq_write(struct file *filp, const char __user * user_data, size_t sz, loff_t *off){
if(*off < 0 || *off > sizeof buf){
return -EINVAL;
}
size_t space_left_from_off = sizeof buf - (size_t) *off;
size_t bytes_to_write = space_left_from_off <= sz ? space_left_from_off : sz;
if(copy_from_user(buf + *off, user_data, bytes_to_write)){
return -EAGAIN;
}
*off += bytes_to_write;
if(*off > limit - buf){
limit = buf + *off;
}
return bytes_to_write;
}
所以我定义struct file_operations
为
static const struct seq_operations seq_ops = {
.start = pfsw_seq_start,
.stop = pfsw_seq_stop,
.next = pfsw_seq_next,
.show = pfsw_seq_show
};
int pfsw_seq_open(struct inode *ino, struct file *filp){
return seq_open(filp, &seq_ops);
}
static const struct file_operations fops = {
.open = pfsw_seq_open,
.read = seq_read,
.write = pfsw_seq_write,
.release = seq_release,
};
您要找的帮手是simple_write_to_buffer。
给定缓冲区指针及其可用大小,帮助程序处理传递给 .write
函数的所有参数:
ssize_t pfsw_write(struct file *filp, const char __user * user_data, size_t sz, loff_t *off)
{
// This performs the most work.
ssize_t res = simple_write_to_buffer(buf, sizeof(buf), off, user_data, sz);
// Optionally, you may update the buffer's actual size.
// NOTE: In the simple form this doesn't work with **concurrent** writing.
if ((res > 0) && *off > buf_size) {
buf_size = *off;
}
return res;
}
simple_write_to_buffer
助手的 "pair" 是 simple_read_from_buffer
。该助手可用于 .read
方法的实现:
ssize_t pfsw_read(struct file filp*, char __user * user_data, size_t sz, loff_t *off)
{
// Here the helper does the whole work.
//
// 'buf_size' could be 'sizeof(buf)' in case of the buffer of the fixed size.
// Alternatively, you need to take care about concurrency;
// see the comments in the 'pfsw_write' function.
return simple_read_from_buffer(buf, buf_size, off, user_data, sz);
}
子系统seq_file
仅用于实现读取文件(.read
函数)。
虽然 seq_read
是 .read
函数的实际 实现 ,但 seq_write
只是一个 帮助程序 用于 struct seq_operations
中的 .show
函数。
有关 seq_file
和写入文件的相关问题,请参见