seq机制,常用在虚拟文件系统的文件读操作,seekable.
seeking是通过seq内部机制结合seq_file结构各成员实现的
用于将零散数据整合到一个buffer中,然后输出
例如,对某文件的 file_operations 设置如下:
-
static struct file_operations ct_file_ops = {
-
.owner = THIS_MODULE,
-
.open = ct_open,
-
.read = seq_read,
-
.llseek = seq_lseek,
-
.release = seq_release
-
};
-
-
static struct seq_operations ct_seq_ops = {
-
.start = ct_seq_start,
-
.next = ct_seq_next,
-
.stop = ct_seq_stop,
-
.show = ct_seq_show
-
};
其中,
-
static int ct_open(struct inode *inode, struct file *file)
-
{
-
return seq_open(file, &ct_seq_ops); //将file的private_data字段设置为ct_seq_ops,关联seq方法
-
};
seq_lseek设置seq_file结构的成员达到定位目的。
seq_release释放整个seq_file结构体。
seq_read根据seq_file结构体内的成员信息将buf缓冲区内容返回个用户空间。
然而,seq机制的核心就在于seq_read函数如何构建buf的内容:
-
struct seq_operations {
-
void * (*start) (struct seq_file *m, loff_t *pos);
-
void (*stop) (struct seq_file *m, void *v);
-
void * (*next) (struct seq_file *m, void *v, loff_t *pos);
-
int (*show) (struct seq_file *m, void *v);
-
};
seq_operations结构体的四个函数指针:
start: 返回将要写入buf的数据的地址 v,参数 pos 给将要写入buf的数据提供一个索引,如第几个数据要素要写入buf
show: 将 v 所指数据写入buf
next: 返回下一轮将要写入buf的数据地址 v,并修改外部数据索引 pos (通常递增)
stop:如果start中分配了内存,在这里释放
那么问题来了,show函数如何把数据写入buf?我是说利用seq机制提供的函数。使用如下函数:
-
int seq_escape(struct seq_file *, const char *, const char *);
-
int seq_putc(struct seq_file *m, char c);
-
int seq_puts(struct seq_file *m, const char *s);
-
int seq_write(struct seq_file *seq, const void *data, size_t len);
-
int seq_printf(struct seq_file *, const char *, ...);
-
int seq_path(struct seq_file *, const struct path *, const char *);
-
int seq_dentry(struct seq_file *, struct dentry *, const char *);
-
int seq_path_root(struct seq_file *m, const struct path *path, const struct path *root, const char *esc);
-
int seq_bitmap(struct seq_file *m, const unsigned long *bits, unsigned int nr_bits);
参考示例:
-
struct seq_file {
-
char *buf; //缓冲区
-
size_t size; //缓冲区总长度
-
size_t from; //从buf的from索引处开始,复制给用户空间
-
size_t count; //当前缓冲区中有效数据量
-
size_t pad_until;
-
loff_t index; //外部数据索引,辅助处理将要写入buf的数据
-
loff_t read_pos;
-
u64 version;
-
struct mutex lock;
-
const struct seq_operations *op;
-
int poll_event;
-
#ifdef CONFIG_USER_NS
-
struct user_namespace *user_ns;
-
#endif
-
void *private;
-
};
阅读(1594) | 评论(0) | 转发(0) |