From 77e7b21f117eecd04bb31257ee68dfc1f425a47e Mon Sep 17 00:00:00 2001 From: Minep Date: Thu, 28 Jul 2022 00:20:37 +0100 Subject: [PATCH] feat: readdir fix and demo --- lunaix-os/includes/lunaix/common.h | 2 +- lunaix-os/includes/lunaix/dirent.h | 4 +++- lunaix-os/kernel/asm/x86/syscall.S | 4 ++-- lunaix-os/kernel/demos/dir_read.c | 25 ++++++++++++++++++++++ lunaix-os/kernel/fs/twifs.c | 18 +++++++++++++--- lunaix-os/kernel/fs/vfs.c | 34 +++++++++++++++++++++++------- lunaix-os/kernel/proc0.c | 10 +++++++-- 7 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 lunaix-os/kernel/demos/dir_read.c diff --git a/lunaix-os/includes/lunaix/common.h b/lunaix-os/includes/lunaix/common.h index 7fdf0b3..d341daa 100644 --- a/lunaix-os/includes/lunaix/common.h +++ b/lunaix-os/includes/lunaix/common.h @@ -48,7 +48,7 @@ #define container_of(ptr, type, member) \ ({ \ const typeof(((type*)0)->member)* __mptr = (ptr); \ - (type*)((char*)__mptr - offsetof(type, member)); \ + (ptr) ? (type*)((char*)__mptr - offsetof(type, member)) : 0; \ }) #endif diff --git a/lunaix-os/includes/lunaix/dirent.h b/lunaix-os/includes/lunaix/dirent.h index 5fce397..faa56a6 100644 --- a/lunaix-os/includes/lunaix/dirent.h +++ b/lunaix-os/includes/lunaix/dirent.h @@ -1,12 +1,14 @@ #ifndef __LUNAIX_DIRENT_H #define __LUNAIX_DIRENT_H +#define DIRENT_NAME_MAX_LEN 256 + struct dirent { unsigned int d_type; unsigned int d_offset; unsigned int d_nlen; - char* d_name; + char d_name[DIRENT_NAME_MAX_LEN]; }; #endif /* __LUNAIX_DIRENT_H */ diff --git a/lunaix-os/kernel/asm/x86/syscall.S b/lunaix-os/kernel/asm/x86/syscall.S index ab9e79f..2816bae 100644 --- a/lunaix-os/kernel/asm/x86/syscall.S +++ b/lunaix-os/kernel/asm/x86/syscall.S @@ -28,8 +28,8 @@ .long __lxsys_sigsuspend .long __lxsys_open .long __lxsys_close - // .long __lxsys_read - // .long __lxsys_write + .long __lxsys_read + .long __lxsys_write .long __lxsys_readdir .long __lxsys_mkdir 2: diff --git a/lunaix-os/kernel/demos/dir_read.c b/lunaix-os/kernel/demos/dir_read.c new file mode 100644 index 0000000..8c4a344 --- /dev/null +++ b/lunaix-os/kernel/demos/dir_read.c @@ -0,0 +1,25 @@ +#include +#include +#include + +LOG_MODULE("RDDIR") + +void +_readdir_main() +{ + int fd = open("/bus/../..", 0); + if (fd == -1) { + kprintf(KERROR "fail to open\n"); + return; + } + + struct dirent ent = { .d_offset = 0 }; + + while (!readdir(fd, &ent)) { + kprintf(KINFO "%s\n", ent.d_name); + } + + close(fd); + + return; +} \ No newline at end of file diff --git a/lunaix-os/kernel/fs/twifs.c b/lunaix-os/kernel/fs/twifs.c index a024c32..a50a657 100644 --- a/lunaix-os/kernel/fs/twifs.c +++ b/lunaix-os/kernel/fs/twifs.c @@ -31,6 +31,9 @@ __twifs_get_node(struct twifs_node* parent, struct hstr* name); struct v_inode* __twifs_create_inode(struct twifs_node* twi_node); +int +__twifs_iterate_dir(struct v_file* file, struct dir_context* dctx); + int __twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point); @@ -94,6 +97,7 @@ twifs_dir_node(struct twifs_node* parent, const char* name, int name_len) { struct twifs_node* twi_node = __twifs_new_node(parent, name, name_len); twi_node->itype = VFS_INODE_TYPE_DIR; + twi_node->fops.readdir = __twifs_iterate_dir; struct v_inode* twi_inode = __twifs_create_inode(twi_node); struct twifs_node* dot = __twifs_new_node(twi_node, ".", 1); @@ -104,7 +108,7 @@ twifs_dir_node(struct twifs_node* parent, const char* name, int name_len) twi_node->inode = twi_inode; dot->inode = twi_inode; - ddot->inode = parent->inode; + ddot->inode = parent ? parent->inode : twi_inode; return twi_node; } @@ -119,6 +123,13 @@ int __twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point) { mount_point->inode = fs_root->inode; + // FIXME: try to mitigate this special case or pull it up to higher level of + // abstraction + if (mount_point->parent && mount_point->parent->inode) { + struct hstr ddot_name = HSTR("..", 2); + struct twifs_node* root_ddot = __twifs_get_node(fs_root, &ddot_name); + root_ddot->inode = mount_point->parent->inode; + } return 0; } @@ -181,11 +192,11 @@ __twifs_iterate_dir(struct v_file* file, struct dir_context* dctx) dctx->index = counter; dctx->read_complete_callback( dctx, pos->name.value, pos->name.len, pos->itype); - return 1; + return 0; } } - return 0; + return 1; } int @@ -193,6 +204,7 @@ __twifs_openfile(struct v_inode* inode, struct v_file* file) { struct twifs_node* twi_node = (struct twifs_node*)inode->data; if (twi_node) { + file->inode = twi_node->inode; file->ops = twi_node->fops; return 0; } diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index 902f21e..51ef5c9 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -80,6 +80,9 @@ __dcache_get_bucket(struct v_dnode* parent, unsigned int hash) struct v_dnode* vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str) { + if (!str->len) + return parent; + struct hbucket* slot = __dcache_get_bucket(parent, str->hash); struct v_dnode *pos, *n; @@ -109,7 +112,7 @@ vfs_walk(struct v_dnode* start, int errno = 0; int i = 0, j = 0; - if (path[0] == PATH_DELIM) { + if (path[0] == PATH_DELIM || !start) { if ((walk_options & VFS_WALK_FSRELATIVE) && start) { start = start->super_block->root; } else { @@ -146,6 +149,7 @@ vfs_walk(struct v_dnode* start, } name_content[j] = 0; + name.len = j; hstr_rehash(&name, HSTR_FULL_HASH); if (!lookahead && (walk_options & VFS_WALK_PARENT)) { @@ -381,11 +385,15 @@ __DEFINE_LXSYSCALL2(int, open, const char*, path, int, options) return -1; } + vfs_walk(dentry, name.value, &file, NULL, 0); + struct v_file* opened_file = 0; - if (!(file = vfs_dcache_lookup(dentry, &name)) && (options & FO_CREATE)) { - errno = dentry->inode->ops.create(dentry->inode, opened_file); - } else if (!file) { - errno = EEXIST; + if (!file) { + if ((options & FO_CREATE)) { + errno = dentry->inode->ops.create(dentry->inode, opened_file); + } else { + errno = ENOENT; + } } else { errno = vfs_open(file, &opened_file); } @@ -410,6 +418,7 @@ __DEFINE_LXSYSCALL1(int, close, int, fd) errno = EBADF; } else if (!(errno = vfs_close(fd_s->file))) { vfree(fd_s); + __current->fdtable->fds[fd] = 0; } __current->k_status = errno; @@ -424,7 +433,7 @@ __vfs_readdir_callback(struct dir_context* dctx, const int dtype) { struct dirent* dent = (struct dirent*)dctx->cb_data; - strcpy(dent->d_name, name); + strncpy(dent->d_name, name, DIRENT_NAME_MAX_LEN); dent->d_nlen = len; dent->d_type = dtype; } @@ -456,8 +465,7 @@ __DEFINE_LXSYSCALL1(int, mkdir, const char*, path) { struct v_dnode *parent, *dir; struct hstr component = HSTR(valloc(VFS_NAME_MAXLEN), 0); - int errno = - vfs_walk(root_sb->root, path, &parent, &component, VFS_WALK_PARENT); + int errno = vfs_walk(NULL, path, &parent, &component, VFS_WALK_PARENT); if (errno) { goto done; } @@ -480,4 +488,14 @@ __DEFINE_LXSYSCALL1(int, mkdir, const char*, path) done: __current->k_status = errno; return SYSCALL_ESTATUS(errno); +} + +__DEFINE_LXSYSCALL3(size_t, read, int, fd, void*, buf, size_t, count) +{ + // TODO +} + +__DEFINE_LXSYSCALL3(size_t, write, int, fd, void*, buf, size_t, count) +{ + // TODO } \ No newline at end of file diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index f2a8458..4cf0c82 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -40,8 +40,9 @@ unlock_reserved_memory(); void __do_reserved_memory(int unlock); -//#define USE_DEMO -#define DEMO_SIGNAL +#define USE_DEMO +// #define DEMO_SIGNAL +#define DEMO_READDIR extern void _pconsole_main(); @@ -52,6 +53,9 @@ _signal_demo_main(); extern void _lxinit_main(); +extern void +_readdir_main(); + void __USER__ __proc0_usr() { @@ -65,6 +69,8 @@ __proc0_usr() _exit(0); #elif defined DEMO_SIGNAL _signal_demo_main(); +#elif defined DEMO_READDIR + _readdir_main(); #else _lxinit_main(); #endif -- 2.27.0