The simplest Virtual File System Code in linux-VFS

Source: Internet
Author: User
Linux implements the simplest Virtual File System Code-VFS-general Linux technology-Linux programming and kernel information. The following is a detailed description.
CODE: This is the "lwnfs" module source which goes along with this article on virtual filesystems from the Porting Drivers to 2.6 series.

/*
* Demonstrate a trivial filesystem using libfs.
*
* Copyright 2002,200 3 Jonathan Corbet
* This file may be redistributed under the terms of the gnu gpl.
*
* Chances are that this code will crash your system, delete your
* Nethack high scores, and set your disk drives on fire. You have
* Been warned.
*/
# Include
# Include
# Include
# Include /* PAGE_CACHE_SIZE */
# Include /* This is where libfs stuff is declared */
# Include
# Include/* copy_to_user */

/*
* Boilerplate stuff.
*/
MODULE_LICENSE ("GPL ");
MODULE_AUTHOR ("Jonathan Corbet ");

# Define LFS_MAGIC 0x19980122


/*
* Anytime we make a file or directory in our filesystem we need
* Come up with an inode to represent it internally. This is
* The function that does that job. All that's really interesting
* Is the "mode" parameter, which says whether this is a directory
* Or file, and gives the permissions.
*/
Static struct inode * lfs_make_inode (struct super_block * sb, int mode)
{
Struct inode * ret = new_inode (sb );

If (ret ){
Ret-> I _mode = mode;
Ret-> I _uid = ret-> I _gid = 0;
Ret-> I _blksize = PAGE_CACHE_SIZE;
Ret-> I _blocks = 0;
Ret-> I _atime = ret-> I _mtime = ret-> I _ctime = CURRENT_TIME;
}
Return ret;
}


/*
* The operations on our "files ".
*/

/*
* Open a file. All we have to do here is to copy over
* Copy of the counter pointer so it's easier to get.
*/
Static int lfs_open (struct inode * inode, struct file * filp)
{
Filp-> private_data = inode-> u. generic_ip;
Return 0;
}

# Define TMPSIZE 20
/*
* Read a file. Here we increment and read the counter, then pass it
* Back to the caller. The increment only happens if the read is done
* At the beginning of the file (offset = 0); otherwise we end up counting
* By twos.
*/
Static ssize_t lfs_read_file (struct file * filp, char * buf,
Size_t count, loff_t * offset)
{
Atomic_t * counter = (atomic_t *) filp-> private_data;
Int v, len;
Char tmp [TMPSIZE];
/*
* Encode the value, and figure out how much of it we can pass back.
*/
V = atomic_read (counter );
If (* offset> 0)
V-= 1;/* the value returned when offset was zero */
Else
Atomic_inc (counter );
Len = snprintf (tmp, TMPSIZE, "% d \ n", v );
If (* offset> len)
Return 0;
If (count> len-* offset)
Count = len-* offset;
/*
* Copy it back, increment the offset, and we're done.
*/
If (copy_to_user (buf, tmp + * offset, count ))
Return-EFAULT;
* Offset + = count;
Return count;
}

/*
* Write a file.
*/
Static ssize_t lfs_write_file (struct file * filp, const char * buf,
Size_t count, loff_t * offset)
{
Atomic_t * counter = (atomic_t *) filp-> private_data;
Char tmp [TMPSIZE];
/*
* Only write from the beginning.
*/
If (* offset! = 0)
Return-EINVAL;
/*
* Read the value from the user.
*/
If (count> = TMPSIZE)
Return-EINVAL;
Memset (tmp, 0, TMPSIZE );
If (copy_from_user (tmp, buf, count ))
Return-EFAULT;
/*
* Store it in the counter and we are done.
*/
Atomic_set (counter, simple_strtol (tmp, NULL, 10 ));
Return count;
}


/*
* Now we can put together our file operations structure.
*/
Static struct file_operations lfs_file_ops = {
. Open = lfs_open,
. Read = lfs_read_file,
. Write = lfs_write_file,
};


