};
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) {
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;
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);
dentry_get_locked(dentry);
- break;
+ mutex_unlock(&dhe->mutex);
+ return dentry;
}
mutex_unlock(&dhe->mutex);
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);
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)
// {
* ------------------------------------------------------------------------
*/
+#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;
}
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);
}
#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;
}
q->hash += q->hash >> (4 * sizeof(q->hash));
+ q->hash &= 0x00000000FFFFFFFF;
+
return q->hash;
}
}
int path_walk(const char *path, namei_t *ni) {
- dentry_t *dentry;
+ dentry_t *dentry = NULL;
int ret = 0;
if (path == NULL) {
return -EINVAL;
while (true) {
qstr_t this;
this.name = path;
-
do {
path++;
} while (*path != 0 && (*path != '/'));
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;
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);
#include "ramfs.h"
+#include "errno.h"
#include "fs.h"
#include "mm.h"
#include "string.h"
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);
};
-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) {
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);
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);
+ }
+
// 有一点点垃圾事情需要处理
// 之前内核初始化都是在关中断下进行的
// 这就段时间有可能按键盘,然而键盘不把数据读出来就不会触发下一次中断