From c6aa2fe4ad47534b8bfde57c69d1d4549c3d6f30 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 11 Mar 2023 10:23:46 +0100 Subject: [PATCH] VFS: Populate the initial filesystem based on the initial ramdisk --- kernel/src/InitRD.cpp | 27 +++++++++++++++++++++++++++ kernel/src/InitRD.h | 1 + kernel/src/fs/VFS.cpp | 24 ++++++++++++++++-------- kernel/src/fs/VFS.h | 1 + kernel/src/main.cpp | 33 ++------------------------------- 5 files changed, 47 insertions(+), 39 deletions(-) diff --git a/kernel/src/InitRD.cpp b/kernel/src/InitRD.cpp index a661b817..37e3f210 100644 --- a/kernel/src/InitRD.cpp +++ b/kernel/src/InitRD.cpp @@ -1,6 +1,7 @@ #include "InitRD.h" #include "arch/MMU.h" #include "boot/bootboot.h" +#include "fs/VFS.h" TarStream g_initrd; extern const BOOTBOOT bootboot; @@ -11,3 +12,29 @@ void InitRD::initialize() g_initrd.initialize((void*)virtual_initrd_address, bootboot.initrd_size); } + +static Result vfs_create_dir_if_not_exists(const char* path) +{ + auto rc = VFS::create_directory(path); + if (rc.has_error()) + { + if (rc.error() == EEXIST) return {}; + return rc.release_error(); + } + return {}; +} + +Result InitRD::populate_vfs() +{ + TarStream::Entry entry; + while (TRY(g_initrd.read_next_entry(entry))) + { + if (entry.type == TarStream::EntryType::RegularFile) + { + auto file = TRY(VFS::create_file(entry.name)); + file->write(entry.data(), 0, entry.size); + } + else if (entry.type == TarStream::EntryType::Directory) { TRY(vfs_create_dir_if_not_exists(entry.name)); } + } + return {}; +} diff --git a/kernel/src/InitRD.h b/kernel/src/InitRD.h index 2eecf546..90d5d19c 100644 --- a/kernel/src/InitRD.h +++ b/kernel/src/InitRD.h @@ -6,4 +6,5 @@ extern TarStream g_initrd; namespace InitRD { void initialize(); + Result populate_vfs(); } diff --git a/kernel/src/fs/VFS.cpp b/kernel/src/fs/VFS.cpp index 5852b9d1..c63b4eb9 100644 --- a/kernel/src/fs/VFS.cpp +++ b/kernel/src/fs/VFS.cpp @@ -15,18 +15,12 @@ namespace VFS { auto parser = TRY(PathParser::create(path)); - kdbgln("vfs: trying to resolve path %s", path); - SharedPtr current_inode = root_fs->root_inode(); // FIXME: Properly handle relative paths. const char* section; - while (parser.next().try_set_value(section)) - { - kdbgln("vfs: searching for entry '%s' in inode %zu", section, current_inode->inode_number()); - current_inode = TRY(current_inode->find(section)); - } + while (parser.next().try_set_value(section)) { current_inode = TRY(current_inode->find(section)); } return current_inode; } @@ -40,8 +34,22 @@ namespace VFS auto child_name = TRY(parser.basename()); - kdbgln("vfs: creating directory '%s' in parent '%s'", child_name.chars(), parent_path.chars()); + // kdbgln("vfs: creating directory '%s' in parent '%s'", child_name.chars(), parent_path.chars()); return parent_inode->create_subdirectory(child_name.chars()); } + + Result> create_file(const char* path) + { + auto parser = TRY(PathParser::create(path)); + auto parent_path = TRY(parser.dirname()); + + auto parent_inode = TRY(resolve_path(parent_path.chars())); + + auto child_name = TRY(parser.basename()); + + // kdbgln("vfs: creating file '%s' in parent '%s'", child_name.chars(), parent_path.chars()); + + return parent_inode->create_file(child_name.chars()); + } } diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index c699d99a..b2e26326 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -79,6 +79,7 @@ namespace VFS Result> resolve_path(const char* path); Result> create_directory(const char* path); + Result> create_file(const char* path); Inode& root_inode(); } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 6d636928..eceebffd 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -51,37 +51,7 @@ static Result try_init_vfs() { VFS::root_fs = TRY(TmpFS::FileSystem::create()); - VFS::Inode& root_inode = VFS::root_inode(); - - kinfoln("root inode number: %zu", root_inode.inode_number()); - - kinfoln("root inode's '.' entry inode number: %zu", TRY(root_inode.find("."))->inode_number()); - kinfoln("root inode's '..' entry inode number: %zu", TRY(root_inode.find(".."))->inode_number()); - - TRY(VFS::create_directory("/etc/")); - - kinfoln("root inode's 'etc' entry inode number: %zu", TRY(root_inode.find("etc"))->inode_number()); - - auto& etc = *TRY(root_inode.find("etc")); - - kinfoln("etc inode's '.' entry inode number: %zu", TRY(etc.find("."))->inode_number()); - kinfoln("etc inode's '..' entry inode number: %zu", TRY(etc.find(".."))->inode_number()); - - TRY(etc.create_file("passwd")); - - kinfoln("etc inode's 'passwd' entry inode number: %zu", TRY(etc.find("passwd"))->inode_number()); - - auto& passwd = *TRY(VFS::resolve_path("/etc/passwd")); - - kinfoln("/etc/passwd's inode number: %zu", passwd.inode_number()); - - const char* data = "hello, world!"; - TRY(passwd.write((const u8*)data, 0, 14)); - - char output[14]; - TRY(passwd.read((u8*)output, 0, 14)); - - kinfoln("/etc/passwd contents: '%s'", output); + InitRD::populate_vfs(); return {}; } @@ -94,6 +64,7 @@ static void init_vfs() static Result try_init_userspace() { TarStream::Entry entry; + g_initrd.rewind(); while (TRY(g_initrd.read_next_entry(entry))) { if (entry.type == TarStream::EntryType::RegularFile)