seq_file的用法

/*

初始化代码

*/

entry = create_proc_entry(cache_file_path, 0, NULL);

if (entry) {

entry->proc_fops = &flashcache_cache_operations;

entry->data = dmc;

}

kfree(s);


/*

销毁函数代码

*/

remove_proc_entry(cache_file_path,NULL);

kfree(s);



简单的方式single_open

static int

flashcache_version_show(struct seq_file*seq, void *v)

{

seq_printf(seq, "FlashcacheVersion : %s\n", flashcache_sw_version);

#ifdef COMMIT_REV

seq_printf(seq, "git commit:%s\n", COMMIT_REV);

#endif

return 0;

}


static int

flashcache_version_open(struct inode*inode, struct file *file)

{

return single_open(file,&flashcache_version_show, PDE(inode)->data);

}


static struct file_operationsflashcache_version_operations = {

.open = flashcache_version_open,

.read = seq_read,

.llseek = seq_lseek,

.release = single_release,

};

优缺点:

这种方法的好处就在于简单,但是经过测试在一个show函数里的seq_printf会先输出到seq_filebuff里面,当输出数据过大的时候很出现缓冲区溢出的错误,导致cannotallocate memory的错误。


复杂的方式seq_open

/*

如果当前迭代位置超过了列表的边界,则返回NULL

*/

static void*flashcache_cache_start(struct seq_file *seq, loff_t *pos)

{

struct cache_c *dmc = seq->private;


if(*pos >= (dmc->num_sets *dmc->assoc)) {

return NULL;

}

return &dmc->cache[*pos];

}

/*

如果当前迭代位置超过了列表的边界,则返回NULL

*/

static void*flashcache_cache_next(struct seq_file *seq, void *v, loff_t *pos)

{

struct cache_c *dmc = seq->private;

(*pos)++;

if(*pos >= (dmc->num_sets *dmc->assoc)) {

return NULL;

}

return &dmc->cache[*pos];

}

static voidflashcache_cache_stop(struct seq_file *seq, void *v)

{

}

/*

如果该函数输出的数据较少,则返回到next函数中继续迭代。当show函数产生一定数量的输出之后,迭代进入到start函数中。当nextstart函数中有一个返回NULL,则迭代停止

*/

static int flashcache_cache_show(structseq_file *seq, void *v)

{

struct cacheblock *cache = (structcacheblock *)v;


if(cache->cache_state & VALID){

seq_printf(seq, "%llu ",(u_int64_t)cache->dbn);

}

return 0;

}


static struct seq_operationsflashcache_cache_seq_ops = {

.start = flashcache_cache_start,

.next = flashcache_cache_next,

.stop = flashcache_cache_stop,

.show = flashcache_cache_show,

};


/*

在这里设置seq_fileprivateprivate作为私有成员在迭代中传递

*/

static int

flashcache_cache_open(struct inode*inode, struct file *file)

{

struct seq_file *seq;

int ret;

ret = seq_open(file,&flashcache_cache_seq_ops);

if(ret) {

return ret;

}

seq = (struct seq_file*)file->private_data;

seq->private = PDE(inode)->data;


return 0;

}


static struct file_operationsflashcache_cache_operations = {

.open = flashcache_cache_open,

.read = seq_read,

.llseek = seq_lseek,

.release = seq_release,

};


参考文献


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值