/*
* Create a file mapping a name to a counter.
*/
Static struct dentry * lfs_create_file (struct super_block * sb,
Struct dentry * dir, const char * name,
Atomic_t * counter)
{
Struct dentry * dentry;
Struct inode * inode;
Struct qstr qname;
/*
* Make a hashed version of the name to go with the dentry.
*/
Qname. name = name;
Qname. len = strlen (name );
Qname. hash = full_name_hash (name, qname. len );
/*
* Now we can create our dentry and the inode to go with it.
*/
Dentry = d_alloc (dir, & qname );
If (! Dentry)
Goto out;
Inode = lfs_make_inode (sb, S_IFREG | 0644 );
If (! Inode)
Goto out_dput;
Inode-> I _fop = & lfs_file_ops;
Inode-> u. generic_ip = counter;
/*
* Put it all into the dentry cache and we're all done.
*/
D_add (dentry, inode );
Return dentry;
/*
* Then again, maybe it didn't work.
*/
Out_dput:
Dput (dentry );
Out:
Return 0;
}


/*
* Create a directory which can be used to hold files. This code is
* Almost identical to the "create file" logic, doesn't that we create
* The inode with a different mode, and use the libfs "simple" operations.
*/
Static struct dentry * lfs_create_dir (struct super_block * sb,
Struct dentry * parent, const char * name)
{
Struct dentry * dentry;
Struct inode * inode;
Struct qstr qname;

Qname. name = name;
Qname. len = strlen (name );
Qname. hash = full_name_hash (name, qname. len );
Dentry = d_alloc (parent, & qname );
If (! Dentry)
Goto out;

Inode = lfs_make_inode (sb, S_IFDIR | 0644 );
If (! Inode)
Goto out_dput;
Inode-> I _op = & simple_dir_inode_operations;
Inode-> I _fop = & simple_dir_operations;

D_add (dentry, inode );
Return dentry;

Out_dput:
Dput (dentry );
Out:
Return 0;
}



/*
* OK, create the files that we export.
*/
Static atomic_t counter, subcounter;

Static void lfs_create_files (struct super_block * sb, struct dentry * root)
{
Struct dentry * subdir;
/*
* One counter in the top-level directory.
*/
Atomic_set (& counter, 0 );
Lfs_create_file (sb, root, "counter", & counter );
/*
* And one in a subdirectory.
*/
Atomic_set (& subcounter, 0 );
Subdir = lfs_create_dir (sb, root, "subdir ");
If (subdir)
Lfs_create_file (sb, subdir, "subcounter", & subcounter );
}



/*
* Superblock stuff. This is all boilerplate to give the vfs something
* That looks like a filesystem to work.
*/

/*
* Our superblock operations, both of which are generic kernel ops
* That we don't have to write ourselves.
*/
Static struct super_operations lfs_s_ops = {
. Statfs = simple_statfs,
. Drop_inode = generic_delete_inode,
};

/*
* "Fill" a superblock with mundane stuff.
*/
Static int lfs_fill_super (struct super_block * sb, void * data, int silent)
{
Struct inode * root;
Struct dentry * root_dentry;
/*
* Basic parameters.
*/
Sb-> s_blocksize = PAGE_CACHE_SIZE;
Sb-> s_blocksize_bits = PAGE_CACHE_SHIFT;
Sb-> s_magic = LFS_MAGIC;
Sb-> s_op = & lfs_ops;
/*
* We need to conjure up an inode to represent the root directory
* Of this filesystem. Its operations all come from libfs, so we
* Don't have to mess with actually * doing * things inside this
* Directory.
*/
Root = lfs_make_inode (sb, S_IFDIR | 0755 );
If (! Root)
Goto out;
Root-> I _op = & simple_dir_inode_operations;
Root-> I _fop = & simple_dir_operations;
/*
* Get a dentry to represent the directory in core.
*/
Root_dentry = d_alloc_root (root );
If (! Root_dentry)
Goto out_iput;
Sb-> s_root = root_dentry;
/*
* Make up the files which will be in this filesystem, and we're re done.
*/
Lfs_create_files (sb, root_dentry );
Return 0;

Out_iput:
Iput (root );
Out:
Return-ENOMEM;
}


/*
* Stuff to pass in when registering the filesystem.
*/
Static struct super_block * lfs_get_super (struct file_system_type * fst,
Int flags, const char * devname, void * data)
{
Return get_sb_single (fst, flags, data, lfs_fill_super );
}

Static struct file_system_type lfs_type = {
. Owner = THIS_MODULE,
. Name = "lwnfs ",
. Get_sb = lfs_get_super,
. Kill_sb = kill_litter_super,
};




/*
* Get things set up.
*/
Static int _ init lfs_init (void)
{
Return register_filesystem (& lfs_type );
}

Static void _ exit lfs_exit (void)
{
Unregister_filesystem (& lfs_type );
}

Module_init (lfs_init );
Module_exit (lfs_exit );
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.