/*
初始化代码
*/
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_file的buff里面,当输出数据过大的时候很出现缓冲区溢出的错误,导致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函数中。当next或start函数中有一个返回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_file的private,private作为私有成员在迭代中传递
*/
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,
};
参考文献