From 9b6c3413490bfc9d530cd9380f37b6e96d816820 Mon Sep 17 00:00:00 2001 From: nganhkhoa Date: Tue, 29 Oct 2024 10:31:47 +0000 Subject: [PATCH] working vfs hardcoded structure - mount - list directory - read a file --- Makefile | 5 ++- voidfs.c | 102 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 75 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index 9e71f15..99915c0 100644 --- a/Makefile +++ b/Makefile @@ -3,4 +3,7 @@ obj-m += voidfs.o all: voidfs voidfs: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean diff --git a/voidfs.c b/voidfs.c index 05981d8..51a145c 100644 --- a/voidfs.c +++ b/voidfs.c @@ -17,6 +17,10 @@ static int voidfs_fill_super(struct super_block *sb, void *data, int silent); void voidfs_kill_superblock(struct super_block *sb); +struct dentry *voidfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int); +int voidfs_readdir(struct file *fp, struct dir_context *ctx); + +int voidfs_open(struct inode *inode, struct file *fp); 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); @@ -30,36 +34,70 @@ struct file_system_type voidfs_fs_type = { struct super_operations voidfs_super_ops = { // null for now -} +}; -struct super_operations voidfs_inode_ops = { - // null for now -} +struct inode_operations voidfs_inode_ops = { + .lookup = voidfs_lookup, +}; struct file_operations voidfs_dir_ops = { .iterate_shared = voidfs_readdir, -} +}; struct file_operations voidfs_file_ops = { + .open = voidfs_open, .read = voidfs_read, .write = voidfs_write, +}; + +struct dentry *voidfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int) { + struct inode* inode = NULL; + + printk(KERN_INFO "listing directory %s %s", dentry->d_parent->d_name.name, dentry->d_name.name); + printk(KERN_INFO " %p %p", dentry->d_inode, dir->i_sb); + + // parse an entry path + // right now, let's just create a dummy path + if (strcmp(dentry->d_name.name, "dummyfile") == 0) { + // inode->i_sb = sb; + inode = new_inode(dir->i_sb); + inode->i_op = &voidfs_inode_ops; + inode->i_fop = &voidfs_file_ops; + inode->i_mode = S_IFREG | 0644; + inode->i_ino = 3; + // inode->i_private = (void*)1; + } + + d_add(dentry, inode); + return NULL; } -int voidfs_readdir(struct file *fp, struct dir_context *ctx) { +int voidfs_readdir(struct file *dir, struct dir_context *ctx) { // populate directory entry maybe struct inode *inode; struct super_block *sb; printk(KERN_INFO "readdir"); - inode = file_inode(file); + if (ctx->pos > 3) { + return -ENOENT; + } + + inode = file_inode(dir); sb = inode->i_sb; - // if (inode && - // !dir_emit(ctx, f->filename, SIMPLEFS_FILENAME_LEN, f->inode, - // DT_UNKNOWN)) - // break; + dir_emit_dots(dir, ctx); + dir_emit(ctx, "dummydir", 8, 2, DT_DIR); + ctx->pos += 1; + dir_emit(ctx, "dummyfile", 9, 3, DT_REG); + ctx->pos += 1; + + return 0; +} + +int voidfs_open(struct inode *inode, struct file *fp) { + printk(KERN_INFO "voidfs open"); return 0; } @@ -67,7 +105,14 @@ 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); + printk(KERN_INFO "voidfs read"); + + // we only allow read 1 time, should be at the start + if (*ppos > 0) { + return 0; + } + + inode = file_inode(fp); if (!inode) { return -EFAULT; } @@ -83,14 +128,16 @@ ssize_t voidfs_read(struct file *fp, char __user *buf, size_t len, loff_t *ppos) // 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; } + *ppos += nbytes; + return nbytes; } ssize_t voidfs_write(struct file *fp, const char __user *buf, size_t len, loff_t *ppos) { + return 0; } struct dentry *voidfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { @@ -127,41 +174,34 @@ static int voidfs_fill_super(struct super_block *sb, void *data, int silent) { if (!root_inode) { return -ENOMEM; } - inode_init_owner(root_inode, NULL, root_inode->i_mode); + root_inode->i_mode = S_IFDIR | 0644; + inode_init_owner(&nop_mnt_idmap, 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); + // create a dummy file entry point + // root_inode->i_fop = &voidfs_file_ops; + + // create a child file + + return 0; } void voidfs_kill_superblock(struct super_block *sb) { printk(KERN_INFO "voidfs try to unmount\n"); + + kill_block_super(sb); } 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"); @@ -190,5 +230,5 @@ static void __exit voidfs_exit(void) module_init(voidfs_init); module_exit(voidfs_exit); -MODULE_LICENSE("MIT"); +MODULE_LICENSE("GPL"); MODULE_AUTHOR("nganhkhoa");