From e0bba9ee5fc89d51fc7b229bfed941ad3ab7133c Mon Sep 17 00:00:00 2001 From: acevest Date: Mon, 14 Oct 2024 21:28:09 +0800 Subject: [PATCH] =?utf8?q?=E5=AE=8C=E5=96=84sysc=5Fopen=20sysc=5Fread=20sy?= =?utf8?q?sc=5Fwrite?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- fs/file.c | 43 +++++++++++++++++++++++++++++++++++++++++++ fs/fs.c | 3 +++ fs/open.c | 33 +++++++++++++++++++++++++++++---- fs/ramfs.c | 2 +- fs/read.c | 4 +++- fs/vfs.h | 5 +++++ fs/write.c | 2 +- kernel/task_init.c | 18 +++++++++++++++--- 8 files changed, 100 insertions(+), 10 deletions(-) diff --git a/fs/file.c b/fs/file.c index dd03206..779a11d 100644 --- a/fs/file.c +++ b/fs/file.c @@ -117,3 +117,46 @@ void vfs_page_cache_init() { assert(page_hash_table != NULL); memset(page_hash_table, 0, PAGE_SIZE); } + +/// +#define MAX_FILES 1024 +static file_t g_files[MAX_FILES] = { + 0, +}; + +void init_file(file_t *fp) { + fp->f_dentry = NULL; + fp->f_flags = 0; + fp->f_ops = NULL; + fp->f_pos = 0; + + fp->f_state = 0; +} + +void init_files() { + for (int i = 0; i < MAX_FILES; i++) { + init_file(g_files + i); + } +} + +file_t *get_empty_filp() { + file_t *fp = NULL; + + for (int i = 0; i < MAX_FILES; i++) { + file_t *p = g_files + i; + if (p->f_state == 0) { + ENTER_CRITICAL_ZONE(EFLAGS); + + if (p->f_state == 0) { + p->f_state = 1; + fp = p; + EXIT_CRITICAL_ZONE(EFLAGS); + break; + } + + EXIT_CRITICAL_ZONE(EFLAGS); + } + } + + return fp; +} diff --git a/fs/fs.c b/fs/fs.c index 9125c99..b9bbe97 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -42,6 +42,9 @@ dentry_t rootfs_root_dentry; void setup_fs() { // ext2_setup_fs(); + void init_files(); + init_files(); + void vfs_page_cache_init(); vfs_page_cache_init(); diff --git a/fs/open.c b/fs/open.c index 86f9417..bf92c73 100644 --- a/fs/open.c +++ b/fs/open.c @@ -32,10 +32,30 @@ int get_unused_fd() { return -EMFILE; } -file_t *filp_open(const char *path, int flags, int mode) { +int filp_open(const char *path, int flags, int mode, file_t **fp) { int ret = 0; - return NULL; + assert(path != NULL); + + *fp = get_empty_filp(); + if (*fp == NULL) { + return -ENFILE; + } + + namei_t ni; + path_open_namei(path, flags, mode, &ni); + + (*fp)->f_dentry = ni.path.dentry; + (*fp)->f_flags = flags; + (*fp)->f_ops = (*fp)->f_dentry->d_inode->i_fops; + (*fp)->f_pos = 0; + + assert((*fp)->f_ops != NULL); + + // TODO: 添加open支持 + assert((*fp)->f_ops->open == NULL); + + return ret; } int sysc_open(const char *path, int flags, int mode) { @@ -47,9 +67,14 @@ int sysc_open(const char *path, int flags, int mode) { return fd; } - file_t *fp = filp_open(path, flags, mode); + file_t *fp; + + int ret = filp_open(path, flags, mode, &fp); + if (ret != 0) { + return ret; + } current->files.fds[fd] = fp; - return 0; + return fd; } diff --git a/fs/ramfs.c b/fs/ramfs.c index 557fa9b..d58471b 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -41,7 +41,7 @@ inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev); // } static const file_operations_t ramfs_file_operations = { - .read = 0, + .read = vfs_generic_file_read, .write = vfs_generic_file_write, }; diff --git a/fs/read.c b/fs/read.c index 6d3e071..4f7da19 100644 --- a/fs/read.c +++ b/fs/read.c @@ -61,7 +61,7 @@ ssize_t vfs_generic_file_read(file_t *file, char *buf, size_t size, loff_t *p_po void *addr = page2va(page); // printk("memcpy bytes %u index %u\n", bytes, index); // printk("read addr %x bytes %u index %u offset %u\n", addr, bytes, index, offset); - memcpy(buf, addr, bytes); + memcpy(buf, addr + offset, bytes); buf += bytes; offset += bytes; @@ -122,6 +122,8 @@ ssize_t sysc_read(int fd, void *buf, size_t count) { read = file->f_ops->read; loff_t pos = file->f_pos; + pos = 0; // TODO add sysc_seek + // printk("%s pos %lu\n", file->f_dentry->d_inline_name, pos); ret = read(file, buf, count, &pos); return ret; diff --git a/fs/vfs.h b/fs/vfs.h index 712820f..effc7c2 100644 --- a/fs/vfs.h +++ b/fs/vfs.h @@ -73,6 +73,8 @@ struct file { loff_t f_pos; uint32_t f_flags; + + int f_state; // 0 EMPTY 1 USED }; // super block @@ -323,3 +325,6 @@ int path_open_namei(const char *path, int flags, int mode, namei_t *ni); // ssize_t vfs_generic_file_read(file_t *file, char *buf, size_t size, loff_t *p_pos); ssize_t vfs_generic_file_write(file_t *file, const char *buf, size_t size, loff_t *p_pos); + +// file +file_t *get_empty_filp(); diff --git a/fs/write.c b/fs/write.c index d3e70f1..1271fce 100644 --- a/fs/write.c +++ b/fs/write.c @@ -68,7 +68,7 @@ ssize_t vfs_generic_file_write(file_t *file, const char *buf, size_t size, loff_ // ... // 写入page - memcpy(addr, buf + pos, bytes); + memcpy(addr + offset, buf + pos, bytes); // printk("write addr %x bytes %u index %u offset %u\n", addr, bytes, index, offset); // TODO diff --git a/kernel/task_init.c b/kernel/task_init.c index f5abc7d..1bc234e 100644 --- a/kernel/task_init.c +++ b/kernel/task_init.c @@ -241,12 +241,24 @@ void init_rootfs() { printk("\n"); { + // TODO支持带多层目录的fe_name + namei_t ni; const char *path = fe_name; const int flags = O_CREAT | O_APPEND; +#define bufsz 5223 + static char buf[bufsz] = {'b', 'u', 'f'}; +#if 1 + int sysc_open(const char *path, int flags, int mode); + int fd = sysc_open(path, flags, 0700); + assert(fd >= 0); - // TODO支持带多层目录的fe_name + ssize_t sysc_write(int fd, const char *buf, size_t size); + sysc_write(fd, fc, fe_filesz); + ssize_t sysc_read(int fd, void *buf, size_t count); + sysc_read(fd, buf, bufsz); +#else path_open_namei(path, flags, S_IFREG, &ni); file_t file; @@ -259,9 +271,9 @@ void init_rootfs() { vfs_generic_file_write(&file, fc, fe_filesz, &file.f_pos); file.f_pos = 0; -#define bufsz 5223 - static char buf[bufsz] = {'b', 'u', 'f'}; + vfs_generic_file_read(&file, buf, bufsz, &file.f_pos); +#endif for (int i = 0; i < bufsz; i++) { printk("%c", buf[i]); } -- 2.44.0