ソースを参照

feat: find inode according to filename

greatbridf 2 年 前
コミット
3fd580fe86
5 ファイル変更65 行追加19 行削除
  1. 1 0
      include/kernel/stdio.h
  2. 3 3
      include/kernel/vfs.h
  3. 6 1
      include/types/list.hpp
  4. 11 1
      src/kernel/stdio.c
  5. 44 14
      src/kernel/vfs.cpp

+ 1 - 0
include/kernel/stdio.h

@@ -18,6 +18,7 @@ void* memcpy(void* dst, const void* src, size_t n);
 void* memset(void* dst, int c, size_t n);
 size_t strlen(const char* str);
 char* strncpy(char* dst, const char* src, size_t max_n);
+int strcmp(const char* s1, const char* s2);
 
 ssize_t
 snprint_decimal(

+ 3 - 3
include/kernel/vfs.h

@@ -14,7 +14,7 @@ struct dirent;
 typedef size_t (*inode_read)(struct inode* file, char* buf, size_t buf_size, size_t offset, size_t n);
 typedef size_t (*inode_write)(struct inode* file, const char* buf, size_t offset, size_t n);
 typedef int (*inode_readdir)(struct inode* dir, struct dirent* entry, size_t i);
-typedef int (*inode_finddir)(struct inode* dir, struct dirent* entry, const char* filename);
+typedef struct inode* (*inode_findinode)(struct inode* dir, const char* filename);
 typedef int (*inode_mkfile)(struct inode* dir, const char* filename);
 typedef int (*inode_rmfile)(struct inode* dir, const char* filename);
 typedef int (*inode_mkdir)(struct inode* dir, const char* dirname);
@@ -29,7 +29,7 @@ struct inode_ops {
     inode_read read;
     inode_write write;
     inode_readdir readdir;
-    inode_finddir finddir;
+    inode_findinode findinode;
     inode_mkfile mkfile;
     inode_rmfile rmfile;
     inode_mkdir mkdir;
@@ -60,7 +60,7 @@ void init_vfs(void);
 size_t vfs_read(struct inode* file, char* buf, size_t buf_size, size_t offset, size_t n);
 size_t vfs_write(struct inode* file, const char* buf, size_t offset, size_t n);
 int vfs_readdir(struct inode* dir, struct dirent* entry, size_t i);
-int vfs_finddir(struct inode* dir, struct dirent* entry, const char* filename);
+struct inode* vfs_findinode(struct inode* dir, const char* filename);
 int vfs_mkfile(struct inode* dir, const char* filename);
 int vfs_rmfile(struct inode* dir, const char* filename);
 int vfs_mkdir(struct inode* dir, const char* dirname);

+ 6 - 1
include/types/list.hpp

@@ -118,7 +118,12 @@ public:
 
         pointer_type operator->() const noexcept
         {
-            return (static_cast<node_type*>(n))->value;
+            return &(static_cast<node_type*>(n))->value;
+        }
+
+        pointer_type ptr(void) const noexcept
+        {
+            return &(static_cast<node_type*>(n))->value;
         }
 
         node_base_type* _node(void) const noexcept

+ 11 - 1
src/kernel/stdio.c

@@ -412,7 +412,7 @@ snprintf(
     return n_write;
 }
 
-#define BYTES_PER_MAX_COPY_UNIT (sizeof(uint32_t)/sizeof(uint8_t))
+#define BYTES_PER_MAX_COPY_UNIT (sizeof(uint32_t) / sizeof(uint8_t))
 void* memcpy(void* dst, const void* src, size_t n)
 {
     void* orig_dst = dst;
@@ -448,3 +448,13 @@ size_t strlen(const char* str)
         ++n;
     return n;
 }
+
+int strcmp(const char* s1, const char* s2)
+{
+    int c;
+    while ((c = *s1 - *s2) == 0 && *s1 != 0) {
+        ++s1;
+        ++s2;
+    }
+    return c;
+}

+ 44 - 14
src/kernel/vfs.cpp

@@ -59,6 +59,7 @@ public:
     size_t read(struct inode* file, char* buf, size_t buf_size, size_t offset, size_t n);
     size_t write(struct inode* file, const char* buf, size_t offset, size_t n);
     int readdir(struct inode* dir, struct dirent* entry, size_t i);
+    struct inode* findinode(struct inode* dir, const char* filename);
 
     struct inode* root_inode(void)
     {
@@ -81,11 +82,11 @@ int tmpfs_readdir(struct inode* dir, struct dirent* entry, size_t i)
     auto* fs = static_cast<tmpfs*>(dir->fs->impl);
     return fs->readdir(dir, entry, i);
 }
-// int tmpfs_finddir(struct inode* dir, struct dirent* entry, const char* filename)
-// {
-//     auto* fs = static_cast<tmpfs*>(dir->fs->impl);
-//     return fs->finddir(dir, entry, filename);
-// }
+struct inode* tmpfs_findinode(struct inode* dir, const char* filename)
+{
+    auto* fs = static_cast<tmpfs*>(dir->fs->impl);
+    return fs->findinode(dir, filename);
+}
 int tmpfs_mkfile(struct inode* dir, const char* filename)
 {
     auto* fs = static_cast<tmpfs*>(dir->fs->impl);
@@ -101,7 +102,7 @@ int tmpfs_mkfile(struct inode* dir, const char* filename)
 int tmpfs_mkdir(struct inode* dir, const char* dirname)
 {
     auto* fs = static_cast<tmpfs*>(dir->fs->impl);
-    fs->mkfile(dir, dirname);
+    fs->mkdir(dir, dirname);
     return GB_OK;
 }
 
@@ -109,7 +110,7 @@ static const struct inode_ops tmpfs_inode_ops = {
     .read = tmpfs_read,
     .write = tmpfs_write,
     .readdir = tmpfs_readdir,
-    .finddir = 0,
+    .findinode = tmpfs_findinode,
     .mkfile = tmpfs_mkfile,
     .rmfile = 0,
     .mkdir = tmpfs_mkdir,
@@ -183,7 +184,9 @@ size_t tmpfs::write(struct inode* file, const char* buf, size_t offset, size_t n
 
     auto* data = static_cast<vector<char>*>(file->impl);
 
-    data->at(offset + n - 1) = 0x00;
+    for (size_t i = data->size(); i < offset + n; ++i) {
+        data->push_back(0);
+    }
     memcpy(data->data() + offset, buf, n);
 
     return n;
@@ -205,8 +208,22 @@ int tmpfs::readdir(struct inode* dir, struct dirent* entry, size_t i)
     return GB_OK;
 }
 
-// typedef int (*inode_finddir)(struct inode* dir, struct dirent* entry, const char* filename);
-// typedef int (*inode_rmfile)(struct inode* dir, const char* filename);
+struct inode* tmpfs::findinode(struct inode* dir, const char* filename)
+{
+    struct dirent ent { };
+    size_t i = 0;
+    while (readdir(dir, &ent, i) == GB_OK) {
+        if (strcmp(ent.name, filename) == 0) {
+            // optimize: use hash table to build an index
+            auto& inodes = static_cast<tmpfs*>(dir->fs->impl)->m_inodes;
+            for (auto iter = inodes.begin(); iter != inodes.end(); ++iter)
+                if (iter->ino == ent.ino)
+                    return iter.ptr();
+        }
+        ++i;
+    }
+    return nullptr;
+}
 
 size_t vfs_read(struct inode* file, char* buf, size_t buf_size, size_t offset, size_t n)
 {
@@ -232,12 +249,12 @@ int vfs_readdir(struct inode* dir, struct dirent* entry, size_t i)
         return 0;
     }
 }
-int vfs_finddir(struct inode* dir, struct dirent* entry, const char* filename)
+struct inode* vfs_findinode(struct inode* dir, const char* filename)
 {
-    if (dir->fs->ops->finddir) {
-        return dir->fs->ops->finddir(dir, entry, filename);
+    if (dir->fs->ops->findinode) {
+        return dir->fs->ops->findinode(dir, filename);
     } else {
-        return 0;
+        return nullptr;
     }
 }
 int vfs_mkfile(struct inode* dir, const char* filename)
@@ -276,6 +293,7 @@ void init_vfs(void)
     vfs_mkdir(fs_root, "root");
     vfs_mkfile(fs_root, "init");
 
+    tty_print(console, "/:\n");
     struct dirent ent { };
     int i = 0;
     char buf[256];
@@ -284,4 +302,16 @@ void init_vfs(void)
         tty_print(console, buf);
         ++i;
     }
+
+    auto* dev = vfs_findinode(fs_root, "dev");
+    vfs_mkfile(dev, "console");
+    auto* file_console = vfs_findinode(dev, "console");
+
+    tty_print(console, "/dev:\n");
+    i = 0;
+    while (vfs_readdir(dev, &ent, i) == GB_OK) {
+        snprintf(buf, 256, "%s: inode(%d)\n", ent.name, ent.ino);
+        tty_print(console, buf);
+        ++i;
+    }
 }