]> Zhao Yanbai Git Server - kernel.git/commitdiff
ramfs初步代码,vfs read_super inode dentry相关逻辑添加
authoracevest <zhaoyanbai@126.com>
Sat, 31 Aug 2024 14:10:17 +0000 (22:10 +0800)
committeracevest <zhaoyanbai@126.com>
Sat, 31 Aug 2024 14:10:17 +0000 (22:10 +0800)
18 files changed:
fs/dentry.c
fs/ext2.c
fs/fs.c
fs/fslib.c [new file with mode: 0644]
fs/inode.c
fs/mount.c [new file with mode: 0644]
fs/mount.h [new file with mode: 0644]
fs/path.c
fs/ramfs.c
fs/super.c [new file with mode: 0644]
fs/vfs.c
fs/vfs.h
include/fs.h
include/mm.h
include/stat.h
include/system.h
include/types.h
mm/kmem.c

index ff51992630eaf51d1125543e69fd971d1082bb0b..7d07a5efdc3219247484c765eff1c9c2583986c9 100644 (file)
@@ -15,6 +15,7 @@
 #include <vfs.h>
 #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) {
index ffa6e1b551037798660ceade2f1d0a40cee30fe8..58f1f6fa48689be9b13cc606db638e10858cf51e 100644 (file)
--- a/fs/ext2.c
+++ b/fs/ext2.c
 #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 cde27a894501c9de547fa4eaf4475adad7183e82..e7a13e2b3892b1fecff3b61dea1b47a6557ca198 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -11,6 +11,7 @@
  */
 #include <fs.h>
 #include <io.h>
+#include <mm.h>
 #include <printk.h>
 #include <system.h>
 
@@ -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 (file)
index 0000000..3b149c9
--- /dev/null
@@ -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 = {
+
+};
index 142839da1e51caafe571ce59b8ce80ab98356555..c8a6bb9aca3fececbf8db6ebebed7a22ff035149 100644 (file)
@@ -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 (file)
index 0000000..1022785
--- /dev/null
@@ -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 (file)
index 0000000..e0ed4de
--- /dev/null
@@ -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);
index c3f33a34f0f8e6081e3900d7ab479cb13c1b8a75..6c23509898e40bcb8154b2993db1b2a05bc8cb44 100644 (file)
--- 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) {
index e1caf283e11308a45d83d956e5dd2d9cfc808099..2ab035b97f03c401fb7c80b9a445152d6f10f66d 100644 (file)
 #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 (file)
index 0000000..08875d4
--- /dev/null
@@ -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;
+}
index 525dce5ddb9631fd8096e743d70842df74584e6f..c6c3041930318a7c80ef40c0d0f7c78dfdd76edf 100644 (file)
--- a/fs/vfs.c
+++ b/fs/vfs.c
@@ -7,6 +7,7 @@
  * ------------------------------------------------------------------------
  */
 
+#include <errno.h>
 #include <string.h>
 #include <system.h>
 #include <vfs.h>
@@ -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);
 }
 
 /////////
index 6a9e75ebba96badf86d0a2103fe37c3514b750c8..a076ae0302138d6db7ef2c25f1a90c47b20e3d0d 100644 (file)
--- 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;
index 12b8deccce6d1ae4a4ee653dc05e0a8716994ca8..b475b7dae3f5aa5ad954d205e64fa6071e15378f 100644 (file)
@@ -17,6 +17,8 @@
 #include <types.h>
 #include <vfs.h>
 
+#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
index ea778d4a15258b50687e953f830f7ff7ad4d9de9..156d3cf39a091da67d62ef804f2be61df2319e71 100644 (file)
@@ -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);
index 01cf303cb894b77172067c4d63d564e0e1aa3c50..47138dd61f5374519fb80f86cab5e53ce48c4e25 100644 (file)
@@ -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
index 9189c401654a340305a3161062e8074f9917dba7..93604598a117d3600624a4107b7b855b1ffd2135 100644 (file)
@@ -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
index 62c2b65dd00b56cad16460fb967e0529b0d77929..30fb45772e47291914a8cf96fceda96e426e916a 100644 (file)
@@ -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;
index 756aebeace3ddd3d63d1650361010319c96c4be6..dc31f38f19d615e7bc1f4d6355bee5b898138623 100644 (file)
--- 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;