/*
Initialize Code
*/
Entry = Create_proc_entry (Cache_file_path, 0, NULL);
if (entry) {
Entry->proc_fops = &flashcache_cache_operations;
Entry->data = DMC;
}
Kfree (s);
/*
Destroying function code
*/
Remove_proc_entry (Cache_file_path,null);
Kfree (s);
Simple Way to 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,
};
Advantages and Disadvantages
The advantage of this method is simple, but after testing in a show function of the seq_printf will first output to the Seq_file buff, when the output data is too large, there is a buffer overflow error, resulting in cannotallocate memory error.
The complex way Seq_open
/*
Returns null if the current iteration position exceeds the bounds of the list
*/
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];
}
/*
If the current iteration position exceeds the bounds of the list, NULL is returned.
*/
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)
{
}
/*
If the function outputs less data, return to the next function to continue the iteration. When the show function produces a certain amount of output, the iteration enters into the start function. When one of the next or start functions returns NULL, the iteration stops
*/
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,
};
/*
Here set Seq_file's private,private as private member passed in the iteration
*/
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,
};
Reference documents