diff options
| author | Lukas Oesch <lukasoesch20@gmail.com> | 2026-05-12 12:00:40 +0200 |
|---|---|---|
| committer | Lukas Oesch <lukasoesch20@gmail.com> | 2026-05-12 12:00:40 +0200 |
| commit | 91821da0110e05724640903434c3d85fc3d02466 (patch) | |
| tree | fd1e83b1ccab6603374f2c134c8a3691b83164c9 /kernel | |
| parent | fee33c0b2e2ab91a008bec16e143fba755b51974 (diff) | |
| download | kernel-91821da0110e05724640903434c3d85fc3d02466.tar.xz kernel-91821da0110e05724640903434c3d85fc3d02466.zip | |
if the boot_root_fs contains a /dev directory, vfs mounts the devfs onto the existing directory
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/include/kernel/filesystem/vfs.hpp | 3 | ||||
| -rw-r--r-- | kernel/src/filesystem/vfs.cpp | 40 | ||||
| -rw-r--r-- | kernel/src/filesystem/vfs.tests.cpp | 17 | ||||
| -rw-r--r-- | kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img | 2 |
4 files changed, 48 insertions, 14 deletions
diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 7e66fb7..b5053a2 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -1,6 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP +#include "kernel/filesystem/devfs/filesystem.hpp" #include <kernel/filesystem/dentry.hpp> #include <kernel/filesystem/filesystem.hpp> #include <kernel/filesystem/mount_table.hpp> @@ -80,6 +81,8 @@ namespace kernel::filesystem auto do_mount_internal(kstd::shared_ptr<dentry> const & mount_point_dentry, kstd::shared_ptr<filesystem> const & fs) -> void; + auto graft_persistent_device_fs(kstd::shared_ptr<devfs::filesystem> const & device_fs) -> void; + mount_table m_mount_table; }; } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index ee7c262..535f898 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -41,36 +41,35 @@ namespace kernel::filesystem auto vfs::init_internal() -> void { + // mount rootfs at / auto root_fs = kstd::make_shared<rootfs::filesystem>(); root_fs->mount(nullptr); auto root_fs_root_dentry = kstd::make_shared<dentry>(nullptr, root_fs->root_inode(), "/"); m_mount_table.add_mount(kstd::make_shared<mount>(nullptr, root_fs_root_dentry, root_fs, nullptr)); - // Mount devfs at /dev in rootfs (temporary, will be shadowed) + // mount devfs at /dev (inside rootfs, temporary, will be shadowed) auto device_fs = kstd::make_shared<devfs::filesystem>(); device_fs->mount(nullptr); - auto dev_mount_point_dentry = resolve_path("/dev"); - if (!dev_mount_point_dentry) + + if (auto dev_mount_point_dentry = resolve_path("/dev")) + { + do_mount_internal(dev_mount_point_dentry, device_fs); + } + else { kapi::system::panic("[FILESYSTEM] failed to resolve /dev for initial devfs mount."); } - do_mount_internal(dev_mount_point_dentry, device_fs); - // Mount boot filesystem at / (will shadow rootfs) + // mount boot fs at / (shadows rootfs), re-graft devfs if (auto boot_device_dentry = resolve_path("/dev/ram0")) { if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode())) { - do_mount_internal(root_fs_root_dentry, boot_root_fs); - - // Resolve / to get the boot root dentry - if (auto boot_root_dentry = resolve_path("/")) + if (auto root_dentry = resolve_path("/")) { - auto dev_dentry = kstd::make_shared<dentry>(boot_root_dentry, device_fs->root_inode(), "dev"); - boot_root_dentry->add_child(dev_dentry); - - do_mount_internal(dev_dentry, device_fs); + do_mount_internal(root_dentry, boot_root_fs); + graft_persistent_device_fs(device_fs); } } } @@ -151,6 +150,21 @@ namespace kernel::filesystem m_mount_table.add_mount(new_mount); } + auto vfs::graft_persistent_device_fs(kstd::shared_ptr<devfs::filesystem> const & device_fs) -> void + { + if (auto new_root_dentry = resolve_path("/")) + { + auto dev_dentry = new_root_dentry->find_child("dev"); + if (!dev_dentry) + { + dev_dentry = kstd::make_shared<dentry>(new_root_dentry, device_fs->root_inode(), "dev"); + new_root_dentry->add_child(dev_dentry); + } + + do_mount_internal(dev_dentry, device_fs); + } + } + auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr<dentry> { if (!path::is_valid_absolute_path(path)) diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 8e4cb70..add96aa 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -62,6 +62,23 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS } } + GIVEN("a real image file containing a /dev directory") + { + REQUIRE(std::filesystem::exists(image_path_2)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_2"}, {image_path_2})); + + THEN("vfs hides the image's /dev behind the devfs mount") + { + auto & vfs = kernel::filesystem::vfs::get(); + + auto image_1 = vfs.open("/dev/image_1.txt"); + REQUIRE(image_1 == nullptr); + + auto dev = vfs.open("/dev/ram0"); + REQUIRE(dev != nullptr); + } + } + GIVEN("three real image files") { REQUIRE(std::filesystem::exists(image_path_1)); diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img index 8327022..7f297f0 100644 --- a/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img +++ b/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a1d102f2e40083613060d43b2b32d31031137bbef99761a2d1bf4d38e155adb7 +oid sha256:6d9e872916e7d9107b321cc007e151899d5f19400a694666c0b24d482aef61ca size 5242880 |
