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 "InitRD.h"
#include "arch/MMU.h" #include "arch/MMU.h"
#include "boot/bootboot.h" #include "boot/bootboot.h"
#include "fs/VFS.h"
TarStream g_initrd; TarStream g_initrd;
extern const BOOTBOOT bootboot; extern const BOOTBOOT bootboot;
@ -11,3 +12,29 @@ void InitRD::initialize()
g_initrd.initialize((void*)virtual_initrd_address, bootboot.initrd_size); 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 namespace InitRD
{ {
void initialize(); void initialize();
Result<void> populate_vfs();
} }

View File

@ -15,18 +15,12 @@ namespace VFS
{ {
auto parser = TRY(PathParser::create(path)); auto parser = TRY(PathParser::create(path));
kdbgln("vfs: trying to resolve path %s", path);
SharedPtr<Inode> current_inode = root_fs->root_inode(); SharedPtr<Inode> current_inode = root_fs->root_inode();
// FIXME: Properly handle relative paths. // FIXME: Properly handle relative paths.
const char* section; const char* section;
while (parser.next().try_set_value(section)) while (parser.next().try_set_value(section)) { current_inode = TRY(current_inode->find(section)); }
{
kdbgln("vfs: searching for entry '%s' in inode %zu", section, current_inode->inode_number());
current_inode = TRY(current_inode->find(section));
}
return current_inode; return current_inode;
} }
@ -40,8 +34,22 @@ namespace VFS
auto child_name = TRY(parser.basename()); 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()); 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>> resolve_path(const char* path);
Result<SharedPtr<Inode>> create_directory(const char* path); Result<SharedPtr<Inode>> create_directory(const char* path);
Result<SharedPtr<Inode>> create_file(const char* path);
Inode& root_inode(); Inode& root_inode();
} }

View File

@ -51,37 +51,7 @@ static Result<void> try_init_vfs()
{ {
VFS::root_fs = TRY(TmpFS::FileSystem::create()); VFS::root_fs = TRY(TmpFS::FileSystem::create());
VFS::Inode& root_inode = VFS::root_inode(); InitRD::populate_vfs();
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);
return {}; return {};
} }
@ -94,6 +64,7 @@ static void init_vfs()
static Result<void> try_init_userspace() static Result<void> try_init_userspace()
{ {
TarStream::Entry entry; TarStream::Entry entry;
g_initrd.rewind();
while (TRY(g_initrd.read_next_entry(entry))) while (TRY(g_initrd.read_next_entry(entry)))
{ {
if (entry.type == TarStream::EntryType::RegularFile) if (entry.type == TarStream::EntryType::RegularFile)