From 75dc577ebd46f04d02452d6892a85aa44ddc1add Mon Sep 17 00:00:00 2001 From: acevest Date: Sat, 31 Aug 2024 22:10:17 +0800 Subject: [PATCH] =?utf8?q?ramfs=E5=88=9D=E6=AD=A5=E4=BB=A3=E7=A0=81,vfs=20?= =?utf8?q?read=5Fsuper=20inode=20dentry=E7=9B=B8=E5=85=B3=E9=80=BB?= =?utf8?q?=E8=BE=91=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- fs/dentry.c | 57 +++++++++++++++++++++++-- fs/ext2.c | 4 +- fs/fs.c | 22 ++++++++-- fs/fslib.c | 14 ++++++ fs/inode.c | 52 +++++++++++++++++++++++ fs/mount.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++ fs/mount.h | 14 ++++++ fs/path.c | 28 ++++++------ fs/ramfs.c | 101 +++++++++++++++++++++++++++++++++++++++----- fs/super.c | 82 +++++++++++++++++++++++++++++++++++ fs/vfs.c | 17 ++++++-- fs/vfs.h | 65 ++++++++++++++++++++++------ include/fs.h | 11 +++++ include/mm.h | 1 + include/stat.h | 44 +++++++++++++------ include/system.h | 17 +++++++- include/types.h | 1 + mm/kmem.c | 17 ++++++++ 18 files changed, 589 insertions(+), 66 deletions(-) create mode 100644 fs/fslib.c create mode 100644 fs/mount.c create mode 100644 fs/mount.h create mode 100644 fs/super.c diff --git a/fs/dentry.c b/fs/dentry.c index ff51992..7d07a5e 100644 --- a/fs/dentry.c +++ b/fs/dentry.c @@ -15,6 +15,7 @@ #include #define DENTRY_HASH_TABLE_SIZE 233 +static kmem_cache_t *dentry_kmem_cache = NULL; typedef struct { list_head_t list; mutex_t mutex; @@ -32,10 +33,60 @@ uint32_t mod64(uint64_t x, uint32_t y) { return mod; } -dentry_t *dentry_alloc(dentry_t *parent, qstr_t *s) { +dentry_t *dentry_alloc(dentry_t *parent, const qstr_t *s) { dentry_t *dentry = NULL; + + assert(s != NULL); + assert(s->len > 0); + assert(s->len < DENTRY_INLINE_NAME_LEN - 1); + + dentry = kmem_cache_zalloc(dentry_kmem_cache, 0); + if (dentry == NULL) { + panic("no mem for dentry"); + return dentry; + } + + dentry->d_flags = 0; + + dentry->d_name.len = 0; + dentry->d_name.name = 0; + + memcpy(dentry->d_inline_name, s->name, s->len); + dentry->d_inline_name[s->len] = 0; + atomic_set(&dentry->d_count, 1); - panic("to do"); + + if (parent != NULL) { + dentry->d_parent = parent; + } else { + dentry->d_parent = dentry; + } + + INIT_LIST_HEAD(&dentry->d_child); + INIT_LIST_HEAD(&dentry->d_subdirs); + INIT_LIST_HEAD(&dentry->d_hash); + + dentry->d_sb = NULL; + dentry->d_inode = NULL; + dentry->d_ops = NULL; + dentry->d_private = NULL; + + return dentry; +} + +dentry_t *dentry_alloc_root(inode_t *root_inode) { + dentry_t *dentry; + + assert(root_inode != NULL); + + static const qstr_t name = {.name = "/", .len = 1, .hash = 0}; + dentry = dentry_alloc(NULL, &name); + if (dentry != NULL) { + dentry->d_sb = root_inode->i_sb; + dentry->d_parent = dentry; + } + dentry->d_inode = root_inode; + return dentry; } @@ -111,8 +162,6 @@ int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry) { 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) { diff --git a/fs/ext2.c b/fs/ext2.c index ffa6e1b..58f1f6f 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -14,11 +14,11 @@ #include "system.h" #include "vfs.h" -superblock_t *ext2_read_super(superblock_t *sb, void *data) { return sb; } +// superblock_t *ext2_read_super(superblock_t *sb, void *data) { return sb; } fs_type_t ext2_fs_type = { .name = "ext2", - .read_super = ext2_read_super, + // .read_super = ext2_read_super, .next = 0, }; diff --git a/fs/fs.c b/fs/fs.c index cde27a8..e7a13e2 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -11,6 +11,7 @@ */ #include #include +#include #include #include @@ -32,8 +33,21 @@ chrdev_t *chrdev[CHRDEV_SIZE] = {&cnsl_chrdev}; // void ext2_setup_fs(); unsigned int ext2_search_inpath(const char *path); -// void setup_fs() { -// ext2_setup_fs(); -// } - unsigned int namei(const char *path) { return ext2_search_inpath(path); } + +vfsmount_t rootfs_vfsmount; + +dentry_t rootfs_root_dentry; + +void setup_fs() { + // ext2_setup_fs(); + + void inode_cache_init(); + inode_cache_init(); + + void dentry_cache_init(); + dentry_cache_init(); + + void init_mount(); + init_mount(); +} diff --git a/fs/fslib.c b/fs/fslib.c new file mode 100644 index 0000000..3b149c9 --- /dev/null +++ b/fs/fslib.c @@ -0,0 +1,14 @@ +/* + * ------------------------------------------------------------------------ + * 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 142839d..c8a6bb9 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -6,3 +6,55 @@ * Description: none * ------------------------------------------------------------------------ */ + +#include "assert.h" +#include "fs.h" +#include "mm.h" +#include "printk.h" +#include "system.h" + +static kmem_cache_t *g_inode_kmem_cache = NULL; + +inode_t *alloc_inode(superblock_t *sb) { + inode_t *inode = 0; + + assert(NULL != sb->sb_ops); + // assert(NULL != sb->sb_ops->alloc_inode); + + if (NULL != sb->sb_ops->alloc_inode) { + inode = sb->sb_ops->alloc_inode(sb); + } else { + inode = kmem_cache_alloc(g_inode_kmem_cache, 0); + } + + if (0 == inode) { + printk("alloc inode fail"); + } + + static file_operations_t empty_fops; + static inode_operations_t empty_iops; + inode->i_sb = sb; + // inode->i_sem; + inode->i_fops = &empty_fops; + inode->i_ops = &empty_iops; + inode->i_size = 0; + return inode; +} + +void init_special_inode(inode_t *inode, umode_t mode, dev_t rdev) { + inode->i_mode = mode; + if (S_ISCHR(mode)) { + panic("todo"); + } else if (S_ISBLK(mode)) { + panic("todo"); + } else { + panic("todo"); + } +} + +void inode_cache_init() { + g_inode_kmem_cache = kmem_cache_create("inode_kmem_cache", sizeof(inode_t), 4); + assert(g_inode_kmem_cache != NULL); + + // +} diff --git a/fs/mount.c b/fs/mount.c new file mode 100644 index 0000000..1022785 --- /dev/null +++ b/fs/mount.c @@ -0,0 +1,108 @@ +/* + * ------------------------------------------------------------------------ + * File Name: mount.c + * Author: Zhao Yanbai + * 2024-08-30 21:40:57 Friday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#include "mount.h" + +#include "irq.h" +#include "mm.h" +#include "string.h" +#include "system.h" + +kmem_cache_t *vfsmount_kmem_cache = 0; + +// 通过挂载点目录的 path_t 也就是 {mount, dentry}计算hash +// 就可以得到所有挂载在该目录上的挂载描述符 vfsmount +vfsmount_t **vfsmount_hash_table = 0; +int vfsmount_hash_table_size = 0; + +vfsmount_t *alloc_vfsmount(const char *name) { + vfsmount_t *mnt = 0; + + mnt = (vfsmount_t *)kmem_cache_zalloc(vfsmount_kmem_cache, 0); + + if (0 == mnt) { + panic("no mem alloc for vfsmount: %s", name); + return 0; + } + + INIT_LIST_HEAD(&mnt->mnt_list); + strncpy(mnt->mnt_devname, name, MAX_VFSMNT_NAME_LEN); + + assert(mnt->hash_next == 0); + + return mnt; +} + +vfsmount_t *vfs_kernel_mount(fs_type_t *type, int flags, const char *name, void *data) { + int ret = 0; + vfsmount_t *mnt = 0; + + assert(0 != type); + + mnt = alloc_vfsmount(name); + + ret = type->read_super(type, flags, name, data, mnt); + + assert(mnt->mnt_sb != 0); + assert(mnt->mnt_root != 0); + + mnt->mnt_point = mnt->mnt_root; + mnt->mnt_parent = mnt; + + // if (type->flags & FS_TYPE_NODEV) { + // } + + return mnt; +} + +unsigned long vfsmount_table_hash(vfsmount_t *mnt, dentry_t *dentry) { + unsigned long h = (unsigned long)mnt / 5; + h += 1; + h += (unsigned long)dentry / 5; + h = h + (h >> 9); + return h & (vfsmount_hash_table_size - 1); +} + +void add_vfsmount_to_hash_table(vfsmount_t *mnt) { + unsigned long hash = vfsmount_table_hash(mnt->mnt_parent, mnt->mnt_point); + + uint32_t eflags; + irq_save(eflags); + + vfsmount_t **p = vfsmount_hash_table + hash; + + mnt->hash_next = *p; + + *p = mnt; + + irq_restore(eflags); +} + +void init_mount() { + vfsmount_kmem_cache = kmem_cache_create("vfsmount", sizeof(vfsmount_t), 4); + if (0 == vfsmount_kmem_cache) { + panic("create vfsmount kmem cache failed"); + } + + vfsmount_hash_table = (vfsmount_t **)page2va(alloc_one_page(0)); + memset(vfsmount_hash_table, 0, PAGE_SIZE); + + vfsmount_hash_table_size = PAGE_SIZE / sizeof(vfsmount_t *); + + assert(vfsmount_hash_table_size != 0); + + // vfsmount_hash_table_size 应该是2的n次方的数 + int bit1_cnt = 0; + for (int i = 0; i < sizeof(vfsmount_hash_table_size) * 8; i++) { + if (vfsmount_hash_table_size & (1 << i)) { + bit1_cnt++; + } + } + assert(bit1_cnt == 1); +} diff --git a/fs/mount.h b/fs/mount.h new file mode 100644 index 0000000..e0ed4de --- /dev/null +++ b/fs/mount.h @@ -0,0 +1,14 @@ +/* + * ------------------------------------------------------------------------ + * File Name: mount.h + * Author: Zhao Yanbai + * 2024-08-30 21:40:51 Friday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#pragma once + +#include "vfs.h" + +vfsmount_t *vfs_kernel_mount(fs_type_t *type, int flags, const char *name, void *data); diff --git a/fs/path.c b/fs/path.c index c3f33a3..6c23509 100644 --- a/fs/path.c +++ b/fs/path.c @@ -105,20 +105,20 @@ uint64_t compute_qstr_hash(qstr_t *q) { } 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); - } - } + // 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) { diff --git a/fs/ramfs.c b/fs/ramfs.c index e1caf28..2ab035b 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -13,14 +13,6 @@ #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 { // @@ -33,8 +25,97 @@ typedef struct ramfs_dentry { typedef struct ramfs_inode { // d + inode_t vfs_inode; } ramfs_inode_t; -void ramfs_init() { vfs_register_filesystem(&ramfs_type); } +static kmem_cache_t *g_ramfs_inode_cache = 0; + +// static inode_t *ramfs_alloc_inode(superblock_t *sb) { +// ramfs_inode_t *inode = kmem_cache_alloc(g_ramfs_inode_cache, 0); +// assert(inode != 0); + +// return &(inode->vfs_inode); +// } + +static const file_operations_t ramfs_file_operations = { + .read = 0, +}; + +static const inode_operations_t ramfs_file_inode_operations = { + +}; + +static const inode_operations_t ramfs_dir_inode_operations = { + +}; + +inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev) { + inode_t *inode = alloc_inode(sb); + + if (NULL == inode) { + return inode; + } + + inode->i_mode = mode; + + switch (mode & S_IFMT) { + case S_IFREG: + // panic("S_IFREG: not implement"); + inode->i_fops = &ramfs_file_operations; + inode->i_ops = &ramfs_file_inode_operations; + break; + case S_IFDIR: + panic("S_IFDIR: not implement"); + inode->i_fops = &simple_dir_operations; + inode->i_ops = &ramfs_dir_inode_operations; + break; + case S_IFLNK: + panic("S_IFLNK: not implement"); + break; + default: + init_special_inode(inode, mode, dev); + break; + } + + return NULL; +} + +static sb_operations_t ramfs_ops = { + // .alloc_inode = ramfs_alloc_inode, +}; + +int ramfs_fill_super_cb(superblock_t *sb, void *data) { + int err = 0; + + // assert(sb->sb_ops != NULL); + inode_t *fs_root_inode = ramfs_get_inode(sb, S_IFDIR, 0); + assert(fs_root_inode != NULL); + + dentry_t *fs_root_dentry = 0; + fs_root_dentry = dentry_alloc_root(fs_root_inode); + assert(fs_root_dentry != NULL); + + sb->sb_root = fs_root_dentry; + + return err; +} + +int ramfs_read_super(fs_type_t *type, int flags, const char *name, void *data, vfsmount_t *mnt) { + int ret = 0; + + ret = read_super_for_nodev(type, flags, data, ramfs_fill_super_cb, mnt); + + return ret; +} + +fs_type_t ramfs_type = { + .name = "ramfs", + .read_super = ramfs_read_super, + .next = 0, +}; -superblock_t *ramfs_read_super(superblock_t *sb, void *data) { return sb; } +void ramfs_init() { + vfs_register_filesystem(&ramfs_type); + g_ramfs_inode_cache = kmem_cache_create("ramfs_inode_cache", sizeof(ramfs_inode_t), 4); + assert(0 != g_ramfs_inode_cache); +} diff --git a/fs/super.c b/fs/super.c new file mode 100644 index 0000000..08875d4 --- /dev/null +++ b/fs/super.c @@ -0,0 +1,82 @@ +/* + * ------------------------------------------------------------------------ + * File Name: super.c + * Author: Zhao Yanbai + * 2024-08-30 21:38:05 Friday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#include "errno.h" +#include "fs.h" +#include "irq.h" +#include "list.h" +#include "system.h" + +LIST_HEAD(g_superblocks); + +static superblock_t *alloc_super(fs_type_t *type) { + superblock_t *s; + s = (superblock_t *)kzalloc(sizeof(superblock_t), 0); + if (0 == s) { + panic("alloc superblock for %s", type->name); + return s; + } + + static sb_operations_t default_sb_ops; + + s->sb_ops = &default_sb_ops; + INIT_LIST_HEAD(&s->sb_list); + INIT_LIST_HEAD(&s->sb_instance); + + return s; +} + +int read_super_for_nodev(fs_type_t *type, int flags, void *data, fill_super_cb_t fill_super, vfsmount_t *mnt) { + int ret = 0; + superblock_t *s = 0; + + // 分配superblock + + // + s->sb_flags = flags; + + ret = fill_super(s, data); + if (0 != ret) { + } + + return ret; +} + +superblock_t *sget(fs_type_t *type, // + int (*test)(superblock_t *, void *), // + int (*set)(superblock_t *, void *), // + void *data // +) { + int ret = 0; + superblock_t *s = 0; + + if (0 != test) { + panic("not implemented"); + } + + // TOOD REMOVE + assert(0 == s); + + s = alloc_super(type); + if (0 == s) { + return ERR_PTR(-ENOMEM); + } + + assert(0 != set); + + ret = set(s, data); + assert(0 == ret); + + uint32_t eflags; + irq_save(eflags); + list_add_tail(&s->sb_list, &g_superblocks); + irq_restore(eflags); + + return s; +} diff --git a/fs/vfs.c b/fs/vfs.c index 525dce5..c6c3041 100644 --- a/fs/vfs.c +++ b/fs/vfs.c @@ -7,6 +7,7 @@ * ------------------------------------------------------------------------ */ +#include #include #include #include @@ -28,20 +29,30 @@ dentry_t *root_entry = 0; fs_type_t file_systems = {"filesystems", 0, 0}; -void vfs_register_filesystem(fs_type_t *fs) { +int vfs_register_filesystem(fs_type_t *fs) { int ret = 0; + assert(fs != NULL); + if (fs->next != NULL) { + return -EBUSY; + } + + INIT_LIST_HEAD(&fs->sbs); + fs_type_t *add = &file_systems; + // TODO: 加锁、解锁保护 + for (fs_type_t *fst = &file_systems; fst != 0; fst = fst->next) { if (strcmp(fst->name, fs->name) == 0) { - return; + return -EBUSY; } add = fst; } add->next = fs; fs->next = 0; + return 0; } fs_type_t *vfs_find_filesystem(const char *name) { @@ -62,7 +73,7 @@ void vfs_init() { panic("no ramfs"); } - superblock_t *sb = fs->read_super(NULL, NULL); + // superblock_t *sb = fs->read_super(NULL, NULL); } ///////// diff --git a/fs/vfs.h b/fs/vfs.h index 6a9e75e..a076ae0 100644 --- a/fs/vfs.h +++ b/fs/vfs.h @@ -21,20 +21,28 @@ typedef struct qstr { } qstr_t; typedef struct dentry dentry_t; - +typedef struct inode inode_t; typedef struct sb_operations sb_operations_t; typedef struct file_operations file_operations_t; typedef struct inode_operations inode_operations_t; typedef struct dentry_operations dentry_operations_t; +typedef struct vfsmount vfsmount_t; +typedef struct path path_t; // super block typedef struct superblock { // 该超级起的根目录的 dentry dentry_t *sb_root; + + int sb_flags; + // void *sb_private; // sb_operations_t *sb_ops; + + list_head_t sb_list; + list_head_t sb_instance; } superblock_t; // dentry和inode为什么不合二为一? @@ -45,7 +53,7 @@ typedef struct superblock { // 所以dentry代表逻辑意义上的文件,记录的是逻辑意义上的属性 // 而inode结构代表的是物理意义上的文件 // 它们之间的关系是多对一的关系 -typedef struct inode { +struct inode { superblock_t *i_sb; void *i_private; @@ -53,10 +61,10 @@ typedef struct inode { semaphore_t i_sem; // fops - file ops 的副本 - file_operations_t *i_fops; + const file_operations_t *i_fops; // ops - inode ops - inode_operations_t *i_ops; + const inode_operations_t *i_ops; // 缓存的pages list_head_t i_pages; @@ -65,11 +73,14 @@ typedef struct inode { dev_t i_rdev; // inode所代表的设备号 loff_t i_size; -} inode_t; + + umode_t i_mode; // FILE DIR CHR BLK FIFO SOCK +}; #define DENTRY_INLINE_NAME_LEN 16 struct dentry { // char *d_name; + uint32_t d_flags; qstr_t d_name; char d_inline_name[DENTRY_INLINE_NAME_LEN]; @@ -107,7 +118,7 @@ struct dentry { struct sb_operations { // alloc inode - inode_t *alloc_inode(superblock_t *sb); + inode_t *(*alloc_inode)(superblock_t *sb); // read_inode }; @@ -134,6 +145,11 @@ struct dentry_operations { // }; +struct path { + dentry_t *dentry; + vfsmount_t *mount; +}; + // 每当将一个存储设备安装到现有文件系统中的某个节点时,内核就要为之建立一个vfsmount结构 // 这个结构中即包含着该设备的有关信息,也包含了安装点的信息 // 系统中的每个文件系统,包括根设备的根文件系统,都要经过安装 @@ -145,7 +161,8 @@ struct dentry_operations { // 为被安装的设备的根目录创建一个inode,由sb->sb_ops->read_inode来实现 // 将superblock与被安装设备根目录的dentry关联 // 将vfsmount与被安装设备的根目录dentry关联 -typedef struct vfsmount { +#define MAX_VFSMNT_NAME_LEN 32 +struct vfsmount { dentry_t *mnt_point; // 挂载点 dentry dentry_t *mnt_root; // 设备根目录 dentry superblock_t *mnt_sb; // 被安装的设备的superblock @@ -154,26 +171,43 @@ typedef struct vfsmount { list_head_t mnt_list; // vfsmount 链表 - list_head_t mnt_clash; + vfsmount_t *hash_next; + + char mnt_devname[MAX_VFSMNT_NAME_LEN]; + + // list_head_t mnt_clash; // 先简单实现:不支持一个设备挂载多次,或一个目录被挂载多次 -} vfsmount_t; +}; + +#define FS_TYPE_NODEV 1 +#define FS_TYPE_BLKDEV 2 -typedef struct fs_type { +typedef struct fs_type fs_type_t; +struct fs_type { const char *name; - superblock_t *(*read_super)(superblock_t *, void *); + // superblock_t *(*read_super)(superblock_t *, void *); + int (*read_super)(fs_type_t *type, int flags, const char *name, void *data, vfsmount_t *mnt); + int flags; // FS_REQUIRES_DEV or NODEV struct fs_type *next; - list_head_t sbs; // 同属于这个文件系统的所有超级块链表 -} fs_type_t; + // 同属于这个文件系统的所有超级块链表 + // 因为同名文件系统可能有多个实例,所有的该文件系统的实例的superblock,都通过sbs这个链到一起 + list_head_t sbs; +}; extern superblock_t *root_sb; -void vfs_register_filesystem(fs_type_t *fs); +int vfs_register_filesystem(fs_type_t *fs); ///// +inode_t *alloc_inode(superblock_t *sb); +void init_special_inode(inode_t *inode, umode_t mode, dev_t rdev); +//// + dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s); int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry); +dentry_t *dentry_alloc_root(inode_t *root_inode); vfsmount_t *vfsmnt_get(vfsmount_t *m); void vfsmnt_put(vfsmount_t *m); @@ -182,3 +216,6 @@ dentry_t *dentry_get(dentry_t *dentry); void dentry_get_locked(dentry_t *dentry); void dentry_put(dentry_t *dentry); + +///// +extern const file_operations_t simple_dir_operations; diff --git a/include/fs.h b/include/fs.h index 12b8dec..b475b7d 100644 --- a/include/fs.h +++ b/include/fs.h @@ -17,6 +17,8 @@ #include #include +#include "stat.h" + /* 分区表开始的位置 */ #define PARTS_POS 0x1BE @@ -125,4 +127,13 @@ static inline pInode find_empty_inode() } #endif +typedef int (*fill_super_cb_t)(superblock_t *sb, void *data); +int read_super_for_nodev(fs_type_t *type, int flags, void *data, fill_super_cb_t fill_super, vfsmount_t *mnt); + +superblock_t *sget(fs_type_t *type, // + int (*test)(superblock_t *, void *), // + int (*set)(superblock_t *, void *), // + void *data // +); + #endif //_FS_H diff --git a/include/mm.h b/include/mm.h index ea778d4..156d3cf 100644 --- a/include/mm.h +++ b/include/mm.h @@ -20,3 +20,4 @@ unsigned long bootmem_page_state(unsigned long pfn); kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t align); void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags); +void *kmem_cache_zalloc(kmem_cache_t *cache, gfp_t gfpflags); diff --git a/include/stat.h b/include/stat.h index 01cf303..47138dd 100644 --- a/include/stat.h +++ b/include/stat.h @@ -34,24 +34,40 @@ typedef struct stat { unsigned long __unused5; } Stat, *pStat; +// 8进制 #define S_IFMT 00170000 -#define S_IFSOCK 0140000 -#define S_IFLNK 0120000 -#define S_IFREG 0100000 -#define S_IFBLK 0060000 -#define S_IFDIR 0040000 -#define S_IFCHR 0020000 -#define S_IFIFO 0010000 +#define S_IFREG 0010000 +#define S_IFDIR 0020000 +#define S_IFBLK 0030000 +#define S_IFCHR 0040000 +#define S_IFLNK 0050000 + #define S_ISUID 0004000 #define S_ISGID 0002000 #define S_ISVTX 0001000 -#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) -#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) -#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) -#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) -#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) -#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) -#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) +#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) +#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) +#define S_ISBLK(x) (((x) & S_IFMT) == S_IFBLK) +#define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR) +#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) + +// user权限 +#define S_IURWX 00700 +#define S_IUSRR 00400 +#define S_IUSRW 00200 +#define S_IUSRX 00100 + +// group权限 +#define S_IGRWX 00070 +#define S_IGRPR 00040 +#define S_IGRPW 00020 +#define S_IGRPX 00010 + +// other权限 +#define S_IORWX 00007 +#define S_IOTHR 00004 +#define S_IOTHW 00002 +#define S_IOTHX 00001 #endif //_STAT_H diff --git a/include/system.h b/include/system.h index 9189c40..9360459 100644 --- a/include/system.h +++ b/include/system.h @@ -55,6 +55,7 @@ }) void *kmalloc(size_t size, gfp_t gfpflags); +void *kzalloc(size_t size, gfp_t gfpflags); void kfree(void *addr); #define panic(msg, ...) \ @@ -77,7 +78,7 @@ extern char etext, edata, end; #define disableIRQ() cli() #define enableIRQ() sti() -#define ALIGN(x, a) (((x) + (a)-1) & ~((a)-1)) +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) // 定义最大显存为 16MB #define VRAM_VADDR_SIZE (16 << 20) @@ -271,4 +272,18 @@ void boot_delay(int ticks); #endif +#define MAX_ERRNO 4095 + +#ifndef ASM + +#define IS_ERR_VALUE(x) (((unsigned long)(x)) >= ((unsigned long)(-MAX_ERRNO))) + +static inline void *ERR_PTR(long err) { return ((void *)(err)); } + +static inline long PTR_ERR(void *p) { return ((long)(p)); } + +static inline bool IS_ERR(void *p) { return IS_ERR_VALUE(p); } + +#endif + #endif //_SYSTEM_H diff --git a/include/types.h b/include/types.h index 62c2b65..30fb457 100644 --- a/include/types.h +++ b/include/types.h @@ -53,6 +53,7 @@ typedef long long int64_t; typedef uint64_t loff_t; typedef uint32_t dev_t; +typedef uint32_t umode_t; typedef unsigned long pid_t; typedef unsigned long mode_t; diff --git a/mm/kmem.c b/mm/kmem.c index 756aebe..dc31f38 100644 --- a/mm/kmem.c +++ b/mm/kmem.c @@ -73,6 +73,14 @@ err: void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags) { return slub_alloc(cache, gfpflags); } +void *kmem_cache_zalloc(kmem_cache_t *cache, gfp_t gfpflags) { + void *p = slub_alloc(cache, gfpflags); + if (0 != p) { + memset(p, 0, cache->objsize); + } + return p; +} + void kmem_cache_free(kmem_cache_t *cache, void *addr) { page_t *page = 0; @@ -121,6 +129,15 @@ void *kmalloc(size_t size, gfp_t gfpflags) { return addr; } +void *kzalloc(size_t size, gfp_t gfpflags) { + void *p = kmalloc(size, gfpflags); + if (0 != p) { + memset(p, 0, size); + } + + return p; +} + void kfree(void *addr) { page_t *page = get_head_page(va2page((unsigned long)addr)); kmem_cache_t *cache = page->cache; -- 2.44.0