#include #include #include #include #include #include #include #include #include #include #include struct dentry *voidfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data); static int voidfs_fill_super(struct super_block *sb, void *data, int silent); void voidfs_kill_superblock(struct super_block *sb); ssize_t voidfs_read(struct file *fp, char __user *buf, size_t len, loff_t *ppos); ssize_t voidfs_write(struct file *fp, const char __user *buf, size_t len, loff_t *ppos); struct file_system_type voidfs_fs_type = { .owner = THIS_MODULE, .name = "voidfs", .mount = voidfs_mount, .kill_sb = voidfs_kill_superblock, .fs_flags = FS_REQUIRES_DEV, }; struct super_operations voidfs_super_ops = { // null for now } struct super_operations voidfs_inode_ops = { // null for now } struct file_operations voidfs_dir_ops = { .iterate_shared = voidfs_readdir, } struct file_operations voidfs_file_ops = { .read = voidfs_read, .write = voidfs_write, } int voidfs_readdir(struct file *fp, struct dir_context *ctx) { // populate directory entry maybe struct inode *inode; struct super_block *sb; printk(KERN_INFO "readdir"); inode = file_inode(file); sb = inode->i_sb; // if (inode && // !dir_emit(ctx, f->filename, SIMPLEFS_FILENAME_LEN, f->inode, // DT_UNKNOWN)) // break; return 0; } ssize_t voidfs_read(struct file *fp, char __user *buf, size_t len, loff_t *ppos) { struct inode *inode; struct super_block *sb; inode = file_inode(file); if (!inode) { return -EFAULT; } sb = inode->i_sb; // we don't read from the block device for now // so return a dummy string char* buffer = "this is a voidfs file"; ssize_t nbytes = 21; // get file buffer // move the offset // get as much as we can if (copy_to_user(buf, buffer, nbytes)) { brelse(bh); printk(KERN_ERR "Error copying file content to userspace buffer\n"); return -EFAULT; } } ssize_t voidfs_write(struct file *fp, const char __user *buf, size_t len, loff_t *ppos) { } struct dentry *voidfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { printk(KERN_INFO "voidfs try to mount %s\n", dev_name); struct dentry *ret; ret = mount_bdev(fs_type, flags, dev_name, data, voidfs_fill_super); if (unlikely(IS_ERR(ret))) { printk(KERN_ERR "Error mounting voidfs.\n"); } else { printk(KERN_INFO "voidfs is succesfully mounted on: %s\n", dev_name); } return ret; } // initialize super block metadata static int voidfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root_inode; struct inode *dummy_body; sb->s_magic = 0x44445555; sb->s_op = &voidfs_super_ops; sb_set_blocksize(sb, 1 << 12 /* 4 kilobyte */); sb->s_maxbytes = (1 << 12) * 10; // we don't get a read on file for now, because we still have // to define the internal format // create a dummy root node that we can access root_inode = new_inode(sb); if (!root_inode) { return -ENOMEM; } inode_init_owner(root_inode, NULL, root_inode->i_mode); root_inode->i_sb = sb; root_inode->i_op = &voidfs_inode_ops; root_inode->i_atime = root_inode->i_mtime = root_inode->i_ctime = CURRENT_TIME; root_inode->i_fop = &voidfs_dir_ops; // create a dummy file entry point root_inode->i_fop = &voidfs_file_ops; sb->s_root = d_make_root(root_inode); return 0; } void voidfs_kill_superblock(struct super_block *sb) { printk(KERN_INFO "voidfs try to unmount\n"); } static int __init voidfs_init(void) { int ret; // hellofs_inode_cache = kmem_cache_create("hellofs_inode_cache", // sizeof(struct hellofs_inode), // 0, // (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), // NULL); // if (!hellofs_inode_cache) { // return -ENOMEM; // } ret = register_filesystem(&voidfs_fs_type); if (likely(0 == ret)) { printk(KERN_INFO "Sucessfully registered voidfs\n"); } else { printk(KERN_ERR "Failed to register voidfs. Error code: %d\n", ret); } return ret; } static void __exit voidfs_exit(void) { int ret; ret = unregister_filesystem(&voidfs_fs_type); // kmem_cache_destroy(voidfs_inode_cache); if (likely(ret == 0)) { printk(KERN_INFO "Sucessfully unregistered voidfs\n"); } else { printk(KERN_ERR "Failed to unregister voidfs. Error code: %d\n", ret); } } module_init(voidfs_init); module_exit(voidfs_exit); MODULE_LICENSE("MIT"); MODULE_AUTHOR("nganhkhoa");