From 8106ee92deead3f0fd8fbc53ee09671aa40021ac Mon Sep 17 00:00:00 2001 From: acevest Date: Fri, 7 Jun 2024 23:10:10 +0800 Subject: [PATCH] vfs tmp code --- fs/dentry.c | 163 +++++++++++++++++++++++++++++++++++ fs/ext2.c | 19 ++-- fs/fs.c | 17 +++- fs/inode.c | 8 ++ fs/open.c | 38 +++++++- fs/path.c | 205 ++++++++++++++++++++++++++++++++++++++++++++ fs/ramfs.c | 40 +++++++++ fs/ramfs.h | 10 +++ fs/vfs.c | 32 +++++++ fs/vfs.h | 91 +++++++++++++++++--- include/fs.h | 26 ++++-- include/semaphore.h | 3 +- include/task.h | 15 ++++ include/types.h | 4 + kernel/irq.c | 2 + kernel/sched.c | 4 + kernel/semaphore.c | 2 + kernel/wait.c | 2 +- 18 files changed, 651 insertions(+), 30 deletions(-) create mode 100644 fs/dentry.c create mode 100644 fs/inode.c create mode 100644 fs/path.c create mode 100644 fs/ramfs.c create mode 100644 fs/ramfs.h diff --git a/fs/dentry.c b/fs/dentry.c new file mode 100644 index 0000000..ff51992 --- /dev/null +++ b/fs/dentry.c @@ -0,0 +1,163 @@ +/* + * ------------------------------------------------------------------------ + * File Name: dentry.c + * Author: Zhao Yanbai + * 2024-05-15 20:32:49 Wednesday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#include +#include +#include +#include +#include +#include +#define DENTRY_HASH_TABLE_SIZE 233 + +typedef struct { + list_head_t list; + mutex_t mutex; +} dentry_hash_entry_t; + +dentry_hash_entry_t dentry_hash_table[DENTRY_HASH_TABLE_SIZE] = { + 0, +}; + +uint32_t mod64(uint64_t x, uint32_t y) { + uint32_t mod; + + asm("div %3;" : "=d"(mod) : "a"((uint32_t)x), "d"((uint32_t)(x >> 32)), "r"(y) : "cc"); + + return mod; +} + +dentry_t *dentry_alloc(dentry_t *parent, qstr_t *s) { + dentry_t *dentry = NULL; + atomic_set(&dentry->d_count, 1); + panic("to do"); + return dentry; +} + +dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s) { + int index = mod64(s->hash, DENTRY_HASH_TABLE_SIZE); + assert(index < DENTRY_HASH_TABLE_SIZE); + + dentry_hash_entry_t *dhe = dentry_hash_table + index; + + dentry_t *dentry = NULL; + + mutex_lock(&dhe->mutex); + + list_head_t *p; + list_for_each(p, &dhe->list) { + dentry = list_entry(p, dentry_t, d_hash); + assert(dentry != NULL); + + if (dentry->d_name.hash != s->hash) { + continue; + } + + if (dentry->d_name.len != s->len) { + continue; + } + + if (dentry->d_parent != parent) { + continue; + } + + if (memcmp(dentry->d_name.name, s->name, s->len) != 0) { + continue; + } + + dentry_get_locked(dentry); + + break; + } + + mutex_unlock(&dhe->mutex); + + return dentry; +} +int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry) { + *dentry = NULL; + int ret = 0; + + down(&parent->d_inode->i_sem); + + // 在获得信号量后,需要再上cache中查找一遍 + // 因为这个过程中当前进程可能会睡眠,当被唤醒后,其它进程已经在内存准备好了 + *dentry = dentry_cached_lookup(parent, s); + + if (NULL != *dentry) { + up(&parent->d_inode->i_sem); + return ret; + } + + dentry_t *new_dentry = dentry_alloc(parent, s); + if (new_dentry == NULL) { + ret = -ENOMEM; + } else { + *dentry = parent->d_inode->i_ops->lookup(parent->d_inode, new_dentry); + + // 如果找到了,刚分配的,就不用了 + if (*dentry != NULL) { + dentry_put(new_dentry); + } + } + + up(&parent->d_inode->i_sem); + + return ret; +} + +kmem_cache_t *dentry_kmem_cache = NULL; + +void dentry_cache_init() { + kmem_cache_t *dentry_kmem_cache = kmem_cache_create("dentry_cache", sizeof(dentry_t), 4); + if (NULL == dentry_kmem_cache) { + panic("create dentry cache faild"); + } + + for (int i = 0; i < DENTRY_HASH_TABLE_SIZE; i++) { + dentry_hash_entry_t *dhe = dentry_hash_table + i; + list_init(&dhe->list); + mutex_init(&dhe->mutex); + } +} + +dentry_t *dentry_get(dentry_t *dentry) { + assert(dentry != NULL); + atomic_inc(&dentry->d_count); + return dentry; +} + +void dentry_get_locked(dentry_t *dentry) {} + +void dentry_put(dentry_t *dentry) { panic("todo"); } + +// static __inline__ struct dentry * dget(struct dentry *dentry) +// { +// if (dentry) { +// if (!atomic_read(&dentry->d_count)) +// BUG(); +// atomic_inc(&dentry->d_count); +// } +// return dentry; +// } + +// static inline struct dentry * __dget_locked(struct dentry *dentry) +// { +// atomic_inc(&dentry->d_count); +// if (atomic_read(&dentry->d_count) == 1) { +// dentry_stat.nr_unused--; +// list_del(&dentry->d_lru); +// INIT_LIST_HEAD(&dentry->d_lru); /* make "list_empty()" work */ +// } +// return dentry; +// } + +// struct dentry * dget_locked(struct dentry *dentry) +// { +// return __dget_locked(dentry); +// } diff --git a/fs/ext2.c b/fs/ext2.c index 36345ce..ffa6e1b 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -17,11 +17,14 @@ superblock_t *ext2_read_super(superblock_t *sb, void *data) { return sb; } fs_type_t ext2_fs_type = { - "ext2", - ext2_read_super, - 0, + .name = "ext2", + .read_super = ext2_read_super, + .next = 0, }; +void ext2_setup() { vfs_register_filesystem(&ext2_fs_type); } + +//-------------------------------------------------------------------------- struct { ext2_sb_t ext2_sb; ext2_gd_t *ext2_gd; @@ -30,9 +33,9 @@ struct { extern void blk_rw(dev_t dev, u64_t offset, u32_t scnt, char *buf); extern void kmem_cache_free(kmem_cache_t *cache, void *addr); -#define BLKRW(blkid, blkcnt, buf) \ - do { \ - blk_rw(system.root_dev, 1ULL * (blkid)*EXT2_BLOCK_SIZE, (blkcnt)*EXT2_BLOCK_SIZE, buf); \ +#define BLKRW(blkid, blkcnt, buf) \ + do { \ + blk_rw(system.root_dev, 1ULL * (blkid) * EXT2_BLOCK_SIZE, (blkcnt) * EXT2_BLOCK_SIZE, buf); \ } while (0) kmem_cache_t *ext2_block_cache; @@ -213,7 +216,9 @@ void ext2_setup_fs() { memset(&ext2_fs, 0, sizeof(ext2_fs)); char *buf = kmalloc(EXT2_BLOCK_SIZE, 0); - if (buf == 0) panic("out of memory"); + if (buf == 0) { + panic("out of memory"); + } BLKRW(1, 1, buf); // now blocksize == 1024, so blkid == 1 diff --git a/fs/fs.c b/fs/fs.c index 0088189..cde27a8 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -14,13 +14,26 @@ #include #include +// void ramfs_setup(); +// void ext2_setup(); + +// void setup_fs() { +// ramfs_setup(); + +// // ext2_setup(); +// } + +//-------------------------------------------------------------------------- + extern chrdev_t cnsl_chrdev; chrdev_t *chrdev[CHRDEV_SIZE] = {&cnsl_chrdev}; -void ext2_setup_fs(); +// void ext2_setup_fs(); unsigned int ext2_search_inpath(const char *path); -void setup_fs() { ext2_setup_fs(); } +// void setup_fs() { +// ext2_setup_fs(); +// } unsigned int namei(const char *path) { return ext2_search_inpath(path); } diff --git a/fs/inode.c b/fs/inode.c new file mode 100644 index 0000000..142839d --- /dev/null +++ b/fs/inode.c @@ -0,0 +1,8 @@ +/* + * ------------------------------------------------------------------------ + * File Name: inode.c + * Author: Zhao Yanbai + * 2024-05-15 20:32:55 Wednesday CST + * Description: none + * ------------------------------------------------------------------------ + */ diff --git a/fs/open.c b/fs/open.c index 46ff07e..54c57b3 100644 --- a/fs/open.c +++ b/fs/open.c @@ -18,4 +18,40 @@ #include #include -int sysc_open(const char *path, int flags, mode_t mode) { return 0; } +int get_unused_fd() { + int fd; + task_files_t *files = &(current->files); + + for (int i = 0; i < NR_TASK_OPEN_CNT; i++) { + if (files->fds[i] == 0) { + return i; + } + } + + printk("too many open files for %s\n", current->name); + return -EMFILE; +} + +file_t *filp_open(const char *path, int flags, mode_t mode) { + int ret = 0; + + // ret = open_path(path, flags, mode, nd); + + return NULL; +} + +int sysc_open(const char *path, int flags, mode_t mode) { + int fd = 0; + + fd = get_unused_fd(); + + if (fd < 0) { + return fd; + } + + file_t *fp = filp_open(path, flags, mode); + + current->files.fds[fd] = fp; + + return 0; +} diff --git a/fs/path.c b/fs/path.c new file mode 100644 index 0000000..cae8e30 --- /dev/null +++ b/fs/path.c @@ -0,0 +1,205 @@ +/* + * ------------------------------------------------------------------------ + * File Name: path.c + * Author: Zhao Yanbai + * 2024-04-20 19:24:42 Saturday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#include +#include +#include +#include +#include + +bool path_init(const char *path, unsigned int flags, namei_t *ni) { + if (path == NULL) { + return false; + } + + if (*path == '/') { + ni->mnt = current->mnt_root; + ni->dentry = current->dentry_root; + } + + ni->mnt = current->mnt_pwd; + ni->dentry = current->dentry_pwd; + + return true; +} + +void follow_dotdot(namei_t *ni) { + while (1) { + dentry_t *dentry = NULL; + vfsmount_t *parent = NULL; + + // 如果当前目录已经是根目录 + if (ni->dentry == current->dentry_root) { + assert(ni->mnt == current->mnt_root); + // do nothing + return; + } + + // 如果当前目录不是挂载的根目录 + if (ni->dentry != ni->mnt->mnt_root) { + dentry = ni->dentry->d_parent; + ni->dentry = dentry; + return; + } + + // 当前目录是挂载的根目录,这就需要找到挂载点的上一层目录 + // 所以先找到挂载点的父挂载点vfsmount + parent = ni->mnt->mnt_parent; + + // 如果当前挂载点已经是最开始的挂载点vfsmount了 + if (ni->mnt == parent) { + return; + } + + // 如果当前挂载点有父挂载点 + // 就记录当前挂载点的dentry和它所在的挂载vfsmount + dentry = ni->mnt->mnt_point; + ni->dentry = dentry; + ni->mnt = parent; + + // 此时有两种情况 + // 1. dentry 是根目录,就需要继续往上找 + // 2. dentry 不是根目录,也需要再往上找一层dentry + + // 关于这个循环可能处理的情况举例如下: + + // case1 + // 以 /root/aa/.. 为例 代表的是 /root + // 如果 挂载一个目录到 /root/aa/ + // 这时 dentry 指向的是 aa + // 还需要再往上走一层 + + // case2 + // 假设 /mnt/a 挂载到 /mnt/b 后, /mnt/b 再挂载到 /mnt/c + // 分别产生vfsmnt_a vfsmnt_b + // 对于路径/mnt/c/..当读到c时,对于它的dentry,会最终读到a的dentry + // 对于.. + // 第一次循环 dentry为b的dentry,mnt为 vfsmnt_b + // 第二次循环 dentry为c的dentry, mnt为 vfsmnt_a + // 第三次循环,dentry为mnt的dentry,mnt为mnt_root + + // case3 + // 假设 /mnt/a 挂载到 /mnt/c 后, /mnt/b 再挂载到 /mnt/c + // 分别产生 vfsmnt_a vfsmnt_b + // 这两个vfsmnt都会挂载到dentry->d_vfsmnt链表上 + } +} + +uint64_t compute_qstr_hash(qstr_t *q) { + q->hash = 0; + for (int i = 0; i < q->len; i++) { + uint64_t x = (uint64_t)(q->name[i]); + q->hash = (x << 4) | (x >> (8 * sizeof(q->hash) - 4)); + } + + q->hash += q->hash >> (4 * sizeof(q->hash)); + + return q->hash; +} + +int follow_down(dentry_t **dentry, vfsmount_t **vfsmnt) { + assert(*dentry != NULL); + assert(*vfsmnt != NULL); + + list_head_t *pos; + list_for_each(pos, &((*dentry)->d_vfsmnt)) { + vfsmount_t *tmp_mnt = list_entry(pos, vfsmount_t, mnt_clash); + if (*vfsmnt == tmp_mnt->mnt_parent) { + *vfsmnt = vfsmnt_get(tmp_mnt); + vfsmnt_put(tmp_mnt->mnt_parent); + + dentry_put(*dentry); + *dentry = dentry_get(tmp_mnt->mnt_root); + } + } +} + +int path_walk(const char *path, namei_t *ni) { + dentry_t *dentry; + int ret = 0; + if (path == NULL) { + return -EINVAL; + } + + // 先跳过最开始的 '/' + while (*path == '/') { + path++; + } + + // 所有连续'/'之后立即就是'\0' + if (*path == 0) { + return 0; + } + + // 拿到当前目录的 inode + inode_t *inode = ni->dentry->d_inode; + + while (true) { + qstr_t this; + this.name = path; + + do { + path++; + } while (*path && (*path != '/')); + + this.len = path - this.name; + + // 看是不是路径的最后一个文件名 + if (*path == 0) { + // + } + + // 跳过所有连续的 '/' + while (*path == '/') { + path++; + } + + // 看是不是路径其实是以'/'结尾的 + if (*path == 0) { + // + } + + // 开始解析name(到这里这个name后跟着的所有的'/'都已经跳过了) + if (this.name[0] == '.') { + if (this.len == 1) { + // 目录无变化,继续下一轮解析 + continue; + } else if (this.len == 2 && this.name[1] == '.') { + follow_dotdot(ni); + inode = ni->dentry->d_inode; + continue; + } + } + + // + compute_qstr_hash(&this); + + // 根据该名字,先上dentry cache里找 + dentry = dentry_cached_lookup(ni->dentry, &this); + + // 如果找不到就上实际存储设备中去找 + if (NULL == dentry) { + ret = dentry_real_lookup(ni->dentry, &this, &dentry); + if (0 != ret) { + break; + } + } + + // 找到了,先看看它是不是一个挂载点 + while (!list_empty(&dentry->d_vfsmnt)) { + // 如果是一个挂载点,则更进一步 + + // 这种解决的是先将/a 挂载到 /b + // 再将/b挂载到/c + // 读/c时,直接读到/a的dentry + } + } + + return ret; +} diff --git a/fs/ramfs.c b/fs/ramfs.c new file mode 100644 index 0000000..e1caf28 --- /dev/null +++ b/fs/ramfs.c @@ -0,0 +1,40 @@ +/* + * ------------------------------------------------------------------------ + * File Name: ramfs.c + * Author: Zhao Yanbai + * 2024-04-13 23:43:49 Saturday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#include "ramfs.h" + +#include "fs.h" +#include "mm.h" +#include "string.h" +#include "system.h" +#include "vfs.h" + +superblock_t *ramfs_read_super(superblock_t *sb, void *data); +fs_type_t ramfs_type = { + .name = "ramfs", + .read_super = ramfs_read_super, + .next = 0, +}; + +typedef struct ramfs_superblock { + // +} ramfs_superblock_t; + +typedef struct ramfs_dentry { + // d + +} ramfs_dentry_t; + +typedef struct ramfs_inode { + // d +} ramfs_inode_t; + +void ramfs_init() { vfs_register_filesystem(&ramfs_type); } + +superblock_t *ramfs_read_super(superblock_t *sb, void *data) { return sb; } diff --git a/fs/ramfs.h b/fs/ramfs.h new file mode 100644 index 0000000..4fd1d9a --- /dev/null +++ b/fs/ramfs.h @@ -0,0 +1,10 @@ +/* + * ------------------------------------------------------------------------ + * File Name: ramfs.h + * Author: Zhao Yanbai + * 2024-04-13 23:43:53 Saturday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#pragma once diff --git a/fs/vfs.c b/fs/vfs.c index d1ab375..525dce5 100644 --- a/fs/vfs.c +++ b/fs/vfs.c @@ -8,6 +8,7 @@ */ #include +#include #include // 要访问一个文件就必需先访问一个目录,才能根据文件名从目录中找到该文件的目录项,进而找到其inode @@ -42,3 +43,34 @@ void vfs_register_filesystem(fs_type_t *fs) { add->next = fs; fs->next = 0; } + +fs_type_t *vfs_find_filesystem(const char *name) { + for (fs_type_t *fs = &file_systems; fs != 0; fs = fs->next) { + if (strcmp(fs->name, name) == 0) { + return fs; + } + } + + return NULL; +} + +void ramfs_init(); +void vfs_init() { + ramfs_init(); + fs_type_t *fs = vfs_find_filesystem("ramfs"); + if (NULL == fs) { + panic("no ramfs"); + } + + superblock_t *sb = fs->read_super(NULL, NULL); +} + +///////// +vfsmount_t *vfsmnt_get(vfsmount_t *m) { + panic("todo"); + return NULL; +} +void vfsmnt_put(vfsmount_t *m) { + // + panic("todo"); +} diff --git a/fs/vfs.h b/fs/vfs.h index af9dee5..7547428 100644 --- a/fs/vfs.h +++ b/fs/vfs.h @@ -9,7 +9,16 @@ #pragma once +#include #include +#include +#include + +typedef struct qstr { + const char *name; + unsigned int len; + uint64_t hash; +} qstr_t; typedef struct dentry dentry_t; @@ -20,9 +29,11 @@ typedef struct dentry_operations dentry_operations_t; // super block typedef struct superblock { - // + // 该超级起的根目录的 dentry dentry_t *sb_root; + // void *sb_private; + // sb_operations_t *sb_ops; } superblock_t; @@ -39,6 +50,8 @@ typedef struct inode { void *i_private; + semaphore_t i_sem; + // fops - file ops 的副本 file_operations_t *i_fops; @@ -47,10 +60,20 @@ typedef struct inode { // 缓存的pages list_head_t i_pages; + + dev_t i_dev; // inode存储在该设备上 + dev_t i_rdev; // inode所代表的设备号 + + loff_t i_size; } inode_t; +#define DENTRY_INLINE_NAME_LEN 16 struct dentry { - char *d_name; + // char *d_name; + qstr_t d_name; + char d_inline_name[DENTRY_INLINE_NAME_LEN]; + + atomic_t d_count; // dentry_t *d_parent; @@ -60,6 +83,8 @@ struct dentry { list_head_t d_child; list_head_t d_subdirs; + list_head_t d_hash; + // superblock_t *d_sb; @@ -67,6 +92,12 @@ struct dentry { // 但多个dentry可以指向同一个inode(不实现) inode_t *d_inode; + // 需要一个标记自己已经成为挂载点的标志? + // uint32_t d_flags; + // 也可以用一个指向vfsmount的指针,非0表示挂载? + // 貌似应该搞个链表,因为一个点可以重复挂N次,N个文件系统 + list_head_t d_vfsmnt; // 所有挂载到这个目录的挂载点 + // dentry_operations_t *d_ops; @@ -75,39 +106,77 @@ struct dentry { }; struct sb_operations { - // + // read_inode }; -struct file_operations { - // open - // close - // read - // write - // lseek - // ioctl -}; +// struct file_operations { +// // open +// // close +// // read +// // write +// // lseek +// // ioctl + +// }; struct inode_operations { // + dentry_t *(*lookup)(inode_t *i, dentry_t *d); }; struct dentry_operations { // // hash // compare + // d_release 关闭文件 + // d_delete 删除文件 + // }; // 每当将一个存储设备安装到现有文件系统中的某个节点时,内核就要为之建立一个vfsmount结构 // 这个结构中即包含着该设备的有关信息,也包含了安装点的信息 // 系统中的每个文件系统,包括根设备的根文件系统,都要经过安装 +// +// 在安装文件系统时内核主要做如下的事情 +// 创建一个vfsmount +// 为被安装的设备创建一个superblock,并由该设备对应的文件系统来设置这个superblock +// 为被安装的设备的根目录创建一个dentry +// 为被安装的设备的根目录创建一个inode,由sb->sb_ops->read_inode来实现 +// 将superblock与被安装设备根目录的dentry关联 +// 将vfsmount与被安装设备的根目录dentry关联 typedef struct vfsmount { + dentry_t *mnt_point; // 挂载点 dentry + dentry_t *mnt_root; // 设备根目录 dentry + superblock_t *mnt_sb; // 被安装的设备的superblock + struct vfsmount *mnt_parent; // 如果多个设备挂载到同一个目录,则每个vfsmount的parent都指向同一个vfsmount + // sb->sb_ops->read_inode得到被安装设备根目录的inode + + list_head_t mnt_list; // vfsmount 链表 + + list_head_t mnt_clash; + + // 先简单实现:不支持一个设备挂载多次,或一个目录被挂载多次 } vfsmount_t; typedef struct fs_type { const char *name; superblock_t *(*read_super)(superblock_t *, void *); struct fs_type *next; + list_head_t sbs; // 同属于这个文件系统的所有超级块链表 } fs_type_t; extern superblock_t *root_sb; void vfs_register_filesystem(fs_type_t *fs); + +///// + +dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s); +int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry); + +vfsmount_t *vfsmnt_get(vfsmount_t *m); +void vfsmnt_put(vfsmount_t *m); + +dentry_t *dentry_get(dentry_t *dentry); +void dentry_get_locked(dentry_t *dentry); + +void dentry_put(dentry_t *dentry); diff --git a/include/fs.h b/include/fs.h index 7750690..108e72a 100644 --- a/include/fs.h +++ b/include/fs.h @@ -15,6 +15,7 @@ #include #include +#include /* 分区表开始的位置 */ #define PARTS_POS 0x1BE @@ -32,10 +33,10 @@ #define DEV_MINOR_MASK ((1UL << DEV_MAJOR_BITS) - 1) #define MAKE_DEV(major, minor) ((major) << DEV_MAJOR_BITS | minor) -#define MAKE_DISK_DEV(drv_no, part_no) MAKE_DEV(DEV_MAJOR_DISK, (((drv_no)&0x03) << 8) | (((part_no)&0xFF) << 0)) +#define MAKE_DISK_DEV(drv_no, part_no) MAKE_DEV(DEV_MAJOR_DISK, (((drv_no) & 0x03) << 8) | (((part_no) & 0xFF) << 0)) #define DEV_MAJOR(dev) ((unsigned int)((dev) >> DEV_MAJOR_BITS)) -#define DEV_MINOR(dev) ((unsigned int)((dev)&DEV_MINOR_MASK)) +#define DEV_MINOR(dev) ((unsigned int)((dev) & DEV_MINOR_MASK)) // #define MAX_SUPT_FILE_SIZE (1) #define NR_FILES (1) @@ -53,8 +54,23 @@ enum { CHRDEV_CNSL, CHRDEV_SIZE }; extern chrdev_t *chrdev[]; -typedef struct { -} file_t; +typedef struct file file_t; + +typedef struct file_operations { + int (*open)(inode_t *, file_t *); + ssize_t (*read)(file_t *, char *, size_t, loff_t *); +} file_operations_t; + +struct file { + // 多个打开的文件可能是同一个文件 + dentry_t *f_dentry; + file_operations_t *f_ops; +}; + +typedef struct namei { + vfsmount_t *mnt; + dentry_t *dentry; +} namei_t; #if 0 #define NR_FILES (PAGE_SIZE / sizeof(File)) @@ -107,6 +123,4 @@ static inline pInode find_empty_inode() } #endif -typedef uint32_t dev_t; - #endif //_FS_H diff --git a/include/semaphore.h b/include/semaphore.h index 207341c..cd826de 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -9,9 +9,7 @@ #pragma once -#include #include -#include typedef struct semaphore { volatile unsigned int cnt; @@ -44,5 +42,6 @@ typedef semaphore_t mutex_t; (ptr)->cnt = 1; \ INIT_LIST_HEAD(&((ptr)->wait_list)); \ } while (0) +void mutex_init(mutex_t *); void mutex_lock(mutex_t *); void mutex_unlock(mutex_t *); diff --git a/include/task.h b/include/task.h index eebbf8d..f91562f 100644 --- a/include/task.h +++ b/include/task.h @@ -22,6 +22,7 @@ #include #include #include +#include // #include enum { @@ -40,6 +41,12 @@ enum { #define TASK_MAGIC 0xAABBCCDD11223344 +#define NR_TASK_OPEN_CNT 32 +typedef struct task_files { + // 暂时先不用bitmap,直接线性搜索 + file_t *fds[NR_TASK_OPEN_CNT]; +} task_files_t; + typedef union task_union { struct { uint32_t esp0; /* kernel stack */ @@ -68,6 +75,14 @@ typedef union task_union { char name[TASK_NAME_SIZE]; + task_files_t files; + + dentry_t *dentry_root; + dentry_t *dentry_pwd; + + vfsmount_t *mnt_root; + vfsmount_t *mnt_pwd; + list_head_t list; // 所有进程串成一个链表 list_head_t pend; // 某些条件串成一个链表 diff --git a/include/types.h b/include/types.h index 04a3aaa..62c2b65 100644 --- a/include/types.h +++ b/include/types.h @@ -50,6 +50,10 @@ typedef long int32_t; typedef unsigned long long uint64_t; typedef long long int64_t; +typedef uint64_t loff_t; + +typedef uint32_t dev_t; + typedef unsigned long pid_t; typedef unsigned long mode_t; diff --git a/kernel/irq.c b/kernel/irq.c index d688d15..61ad2c8 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -96,6 +96,8 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) { assert(reenter >= 0); assert(reenter <= 1); + // TODO 判断打断的是否是内核态代码 + // 屏蔽当前中断 p->chip->disable(irq); diff --git a/kernel/sched.c b/kernel/sched.c index cace86f..08a98e6 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -83,6 +83,10 @@ void init_root_task() { wrmsr(MSR_SYSENTER_ESP, root_task.esp0, 0); #endif + for (i = 0; i < NR_TASK_OPEN_CNT; i++) { + root_task.files.fds[i] = NULL; + } + printk("init_root_task tss.esp0 %08x\n", tss.esp0); } diff --git a/kernel/semaphore.c b/kernel/semaphore.c index 19b08b5..be4395f 100644 --- a/kernel/semaphore.c +++ b/kernel/semaphore.c @@ -9,6 +9,7 @@ #include #include #include +#include typedef struct semaphore_waiter { list_head_t list; @@ -74,5 +75,6 @@ volatile void up(semaphore_t *s) { irq_restore(iflags); } +void mutex_init(mutex_t *s) { INIT_MUTEX(s); } void mutex_lock(semaphore_t *s) { down(s); } void mutex_unlock(semaphore_t *s) { up(s); } diff --git a/kernel/wait.c b/kernel/wait.c index bb4fd0f..4009765 100644 --- a/kernel/wait.c +++ b/kernel/wait.c @@ -80,7 +80,7 @@ volatile void wait_on(wait_queue_head_t *head) { irq_save(flags); current->state = TASK_WAIT; - current->reason = "sleep_on"; + current->reason = "wait_on"; list_add_tail(&wait.entry, &head->task_list); -- 2.44.0