]> Zhao Yanbai Git Server - kernel.git/commitdiff
进一步完善sysc_mkdir相关逻辑;修复dentry_cached_lookup中找到cached dentry也返回NULL的问题;修复path_init中没有正确...
authoracevest <zhaoyanbai@126.com>
Mon, 2 Sep 2024 15:45:05 +0000 (23:45 +0800)
committeracevest <zhaoyanbai@126.com>
Mon, 2 Sep 2024 15:45:05 +0000 (23:45 +0800)
fs/dentry.c
fs/fssysc.c
fs/path.c
fs/ramfs.c
fs/vfs.h
kernel/task_root.c

index de7cdac75d5f3af070bada1bfbe3cbb233cff952..33cb782fb8b53aeffd6f66f63e1e7ba3b3ab4726 100644 (file)
@@ -26,11 +26,17 @@ dentry_hash_entry_t dentry_hash_table[DENTRY_HASH_TABLE_SIZE] = {
 };
 
 uint32_t mod64(uint64_t x, uint32_t y) {
+#if 1
+    // TODO FIXME
+    uint32_t d = (uint32_t)x;
+    return d % y;
+#else
     uint32_t mod;
 
     asm("div %3;" : "=d"(mod) : "a"((uint32_t)x), "d"((uint32_t)(x >> 32)), "r"(y) : "cc");
 
     return mod;
+#endif
 }
 
 dentry_t *dentry_alloc(dentry_t *parent, const qstr_t *s) {
@@ -50,6 +56,7 @@ dentry_t *dentry_alloc(dentry_t *parent, const qstr_t *s) {
 
     dentry->d_name.len = 0;
     dentry->d_name.name = 0;
+    dentry->d_name = *s;
 
     memcpy(dentry->d_inline_name, s->name, s->len);
     dentry->d_inline_name[s->len] = 0;
@@ -90,12 +97,44 @@ dentry_t *dentry_alloc_root(inode_t *root_inode) {
     return dentry;
 }
 
-dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s) {
-    int index = mod64(s->hash, DENTRY_HASH_TABLE_SIZE);
+dentry_hash_entry_t *dentry_hash(dentry_t *parent, uint64_t hash) {
+    int index = mod64(hash, DENTRY_HASH_TABLE_SIZE);
     assert(index < DENTRY_HASH_TABLE_SIZE);
 
     dentry_hash_entry_t *dhe = dentry_hash_table + index;
 
+    assert(dhe != NULL);
+    assert(dhe >= dentry_hash_table);
+    assert(dhe < dentry_hash_table + DENTRY_HASH_TABLE_SIZE);
+
+    return dhe;
+}
+
+void dentry_attach_inode(dentry_t *dentry, inode_t *inode) {
+    assert(dentry != NULL);
+    // assert(inode != NULL);
+
+    dentry->d_inode = inode;
+}
+
+void dentry_rehash(dentry_t *dentry) {
+    dentry_hash_entry_t *dhe = dentry_hash(dentry->d_parent, dentry->d_name.hash);
+
+    mutex_lock(&dhe->mutex);
+
+    list_add(&dentry->d_hash, &dhe->list);
+
+    mutex_unlock(&dhe->mutex);
+}
+
+void dentry_add(dentry_t *dentry, inode_t *inode) {
+    dentry_attach_inode(dentry, inode);
+    dentry_rehash(dentry);
+}
+
+dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s) {
+    dentry_hash_entry_t *dhe = dentry_hash(parent, s->hash);
+
     dentry_t *dentry = NULL;
 
     mutex_lock(&dhe->mutex);
@@ -123,7 +162,8 @@ dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s) {
 
         dentry_get_locked(dentry);
 
-        break;
+        mutex_unlock(&dhe->mutex);
+        return dentry;
     }
 
     mutex_unlock(&dhe->mutex);
@@ -152,10 +192,13 @@ int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry) {
     if (new_dentry == NULL) {
         ret = -ENOMEM;
     } else {
+        assert(dir->i_ops != NULL);
+        assert(dir->i_ops->lookup != NULL);
+        printk(">>>>>> %x %x\n", dir->i_ops, dir->i_ops->lookup);
         *dentry = dir->i_ops->lookup(dir, new_dentry);
         // 返回 lookup 没有再分配一个dentry
         // 否则就释放dentry_new使用lookup返回的dentry
-        if (dentry == NULL) {
+        if (*dentry == NULL) {
             *dentry = new_dentry;
         } else {
             dentry_put(new_dentry);
@@ -191,9 +234,13 @@ dentry_t *dentry_get(dentry_t *dentry) {
     return dentry;
 }
 
-void dentry_get_locked(dentry_t *dentry) {}
+void dentry_get_locked(dentry_t *dentry) {
+    //
+}
 
-void dentry_put(dentry_t *dentry) { panic("todo"); }
+void dentry_put(dentry_t *dentry) {
+    //
+}
 
 // static __inline__ struct dentry * dget(struct dentry *dentry)
 // {
index 9f0e02b0cde2949f8e05cf03f46ea49124ca5a3f..f528d9ea1d0d80133dd3bab89db81a332ecd0115 100644 (file)
@@ -7,13 +7,27 @@
  * ------------------------------------------------------------------------
  */
 
+#include "errno.h"
 #include "fs.h"
 #include "system.h"
 
 //////
-int vfs_mkdir() {
+int vfs_mkdir(inode_t *dir, dentry_t *dentry, int mode) {
     int ret = 0;
 
+    // TODO REMOVE
+    assert(dir->i_ops->mkdir != NULL);
+
+    if (dir->i_ops->mkdir == NULL) {
+        return -EPERM;
+    }
+
+    ret = dir->i_ops->mkdir(dir, dentry, mode);
+
+    if (0 != ret) {
+        printk("%s ret %d\n", __func__, ret);
+    }
+
     return ret;
 }
 
@@ -34,7 +48,7 @@ __attribute__((regparm(0))) long sysc_mkdir(const char *path, int mode) {
     dentry = path_lookup_create(&ni);
     ret = PTR_ERR(dentry);
     if (!IS_ERR(dentry)) {
-        ret = vfs_mkdir(ni.path.dentry, dentry, mode);
+        ret = vfs_mkdir(ni.path.dentry->d_inode, dentry, mode);
         dentry_put(dentry);
     }
 
index 3ccdc247a26b6b139dc2ebb62894a29e726487ae..d647244b6fbbceb2c69b72b78bc1d7fcd0a4eda3 100644 (file)
--- a/fs/path.c
+++ b/fs/path.c
@@ -14,6 +14,9 @@
 #include <vfs.h>
 
 bool path_init(const char *path, unsigned int flags, namei_t *ni) {
+    ni->flags = flags;
+    ni->last_type = LAST_ROOT;
+
     if (path == NULL) {
         return false;
     }
@@ -107,6 +110,8 @@ uint64_t compute_qstr_hash(qstr_t *q) {
 
     q->hash += q->hash >> (4 * sizeof(q->hash));
 
+    q->hash &= 0x00000000FFFFFFFF;
+
     return q->hash;
 }
 
@@ -128,7 +133,7 @@ int follow_down(dentry_t **dentry, vfsmount_t **vfsmnt) {
 }
 
 int path_walk(const char *path, namei_t *ni) {
-    dentry_t *dentry;
+    dentry_t *dentry = NULL;
     int ret = 0;
     if (path == NULL) {
         return -EINVAL;
@@ -152,7 +157,6 @@ int path_walk(const char *path, namei_t *ni) {
     while (true) {
         qstr_t this;
         this.name = path;
-
         do {
             path++;
         } while (*path != 0 && (*path != '/'));
@@ -242,6 +246,11 @@ int path_walk(const char *path, namei_t *ni) {
     last_file_name_with_slash:
         path_lookup_flags |= PATH_LOOKUP_DIRECTORY;
     last_file_name:
+
+        // 计算当前文件名的hash
+        compute_qstr_hash(&this);
+        printk("HASH %s %lu\n", this.name, this.hash);
+
         if (path_lookup_flags & PATH_LOOKUP_PARENT) {
             ni->last = this;
             ni->last_type = LAST_NORMAL;
@@ -265,8 +274,9 @@ int path_walk(const char *path, namei_t *ni) {
             goto ok;
         }
 
-        // 计算当前文件名的hash
-        compute_qstr_hash(&this);
+        // // 计算当前文件名的hash
+        // compute_qstr_hash(&this);
+        // printk("HASH %s %lu\n", this.name, this.hash);
 
         // 根据该名字,先上dentry cache里找
         dentry = dentry_cached_lookup(ni->path.dentry, &this);
index 281f301e1e4252b3af6af3b5bf2f6f10e0a053b4..a1df5659b1f89f6bb7095e03d1237f47ed2e968b 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "ramfs.h"
 
+#include "errno.h"
 #include "fs.h"
 #include "mm.h"
 #include "string.h"
@@ -30,6 +31,8 @@ typedef struct ramfs_inode {
 
 static kmem_cache_t *g_ramfs_inode_cache = 0;
 
+inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev);
+
 // static inode_t *ramfs_alloc_inode(superblock_t *sb) {
 //     ramfs_inode_t *inode = kmem_cache_alloc(g_ramfs_inode_cache, 0);
 //     assert(inode != 0);
@@ -49,14 +52,32 @@ static const file_operations_t ramfs_dir_operations = {
 
 };
 
-int ramfs_mkdir(inode_t *, dentry_t *, int) {
+int ramfs_mkdir(inode_t *dir, dentry_t *dentry, int mode) {
     int ret = 0;
 
+    inode_t *inode = NULL;
+
+    inode = ramfs_get_inode(dir->i_sb, mode | S_IFDIR, 0);
+    if (inode == NULL) {
+        return -ENOSPC;
+    }
+
+    dentry_attach_inode(dentry, inode);
+
+    dentry_get(dentry);
+
     return ret;
 }
 
+dentry_t *ramfs_lookup(inode_t *dir, dentry_t *dentry) {
+    dentry_add(dentry, NULL);
+
+    return NULL;
+}
+
 static const inode_operations_t ramfs_dir_inode_operations = {
     .mkdir = ramfs_mkdir,
+    .lookup = ramfs_lookup,
 };
 
 inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev) {
index 989bbd758f415ecd3fa0f2d9dc790ca36b545810..b4936bef6b8f3b401c30bd0f840b19fb5673e630 100644 (file)
--- a/fs/vfs.h
+++ b/fs/vfs.h
@@ -264,6 +264,8 @@ 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);
 dentry_t *dentry_alloc(dentry_t *parent, const qstr_t *s);
+void dentry_add(dentry_t *dentry, inode_t *inode);
+void dentry_attach_inode(dentry_t *dentry, inode_t *inode);
 
 vfsmount_t *vfsmnt_get(vfsmount_t *m);
 void vfsmnt_put(vfsmount_t *m);
index c7eeeadce9f02ddde7fbd1a207506d0c4eaa0019..858d3c508218f37ba75a8c8a77ef01b4aa760bf4 100644 (file)
@@ -164,6 +164,16 @@ void taskC_entry() {
 void root_task_entry() {
     sti();
 
+    extern __attribute__((regparm(0))) long sysc_mkdir(const char *path, int mode);
+    sysc_mkdir("/root", 0777);
+
+    {
+        namei_t ni;
+        const char *path = "/root";
+        path_init(path, 0, &ni);
+        path_walk(path, &ni);
+    }
+
     // 有一点点垃圾事情需要处理
     // 之前内核初始化都是在关中断下进行的
     // 这就段时间有可能按键盘,然而键盘不把数据读出来就不会触发下一次中断