VFS: Populate the initial filesystem based on the initial ramdisk

This commit is contained in:
apio 2023-03-11 10:23:46 +01:00
parent ac304073b4
commit c6aa2fe4ad
Signed by: apio
GPG Key ID: B8A7D06E42258954
5 changed files with 47 additions and 39 deletions

View File

@ -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<void> 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<void> 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 {};
}

View File

@ -6,4 +6,5 @@ extern TarStream g_initrd;
namespace InitRD
{
void initialize();
Result<void> populate_vfs();
}

View File

@ -15,18 +15,12 @@ namespace VFS
{
auto parser = TRY(PathParser::create(path));
kdbgln("vfs: trying to resolve path %s", path);
SharedPtr<Inode> 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<SharedPtr<Inode>> 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());
}
}

View File

@ -79,6 +79,7 @@ namespace VFS
Result<SharedPtr<Inode>> resolve_path(const char* path);
Result<SharedPtr<Inode>> create_directory(const char* path);
Result<SharedPtr<Inode>> create_file(const char* path);
Inode& root_inode();
}

View File

@ -51,37 +51,7 @@ static Result<void> 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<void> try_init_userspace()
{
TarStream::Entry entry;
g_initrd.rewind();
while (TRY(g_initrd.read_next_entry(entry)))
{
if (entry.type == TarStream::EntryType::RegularFile)