From 9c32495771901e5a8a668aa45801c89daacd5ec4 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 22 Aug 2026 22:32:32 +0200 Subject: kernel/fs: prepare for driver state extraction --- kernel/kernel/filesystem/devfs/filesystem.cpp | 5 ++--- kernel/kernel/filesystem/devfs/filesystem.hpp | 2 +- .../kernel/filesystem/devfs/filesystem.tests.cpp | 22 ++++++++++----------- kernel/kernel/filesystem/ext2/filesystem.cpp | 6 ++++-- kernel/kernel/filesystem/ext2/filesystem.hpp | 2 +- kernel/kernel/filesystem/ext2/mount_state.hpp | 23 ++++++++++++++++++++++ kernel/kernel/filesystem/filesystem.hpp | 5 ++++- kernel/kernel/filesystem/mount.cpp | 19 ++++++++++-------- kernel/kernel/filesystem/mount.hpp | 11 +++++++++-- kernel/kernel/filesystem/mount.tests.cpp | 2 +- kernel/kernel/filesystem/rootfs/filesystem.cpp | 5 ++--- kernel/kernel/filesystem/rootfs/filesystem.hpp | 2 +- .../kernel/filesystem/rootfs/filesystem.tests.cpp | 6 +++--- kernel/kernel/filesystem/vfs.cpp | 23 ++++++++++++---------- .../kernel/test_support/filesystem/filesystem.cpp | 6 +++--- .../kernel/test_support/filesystem/filesystem.hpp | 2 +- 16 files changed, 90 insertions(+), 51 deletions(-) create mode 100644 kernel/kernel/filesystem/ext2/mount_state.hpp diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp index 5d8ef7f2..60d174fe 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.cpp @@ -48,8 +48,7 @@ namespace kernel::filesystem::devfs [[gnu::used]] constexpr auto registration = type_registration{}; - auto filesystem::mount(kstd::shared_ptr const &) - -> kstd::result> + auto filesystem::mount(kstd::shared_ptr const &) -> kstd::result { m_root_inode = kstd::make_shared(); @@ -62,7 +61,7 @@ namespace kernel::filesystem::devfs device_number_registry::get().subscribe(shared_from_this()); - return m_root_inode; + return mount_result{m_root_inode, nullptr}; } auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const diff --git a/kernel/kernel/filesystem/devfs/filesystem.hpp b/kernel/kernel/filesystem/devfs/filesystem.hpp index accc8a49..875f3957 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/kernel/filesystem/devfs/filesystem.hpp @@ -31,7 +31,7 @@ namespace kernel::filesystem::devfs device_number_registry_observer { auto mount(kstd::shared_ptr const & backing_inode) - -> kstd::result> override; + -> kstd::result override; [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const -> kstd::result> override; diff --git a/kernel/kernel/filesystem/devfs/filesystem.tests.cpp b/kernel/kernel/filesystem/devfs/filesystem.tests.cpp index 7a0de2d9..20523b71 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.tests.cpp @@ -34,14 +34,14 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, THEN("lookup on root finds ram0 device inode") { - auto inode = fs->lookup(*root, "ram0"); + auto inode = fs->lookup(root->first, "ram0"); REQUIRE(inode); REQUIRE(inode.value()->is_device()); } THEN("lookup of an unknown device returns error") { - auto inode = fs->lookup(*root, "ram99"); + auto inode = fs->lookup(root->first, "ram99"); REQUIRE(!inode); } @@ -51,13 +51,13 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, auto other_root = other_fs->mount(nullptr); CHECK(other_root); - auto inode = fs->lookup(*other_root, "ram0"); + auto inode = fs->lookup(other_root->first, "ram0"); REQUIRE(!inode); } THEN("lookup with a non-directory parent returns error") { - auto non_directory_inode = fs->lookup(*root, "ram0"); + auto non_directory_inode = fs->lookup(root->first, "ram0"); REQUIRE(non_directory_inode); REQUIRE_FALSE(non_directory_inode.value()->is_directory()); @@ -67,7 +67,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, THEN("create_inode always returns an error") { - auto result = fs->create_inode(*root, "new_device", kapi::filesystem::file_type::regular); + auto result = fs->create_inode(root->first, "new_device", kapi::filesystem::file_type::regular); REQUIRE(!result); } } @@ -82,9 +82,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, THEN("lookup finds all generated RAM devices") { - REQUIRE(fs->lookup(*root, "ram0")); - REQUIRE(fs->lookup(*root, "ram1")); - REQUIRE(fs->lookup(*root, "ram2")); + REQUIRE(fs->lookup(root->first, "ram0")); + REQUIRE(fs->lookup(root->first, "ram1")); + REQUIRE(fs->lookup(root->first, "ram2")); } } } @@ -100,7 +100,7 @@ SCENARIO("Devfs filesystem updates", "[filesystem][devfs]") auto bus = kstd::make_shared("devfs_live_update_bus"); kapi::devices::get_root_bus()->add_child(bus); - REQUIRE_FALSE(fs->lookup(*root, "devfs_live_update_device_node")); + REQUIRE_FALSE(fs->lookup(root->first, "devfs_live_update_device_node")); WHEN("a device is attached, bound, and published") { @@ -113,7 +113,7 @@ SCENARIO("Devfs filesystem updates", "[filesystem][devfs]") THEN("devfs finds it immediately") { - REQUIRE(fs->lookup(*root, "devfs_live_update_device_node")); + REQUIRE(fs->lookup(root->first, "devfs_live_update_device_node")); } WHEN("the device is detached") @@ -122,7 +122,7 @@ SCENARIO("Devfs filesystem updates", "[filesystem][devfs]") THEN("devfs does not find it anymore") { - REQUIRE_FALSE(fs->lookup(*root, "devfs_live_update_device_node")); + REQUIRE_FALSE(fs->lookup(root->first, "devfs_live_update_device_node")); } } } diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index 115f6028..a0a0dbf1 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -106,7 +107,7 @@ namespace kernel::filesystem::ext2 } auto filesystem::mount(kstd::shared_ptr const & backing_inode) - -> kstd::result> + -> kstd::result { m_backing_inode = backing_inode; @@ -146,7 +147,8 @@ namespace kernel::filesystem::ext2 return kstd::failure(ext2_errc::invalid_root_inode); } - return root; + return mount_result{*root, + kstd::make_shared(m_superblock, m_block_group_descriptors, m_backing_inode)}; } auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp index 23629928..fd304c00 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/kernel/filesystem/ext2/filesystem.hpp @@ -76,7 +76,7 @@ namespace kernel::filesystem::ext2 struct filesystem final : kernel::filesystem::filesystem { auto mount(kstd::shared_ptr const & backing_inode) - -> kstd::result> override; + -> kstd::result override; [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const -> kstd::result> override; diff --git a/kernel/kernel/filesystem/ext2/mount_state.hpp b/kernel/kernel/filesystem/ext2/mount_state.hpp new file mode 100644 index 00000000..b9c2d5f7 --- /dev/null +++ b/kernel/kernel/filesystem/ext2/mount_state.hpp @@ -0,0 +1,23 @@ +#ifndef TEACHOS_KERNEL_FILESYSTEM_EXT2_MOUNT_STATE_HPP +#define TEACHOS_KERNEL_FILESYSTEM_EXT2_MOUNT_STATE_HPP + +#include +#include +#include + +#include +#include + +namespace kernel::filesystem::ext2 +{ + + struct mount_state + { + struct superblock superblock; + kstd::vector block_group_descriptors; + kstd::shared_ptr backing_inode; + }; + +} // namespace kernel::filesystem::ext2 + +#endif \ No newline at end of file diff --git a/kernel/kernel/filesystem/filesystem.hpp b/kernel/kernel/filesystem/filesystem.hpp index cae36967..83f9b54d 100644 --- a/kernel/kernel/filesystem/filesystem.hpp +++ b/kernel/kernel/filesystem/filesystem.hpp @@ -12,6 +12,7 @@ #include #include +#include namespace kernel::filesystem { @@ -21,6 +22,8 @@ namespace kernel::filesystem //! Filesystem implementations must derive from this class. struct filesystem { + using mount_result = std::pair, kstd::shared_ptr>; + //! Virtual destructor enabling polymorphic destruction. virtual ~filesystem() = default; @@ -37,7 +40,7 @@ namespace kernel::filesystem //! //! @param backing_inode The inode to use as the backing inode for the filesystem. //! @return The root inode of the mounted filesystem on success, and error otherwise. - virtual auto mount(kstd::shared_ptr const & backing_inode) -> kstd::result> = 0; + virtual auto mount(kstd::shared_ptr const & backing_inode) -> kstd::result = 0; //! Find a child inode below the given parent inode with the specified name. //! diff --git a/kernel/kernel/filesystem/mount.cpp b/kernel/kernel/filesystem/mount.cpp index 2f0e0d58..d808ff52 100644 --- a/kernel/kernel/filesystem/mount.cpp +++ b/kernel/kernel/filesystem/mount.cpp @@ -15,12 +15,13 @@ namespace kernel::filesystem { mount::mount(dentry_ptr const & mount_dentry, dentry_ptr const & root_dentry, filesystem_ptr const & fs, - mount_ptr const & parent_mount, mount_ptr const & source_mount) + mount_ptr const & parent_mount, mount_ptr const & source_mount, kstd::shared_ptr driver_data) : m_mount_dentry(mount_dentry) , m_root_dentry(root_dentry) , m_filesystem(fs) , m_parent_mount(parent_mount) , m_source_mount(source_mount) + , m_driver_data(driver_data) , m_ref_count(0) { if (!m_filesystem) @@ -30,15 +31,15 @@ namespace kernel::filesystem } auto mount::attach(dentry_ptr const & mount_dentry, filesystem_ptr const & fs, - kstd::shared_ptr const & root_inode, mount_ptr const & parent_mount, - mount_ptr const & source_mount) -> mount_ptr + kstd::shared_ptr const & root_inode, kstd::shared_ptr driver_data, + mount_ptr const & parent_mount, mount_ptr const & source_mount) -> mount_ptr { auto root_dentry = mount_dentry ? kstd::make_shared(mount_dentry->parent(), root_inode, mount_dentry->name()) : kstd::make_shared(nullptr, root_inode, "/"); auto instance = mount_ptr{ - new mount{mount_dentry, root_dentry, fs, parent_mount, source_mount} + new mount{mount_dentry, root_dentry, fs, parent_mount, source_mount, driver_data} }; root_inode->set_owning_mount(instance); @@ -55,13 +56,15 @@ namespace kernel::filesystem kapi::system::panic("[OS:FS] Tried to mount a null filesystem!"); } - auto root_inode = fs->mount(backing_inode); - if (!root_inode) + auto mount_result = fs->mount(backing_inode); + if (!mount_result) { - return kstd::failure(root_inode.error()); + return kstd::failure(mount_result.error()); } - auto instance = attach(mount_dentry, fs, *root_inode, parent_mount, source_mount); + auto [root_inode, driver_data] = *mount_result; + + auto instance = attach(mount_dentry, fs, root_inode, driver_data, parent_mount, source_mount); instance->m_backing_inode = backing_inode; return instance; diff --git a/kernel/kernel/filesystem/mount.hpp b/kernel/kernel/filesystem/mount.hpp index ac6dae21..e8d9cf6a 100644 --- a/kernel/kernel/filesystem/mount.hpp +++ b/kernel/kernel/filesystem/mount.hpp @@ -28,10 +28,12 @@ namespace kernel::filesystem //! @param mount_dentry The directory entry where the filesystem is mounted. //! @param fs The filesystem instance being mounted. //! @param root_inode The backing inode for the filesystem, must not be null. + //! @param driver_data The filesystem specific driver data. //! @param parent_mount The parent mount which contains the mount_dentry. //! @param source_mount The mount that the filesystem originates from. auto static attach(dentry_ptr const & mount_dentry, filesystem_ptr const & fs, inode_ptr const & root_inode, - mount_ptr const & parent_mount, mount_ptr const & source_mount) -> mount_ptr; + kstd::shared_ptr driver_data, mount_ptr const & parent_mount, + mount_ptr const & source_mount) -> mount_ptr; //! Create a new mount with the given parameters. //! @@ -64,6 +66,9 @@ namespace kernel::filesystem //! Get the source mount where this mount originates from. [[nodiscard]] auto source_mount() const -> mount_ptr; + //! Get the data of the attached filesystem driver. + [[nodiscard]] auto driver_data() const -> kstd::shared_ptr; + //! Increment the reference count for this mount. auto increment_ref_count() -> void; @@ -90,8 +95,9 @@ namespace kernel::filesystem //! @param fs The filesystem instance being mounted. //! @param parent_mount The parent mount which contains the mount_dentry. //! @param source_mount The mount that the filesystem originates from. + //! @param driver_data The driver specific state data. mount(dentry_ptr const & mount_dentry, dentry_ptr const & root_dentry, filesystem_ptr const & fs, - mount_ptr const & parent_mount, mount_ptr const & source_mount); + mount_ptr const & parent_mount, mount_ptr const & source_mount, kstd::shared_ptr driver_data); dentry_ptr m_mount_dentry{}; dentry_ptr m_root_dentry{}; @@ -99,6 +105,7 @@ namespace kernel::filesystem inode_ptr m_backing_inode{}; mount_ptr m_parent_mount{}; kstd::weak_ptr m_source_mount{}; + kstd::shared_ptr m_driver_data{}; std::atomic_size_t m_ref_count{0}; }; } // namespace kernel::filesystem diff --git a/kernel/kernel/filesystem/mount.tests.cpp b/kernel/kernel/filesystem/mount.tests.cpp index 2c67a7cb..a77134e5 100644 --- a/kernel/kernel/filesystem/mount.tests.cpp +++ b/kernel/kernel/filesystem/mount.tests.cpp @@ -22,7 +22,7 @@ SCENARIO("Mount construction", "[filesystem][mount]") WHEN("attaching a mount with no mount point") { - auto mount = kernel::filesystem::mount::attach(nullptr, fs, root_inode, nullptr, nullptr); + auto mount = kernel::filesystem::mount::attach(nullptr, fs, root_inode, nullptr, nullptr, nullptr); THEN("the mount has the correct filesystem, root dentry, mount dentry, and mount path") { diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp index e7a05d55..298e8c94 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp @@ -45,11 +45,10 @@ namespace kernel::filesystem::rootfs [[gnu::used]] constexpr auto registration = type_registration{}; - auto filesystem::mount(kstd::shared_ptr const &) - -> kstd::result> + auto filesystem::mount(kstd::shared_ptr const &) -> kstd::result { auto root = kstd::make_shared(); - return root; + return mount_result{root, nullptr}; } auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) const diff --git a/kernel/kernel/filesystem/rootfs/filesystem.hpp b/kernel/kernel/filesystem/rootfs/filesystem.hpp index 5a2a93c0..9f609106 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.hpp @@ -26,7 +26,7 @@ namespace kernel::filesystem::rootfs { //! @copydoc kernel::filesystem::filesystem::mount auto mount(kstd::shared_ptr const & backing_inode) - -> kstd::result> override; + -> kstd::result override; //! @copydoc kernel::filesystem::filesystem::lookup. //! @return Always returns an error, as rootfs is always empty. diff --git a/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp b/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp index cbf8f744..b4297582 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp @@ -24,9 +24,9 @@ SCENARIO("Rootfs filesystem mount and lookup", "[filesystem][rootfs][filesystem] THEN("looking up a non-existent directory returns an error") { - auto non_existent_inode_1 = fs.lookup(*root, ""); + auto non_existent_inode_1 = fs.lookup(root->first, ""); REQUIRE(!non_existent_inode_1); - auto non_existent_inode_2 = fs.lookup(*root, "nonexistent"); + auto non_existent_inode_2 = fs.lookup(root->first, "nonexistent"); REQUIRE(!non_existent_inode_2); } @@ -38,7 +38,7 @@ SCENARIO("Rootfs filesystem mount and lookup", "[filesystem][rootfs][filesystem] THEN("create_inode always returns an error") { - auto result = fs.create_inode(*root, "new_device", kapi::filesystem::file_type::directory); + auto result = fs.create_inode(root->first, "new_device", kapi::filesystem::file_type::directory); REQUIRE(!result); } } diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index c39a28c4..6a15d211 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -60,13 +60,15 @@ namespace kernel::filesystem } auto root_fs = (*root_fs_descriptor)->make_instance(); - auto root_fs_root_inode = root_fs->mount(nullptr); - if (!root_fs_root_inode) + auto root_mount_result = root_fs->mount(nullptr); + if (!root_mount_result) { - kapi::system::panic("[FILESYSTEM] failed to mount root FS", root_fs_root_inode.error()); + kapi::system::panic("[FILESYSTEM] failed to mount root FS", root_mount_result.error()); } - auto root_mount = mount::attach(nullptr, root_fs, *root_fs_root_inode, nullptr, nullptr); + auto [root_inode, root_state] = *root_mount_result; + + auto root_mount = mount::attach(nullptr, root_fs, root_inode, root_state, nullptr, nullptr); m_mount_table.add_mount(root_mount); // mount devfs at /dev (inside rootfs, temporary, will be shadowed) @@ -77,12 +79,13 @@ namespace kernel::filesystem } auto device_fs = (*device_fs_descriptor)->make_instance(); - auto device_fs_root_inode = device_fs->mount(nullptr); - if (!device_fs_root_inode) + auto device_fs_mount_result = device_fs->mount(nullptr); + if (!device_fs_mount_result) { - kapi::system::panic("[FILESYSTEM] failed to mount device FS", device_fs_root_inode.error()); + kapi::system::panic("[FILESYSTEM] failed to mount device FS", device_fs_mount_result.error()); } - graft_persistent_device_fs(device_fs, *device_fs_root_inode); + + graft_persistent_device_fs(device_fs, device_fs_mount_result->first); // mount boot fs at / (shadows rootfs), re-graft devfs auto [boot_device_dentry, boot_device_mount_context] = @@ -100,7 +103,7 @@ namespace kernel::filesystem kapi::system::panic("[OS:FS] failed to mount boot FS", mount.error()); } m_mount_table.add_mount(*mount); - graft_persistent_device_fs(device_fs, *device_fs_root_inode); + graft_persistent_device_fs(device_fs, device_fs_mount_result->first); } } } @@ -320,7 +323,7 @@ namespace kernel::filesystem root_mount_point_dentry->add_child(dev_dentry); } - auto new_mount = mount::attach(dev_dentry, device_fs, root_inode, root_mount, nullptr); + auto new_mount = mount::attach(dev_dentry, device_fs, root_inode, nullptr, root_mount, nullptr); m_mount_table.add_mount(new_mount); } } diff --git a/kernel/kernel/test_support/filesystem/filesystem.cpp b/kernel/kernel/test_support/filesystem/filesystem.cpp index 51ce1e9f..8bd46e3c 100644 --- a/kernel/kernel/test_support/filesystem/filesystem.cpp +++ b/kernel/kernel/test_support/filesystem/filesystem.cpp @@ -11,13 +11,13 @@ #include #include +#include namespace kernel::tests::filesystem { - auto filesystem::mount(kstd::shared_ptr const &) - -> kstd::result> + auto filesystem::mount(kstd::shared_ptr const &) -> kstd::result { - return kstd::make_shared(); + return std::pair{kstd::make_shared(), nullptr}; } auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) const diff --git a/kernel/kernel/test_support/filesystem/filesystem.hpp b/kernel/kernel/test_support/filesystem/filesystem.hpp index fa03f176..d7f64883 100644 --- a/kernel/kernel/test_support/filesystem/filesystem.hpp +++ b/kernel/kernel/test_support/filesystem/filesystem.hpp @@ -20,7 +20,7 @@ namespace kernel::tests::filesystem filesystem() = default; auto mount(kstd::shared_ptr const & backing_inode) - -> kstd::result> override; + -> kstd::result override; [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const -> kstd::result> override; -- cgit v1.2.3