aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorLukas Oesch <lukasoesch20@gmail.com>2026-05-12 12:00:40 +0200
committerLukas Oesch <lukasoesch20@gmail.com>2026-05-12 12:00:40 +0200
commit91821da0110e05724640903434c3d85fc3d02466 (patch)
treefd1e83b1ccab6603374f2c134c8a3691b83164c9 /kernel
parentfee33c0b2e2ab91a008bec16e143fba755b51974 (diff)
downloadkernel-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.hpp3
-rw-r--r--kernel/src/filesystem/vfs.cpp40
-rw-r--r--kernel/src/filesystem/vfs.tests.cpp17
-rw-r--r--kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img2
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