From: acevest Date: Mon, 2 Sep 2024 15:45:05 +0000 (+0800) Subject: 进一步完善sysc_mkdir相关逻辑;修复dentry_cached_lookup中找到cached dentry也返回NULL的问题;修复path_init中没有正确... X-Git-Url: http://zhaoyanbai.com/repos/man.dnssec-checkds.html?a=commitdiff_plain;h=fc5355add9ff2a7d0b0f9312333e633f2e1a556d;p=kernel.git 进一步完善sysc_mkdir相关逻辑;修复dentry_cached_lookup中找到cached dentry也返回NULL的问题;修复path_init中没有正确初始化flags和last_type的问题 --- diff --git a/fs/dentry.c b/fs/dentry.c index de7cdac..33cb782 100644 --- a/fs/dentry.c +++ b/fs/dentry.c @@ -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) // { diff --git a/fs/fssysc.c b/fs/fssysc.c index 9f0e02b..f528d9e 100644 --- a/fs/fssysc.c +++ b/fs/fssysc.c @@ -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); } diff --git a/fs/path.c b/fs/path.c index 3ccdc24..d647244 100644 --- a/fs/path.c +++ b/fs/path.c @@ -14,6 +14,9 @@ #include 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); diff --git a/fs/ramfs.c b/fs/ramfs.c index 281f301..a1df565 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -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) { diff --git a/fs/vfs.h b/fs/vfs.h index 989bbd7..b4936be 100644 --- 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); diff --git a/kernel/task_root.c b/kernel/task_root.c index c7eeead..858d3c5 100644 --- a/kernel/task_root.c +++ b/kernel/task_root.c @@ -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); + } + // 有一点点垃圾事情需要处理 // 之前内核初始化都是在关中断下进行的 // 这就段时间有可能按键盘,然而键盘不把数据读出来就不会触发下一次中断