Chinaunix首页 | 论坛 | 博客
  • 博客访问: 24251
  • 博文数量: 5
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 45
  • 用 户 组: 普通用户
  • 注册时间: 2014-10-25 10:41
文章分类
文章存档

2015年(1)

2014年(4)

我的朋友

分类: LINUX

2014-11-12 22:25:41


seq机制,常用在虚拟文件系统的文件读操作,seekable.
seeking是通过seq内部机制结合seq_file结构各成员实现的
用于将零散数据整合到一个buffer中,然后输出

例如,对某文件的 file_operations 设置如下:


  1. static struct file_operations ct_file_ops = {
  2.  .owner = THIS_MODULE,
  3.  .open = ct_open,
  4.  .read = seq_read,
  5.  .llseek = seq_lseek,
  6.  .release = seq_release
  7. };

  8. static struct seq_operations ct_seq_ops = {
  9.  .start = ct_seq_start,
  10.  .next = ct_seq_next,
  11.  .stop = ct_seq_stop,
  12.  .show = ct_seq_show
  13. };


其中,

  1. static int ct_open(struct inode *inode, struct file *file)
  2. {
  3.     return seq_open(file, &ct_seq_ops); //将file的private_data字段设置为ct_seq_ops,关联seq方法
  4. };

seq_lseek设置seq_file结构的成员达到定位目的。
seq_release释放整个seq_file结构体。
seq_read根据seq_file结构体内的成员信息将buf缓冲区内容返回个用户空间。


 然而,seq机制的核心就在于seq_read函数如何构建buf的内容:

  1. struct seq_operations {
  2.   void * (*start) (struct seq_file *m, loff_t *pos);
  3.   void (*stop) (struct seq_file *m, void *v);
  4.   void * (*next) (struct seq_file *m, void *v, loff_t *pos);
  5.   int (*show) (struct seq_file *m, void *v);
  6.  };


 seq_operations结构体的四个函数指针:
  start: 返回将要写入buf的数据的地址 v,参数 pos 给将要写入buf的数据提供一个索引,如第几个数据要素要写入buf
  show: 将 v 所指数据写入buf
  next: 返回下一轮将要写入buf的数据地址 v,并修改外部数据索引 pos (通常递增)
  stop:如果start中分配了内存,在这里释放


那么问题来了,show函数如何把数据写入buf?我是说利用seq机制提供的函数。使用如下函数:

  1. int seq_escape(struct seq_file *, const char *, const char *);
  2. int seq_putc(struct seq_file *m, char c);
  3. int seq_puts(struct seq_file *m, const char *s);
  4. int seq_write(struct seq_file *seq, const void *data, size_t len);
  5. int seq_printf(struct seq_file *, const char *, ...);
  6. int seq_path(struct seq_file *, const struct path *, const char *);
  7. int seq_dentry(struct seq_file *, struct dentry *, const char *);
  8. int seq_path_root(struct seq_file *m, const struct path *path, const struct path *root, const char *esc);
  9. int seq_bitmap(struct seq_file *m, const unsigned long *bits, unsigned int nr_bits);


参考示例:


  1. struct seq_file {
  2.     char *buf; //缓冲区
  3.     size_t size; //缓冲区总长度
  4.     size_t from; //从buf的from索引处开始,复制给用户空间
  5.     size_t count; //当前缓冲区中有效数据量
  6.     size_t pad_until;
  7.     loff_t index; //外部数据索引,辅助处理将要写入buf的数据
  8.     loff_t read_pos;
  9.     u64 version;
  10.     struct mutex lock;
  11.     const struct seq_operations *op;
  12.     int poll_event;
  13. #ifdef CONFIG_USER_NS
  14.     struct user_namespace *user_ns;
  15. #endif
  16.     void *private;
  17. };

阅读(1594) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~