From 88cedd61afd1fad1d5c0f40b1ea19fbd7975d99d Mon Sep 17 00:00:00 2001 From: acevest Date: Wed, 2 Oct 2024 00:25:52 +0800 Subject: [PATCH] ... --- fs/fslib.c | 14 -------------- fs/inode.c | 4 ++++ fs/path.c | 17 +++++++++++++---- fs/ramfs.c | 12 ++++++++++++ fs/vfs.h | 15 +++++++++------ fs/write.c | 38 +++++++++++++++++++++++++++++++++++--- kernel/task_init.c | 23 ++++++++++++++++++++--- 7 files changed, 93 insertions(+), 30 deletions(-) delete mode 100644 fs/fslib.c diff --git a/fs/fslib.c b/fs/fslib.c deleted file mode 100644 index 3b149c9..0000000 --- a/fs/fslib.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * ------------------------------------------------------------------------ - * File Name: fslib.c - * Author: Zhao Yanbai - * 2024-08-31 21:12:58 Saturday CST - * Description: none - * ------------------------------------------------------------------------ - */ - -#include "fs.h" - -const file_operations_t simple_dir_operations = { - -}; diff --git a/fs/inode.c b/fs/inode.c index 26fd847..080bd54 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -38,6 +38,10 @@ inode_t *alloc_inode(superblock_t *sb) { inode->i_fops = &empty_fops; inode->i_ops = &empty_iops; inode->i_size = 0; + inode->i_mapping = &inode->i_as; + inode->i_mapping->a_inode = inode; + inode->i_mapping->pages; + INIT_LIST_HEAD(&inode->i_mapping->pages); return inode; } diff --git a/fs/path.c b/fs/path.c index 48d2caa..48a3f43 100644 --- a/fs/path.c +++ b/fs/path.c @@ -413,9 +413,8 @@ int path_open_namei(const char *path, int flags, int mode, namei_t *ni) { goto end; } + assert(dentry != NULL); if (NULL == dentry->d_inode) { - // vfs_create(); - ret = vfs_create(dir->d_inode, dentry, mode, ni); up(&dir->d_inode->i_sem); @@ -428,18 +427,28 @@ int path_open_namei(const char *path, int flags, int mode, namei_t *ni) { // 上述是文件不存在的逻辑 // 此处是文件存在的情况下的处理逻辑 + up(&dir->d_inode->i_sem); if ((flags & O_EXCL) == 0) { - panic("unsupport O_EXCL") + panic("unsupport O_EXCL"); } ok: inode = dentry->d_inode; if (NULL == inode) { - ret = -ENOENT; + ret = ENOENT; goto end; } + if (S_ISDIR(inode->i_mode)) { + ret = EISDIR; + goto end; + } + + if ((flags & O_TRUNC) == 0) { + panic("unsupport O_TRUNC"); + } + end: return ret; diff --git a/fs/ramfs.c b/fs/ramfs.c index ef1ca11..8b65d3c 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -53,6 +53,11 @@ static const file_operations_t ramfs_dir_operations = { }; +static const address_space_operations_t ramfs_address_space_operations = { + .read_page = 0, + .write_page = 0, +}; + static int ramfs_mknod(inode_t *dir, dentry_t *dentry, umode_t mode) { int ret = 0; @@ -93,6 +98,11 @@ static const inode_operations_t ramfs_dir_inode_operations = { .mkdir = ramfs_mkdir, }; +void ramfs_debug_set_f_ops(file_t *filp) { + // + filp->f_ops = &ramfs_file_operations; +} + inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev) { inode_t *inode = alloc_inode(sb); @@ -107,11 +117,13 @@ inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev) { // panic("S_IFREG: not implement"); inode->i_fops = &ramfs_file_operations; inode->i_ops = &ramfs_file_inode_operations; + inode->i_mapping->a_ops = &ramfs_address_space_operations; break; case S_IFDIR: // panic("S_IFDIR: not implement"); inode->i_fops = &ramfs_dir_operations; inode->i_ops = &ramfs_dir_inode_operations; + inode->i_mapping->a_ops = NULL; break; case S_IFLNK: panic("S_IFLNK: not implement"); diff --git a/fs/vfs.h b/fs/vfs.h index d215530..5c82eb3 100644 --- a/fs/vfs.h +++ b/fs/vfs.h @@ -69,7 +69,7 @@ typedef struct file_operations { struct file { // 多个打开的文件可能是同一个文件 dentry_t *f_dentry; - file_operations_t *f_ops; + const file_operations_t *f_ops; loff_t f_pos; uint32_t f_flags; @@ -102,7 +102,7 @@ struct address_space { list_head_t pages; uint32_t total_pages; inode_t *a_inode; - address_space_operations_t *a_ops; + const address_space_operations_t *a_ops; }; // dentry和inode为什么不合二为一? @@ -136,7 +136,8 @@ struct inode { umode_t i_mode; // FILE DIR CHR BLK FIFO SOCK - address_space_t i_mapping; + address_space_t *i_mapping; + address_space_t i_as; }; // d_flags @@ -308,12 +309,14 @@ void dentry_get_locked(dentry_t *dentry); void dentry_put(dentry_t *dentry); -///// -extern const file_operations_t simple_dir_operations; - // bool path_init(const char *path, unsigned int flags, namei_t *ni); int path_walk(const char *path, namei_t *ni); int path_lookup_create(namei_t *ni, // dentry_t **dentry // OUT ); + +int path_open_namei(const char *path, int flags, int mode, namei_t *ni); + +// +ssize_t vfs_generic_file_write(file_t *file, const char *buf, size_t size, loff_t *p_pos); diff --git a/fs/write.c b/fs/write.c index 5ac4ca7..848c38d 100644 --- a/fs/write.c +++ b/fs/write.c @@ -18,7 +18,12 @@ #include #include #include +#include +#include #include + +page_t *get_cached_page(address_space_t *mapping, uint32_t index); + ssize_t vfs_generic_file_write(file_t *file, const char *buf, size_t size, loff_t *p_pos) { ssize_t ret = 0; @@ -28,21 +33,48 @@ ssize_t vfs_generic_file_write(file_t *file, const char *buf, size_t size, loff_ } assert(file->f_dentry->d_inode != NULL); + printk("FLAGS %08x\n", file->f_flags); assert((file->f_flags & O_APPEND) == O_APPEND); // 目前只支持这个 inode_t *inode = file->f_dentry->d_inode; + assert(inode != NULL); + + address_space_t *mapping = inode->i_mapping; + assert(mapping->a_inode == inode); + assert(mapping->a_ops != NULL); + assert(mapping->a_ops->read_page != NULL); + assert(mapping->a_ops->write_page != NULL); down(&inode->i_sem); while (size > 0) { - uint32_t index = pos >> PAGE_SHIFT; - uint32_t offset = pos & (PAGE_SIZE - 1); - uint32_t bytes = PAGE_SIZE - offset; + uint32_t index = pos >> PAGE_SHIFT; // 所在页号索引 + uint32_t offset = pos & (PAGE_SIZE - 1); // 所在页内偏移 + uint32_t bytes = PAGE_SIZE - offset; // 要在这一页写的字节数 if (size < bytes) { bytes = size; } + // 找出page + // 若找不出,则分配一个,并加到cache里 + page_t *page = get_cached_page(mapping, index); + assert(page != NULL); + assert(page->index == index); + assert(page->mapping == mapping); + + void *addr = page2va(page); + + // TODO + // ... + + // 写入page + memcpy(addr, buf, size); + + // TODO + // ... + // + size -= bytes; } end: diff --git a/kernel/task_init.c b/kernel/task_init.c index 4cab514..e8bfd01 100644 --- a/kernel/task_init.c +++ b/kernel/task_init.c @@ -140,13 +140,30 @@ void init_task_entry() { #if 1 extern __attribute__((regparm(0))) long sysc_mkdir(const char *path, int mode); sysc_mkdir("/root", 0777); - sysc_mkdir("/root/aaa", 0777); + sysc_mkdir("/root/sbin/", 0777); { namei_t ni; - const char *path = "/root"; - path_init(path, 0, &ni); + const char *path = "/root/sbin/init.elf"; + path_init(path, PATH_LOOKUP_PARENT, &ni); path_walk(path, &ni); + + printk("FLAGS %08x\n", ni.flags); + + path_open_namei(path, ni.flags, S_IFREG, &ni); + ni.flags = O_CREAT | O_APPEND; + printk("FLAGS %08x\n", ni.flags); + void ramfs_debug_set_f_ops(file_t * filp); + loff_t pos = 0; + file_t file; + file.f_dentry = ni.path.dentry; + file.f_flags = ni.flags; + printk("FLAGS %08x\n", ni.flags); + printk("FLAGS %08x\n", file.f_flags); + file.f_ops = 0; + file.f_pos = 0; + ramfs_debug_set_f_ops(&file); + vfs_generic_file_write(&file, "aaa", 3, &pos); } #endif -- 2.44.0