diff options
| -rw-r--r-- | kernel/kernel/filesystem/devfs/filesystem.cpp | 5 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/devfs/filesystem.hpp | 4 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/devfs/filesystem.tests.cpp | 37 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/filesystem.cpp | 16 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/filesystem.hpp | 3 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/filesystem.tests.cpp | 34 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/inode.tests.cpp | 10 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/filesystem.cpp | 23 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/filesystem.hpp | 15 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/rootfs/filesystem.cpp | 7 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/rootfs/filesystem.hpp | 3 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/rootfs/filesystem.tests.cpp | 11 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/vfs.cpp | 37 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/vfs.hpp | 6 | ||||
| -rw-r--r-- | kernel/kernel/test_support/filesystem/filesystem.cpp | 6 | ||||
| -rw-r--r-- | kernel/kernel/test_support/filesystem/filesystem.hpp | 3 |
16 files changed, 118 insertions, 102 deletions
diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp index 92756a65..5d8ef7f2 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.cpp @@ -48,7 +48,8 @@ namespace kernel::filesystem::devfs [[gnu::used]] constexpr auto registration = type_registration<type>{}; - auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> kstd::result<void> + auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) + -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> { m_root_inode = kstd::make_shared<inode>(); @@ -61,7 +62,7 @@ namespace kernel::filesystem::devfs device_number_registry::get().subscribe(shared_from_this()); - return kstd::success(); + return m_root_inode; } auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const diff --git a/kernel/kernel/filesystem/devfs/filesystem.hpp b/kernel/kernel/filesystem/devfs/filesystem.hpp index 2b0221d0..accc8a49 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/kernel/filesystem/devfs/filesystem.hpp @@ -30,7 +30,8 @@ namespace kernel::filesystem::devfs kstd::enable_shared_from_this<filesystem>, device_number_registry_observer { - auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> kstd::result<void> override; + auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) + -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override; [[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override; @@ -46,6 +47,7 @@ namespace kernel::filesystem::devfs auto on_device_numbered(device_number_registry::entry const & numbered) -> void override; auto on_device_unnumbered(device_number_registry::entry const & numbered) -> void override; + kstd::shared_ptr<kernel::filesystem::inode> m_root_inode{}; kstd::flat_map<kstd::string, kstd::shared_ptr<device_inode>> m_inodes{}; }; } // namespace kernel::filesystem::devfs diff --git a/kernel/kernel/filesystem/devfs/filesystem.tests.cpp b/kernel/kernel/filesystem/devfs/filesystem.tests.cpp index b5a07a22..7a0de2d9 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.tests.cpp @@ -25,39 +25,39 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, setup_modules(1); auto fs = kstd::make_shared<kernel::filesystem::devfs::filesystem>(); - auto result = fs->mount(nullptr); + auto root = fs->mount(nullptr); THEN("mount succeeds") { - REQUIRE(result); - REQUIRE(fs->root_inode()); + REQUIRE(root); } THEN("lookup on root finds ram0 device inode") { - auto inode = fs->lookup(fs->root_inode(), "ram0"); + auto inode = fs->lookup(*root, "ram0"); REQUIRE(inode); REQUIRE(inode.value()->is_device()); } THEN("lookup of an unknown device returns error") { - auto inode = fs->lookup(fs->root_inode(), "ram99"); + auto inode = fs->lookup(*root, "ram99"); REQUIRE(!inode); } THEN("lookup with wrong parent returns error") { auto other_fs = kstd::make_shared<kernel::filesystem::devfs::filesystem>(); - CHECK(other_fs->mount(nullptr)); + auto other_root = other_fs->mount(nullptr); + CHECK(other_root); - auto inode = fs->lookup(other_fs->root_inode(), "ram0"); + auto inode = fs->lookup(*other_root, "ram0"); REQUIRE(!inode); } THEN("lookup with a non-directory parent returns error") { - auto non_directory_inode = fs->lookup(fs->root_inode(), "ram0"); + auto non_directory_inode = fs->lookup(*root, "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(fs->root_inode(), "new_device", kapi::filesystem::file_type::regular); + auto result = fs->create_inode(*root, "new_device", kapi::filesystem::file_type::regular); REQUIRE(!result); } } @@ -77,14 +77,14 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, setup_modules(3, 2048); auto fs = kstd::make_shared<kernel::filesystem::devfs::filesystem>(); - auto result = fs->mount(nullptr); - REQUIRE(result); + auto root = fs->mount(nullptr); + REQUIRE(root); THEN("lookup finds all generated RAM devices") { - REQUIRE(fs->lookup(fs->root_inode(), "ram0")); - REQUIRE(fs->lookup(fs->root_inode(), "ram1")); - REQUIRE(fs->lookup(fs->root_inode(), "ram2")); + REQUIRE(fs->lookup(*root, "ram0")); + REQUIRE(fs->lookup(*root, "ram1")); + REQUIRE(fs->lookup(*root, "ram2")); } } } @@ -94,12 +94,13 @@ SCENARIO("Devfs filesystem updates", "[filesystem][devfs]") GIVEN("A mounted devfs, and a bus attached to the root without a device attached") { auto fs = kstd::make_shared<kernel::filesystem::devfs::filesystem>(); - REQUIRE(fs->mount(nullptr)); + auto root = fs->mount(nullptr); + REQUIRE(root); auto bus = kstd::make_shared<kapi::devices::bus>("devfs_live_update_bus"); kapi::devices::get_root_bus()->add_child(bus); - REQUIRE_FALSE(fs->lookup(fs->root_inode(), "devfs_live_update_device_node")); + REQUIRE_FALSE(fs->lookup(*root, "devfs_live_update_device_node")); WHEN("a device is attached, bound, and published") { @@ -112,7 +113,7 @@ SCENARIO("Devfs filesystem updates", "[filesystem][devfs]") THEN("devfs finds it immediately") { - REQUIRE(fs->lookup(fs->root_inode(), "devfs_live_update_device_node")); + REQUIRE(fs->lookup(*root, "devfs_live_update_device_node")); } WHEN("the device is detached") @@ -121,7 +122,7 @@ SCENARIO("Devfs filesystem updates", "[filesystem][devfs]") THEN("devfs does not find it anymore") { - REQUIRE_FALSE(fs->lookup(fs->root_inode(), "devfs_live_update_device_node")); + REQUIRE_FALSE(fs->lookup(*root, "devfs_live_update_device_node")); } } } diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index fcccad8f..c5808a60 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -27,7 +27,6 @@ #include <optional> #include <span> #include <string_view> -#include <tuple> #include <utility> using namespace kstd::units_literals; @@ -106,9 +105,10 @@ namespace kernel::filesystem::ext2 }; } - auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> kstd::result<void> + auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) + -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> { - std::ignore = kernel::filesystem::filesystem::mount(backing_inode); + m_backing_inode = backing_inode; if (auto read_result = m_backing_inode->read(std::as_writable_bytes(std::span{&m_superblock, 1}), constants::superblock_offset); @@ -134,17 +134,19 @@ namespace kernel::filesystem::ext2 return kstd::failure(read_result.error()); } - if (auto root_inode = read_inode(constants::root_inode_number)) + auto root = read_inode(constants::root_inode_number); + + if (!root) { - m_root_inode = root_inode.value(); + return kstd::failure(root.error()); } - if (!m_root_inode || !m_root_inode->is_directory()) + if (!(*root)->is_directory()) { return kstd::failure(ext2_errc::invalid_root_inode); } - return {}; + return root; } auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp index d70358fd..f53e74da 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/kernel/filesystem/ext2/filesystem.hpp @@ -75,7 +75,8 @@ namespace kernel::filesystem::ext2 //! The Second Extended Filesystem (ext2) struct filesystem final : kernel::filesystem::filesystem { - auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> kstd::result<void> override; + auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) + -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override; [[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override; diff --git a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp index 51ba2f30..bf7c89ae 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp @@ -48,17 +48,18 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device); auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(dev_inode)); + auto root = fs.mount(dev_inode); + REQUIRE(root); THEN("the root inode is available and is a directory") { - REQUIRE(fs.root_inode()); - REQUIRE(fs.root_inode()->is_directory()); + REQUIRE(*root); + REQUIRE((*root)->is_directory()); } THEN("lookup resolves known entries from the image") { - auto information = fs.lookup(fs.root_inode(), "information"); + auto information = fs.lookup(*root, "information"); REQUIRE(information); REQUIRE(information.value()->is_directory()); @@ -71,13 +72,13 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, { REQUIRE(!fs.lookup(nullptr, "information")); - auto information = fs.lookup(fs.root_inode(), "information"); + auto information = fs.lookup(*root, "information"); REQUIRE(information); auto info_1 = fs.lookup(*information, "info_1.txt"); REQUIRE(info_1); REQUIRE(!fs.lookup(*info_1, "anything")); - REQUIRE(!fs.lookup(fs.root_inode(), "does_not_exist")); + REQUIRE(!fs.lookup(*root, "does_not_exist")); } } } @@ -98,37 +99,38 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device); auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(dev_inode)); + auto root = fs.mount(dev_inode); + REQUIRE(root); THEN("a file can be created") { - auto lookup_result = fs.lookup(fs.root_inode(), "blub"); + auto lookup_result = fs.lookup(*root, "blub"); REQUIRE(!lookup_result); - auto new_inode = fs.create_inode(fs.root_inode(), "blub", kapi::filesystem::file_type::regular); + auto new_inode = fs.create_inode(*root, "blub", kapi::filesystem::file_type::regular); REQUIRE(new_inode); REQUIRE(new_inode.value()->is_regular()); - lookup_result = fs.lookup(fs.root_inode(), "blub"); + lookup_result = fs.lookup(*root, "blub"); REQUIRE(lookup_result); } THEN("a directory can be created") { - auto lookup_result = fs.lookup(fs.root_inode(), "blub"); + auto lookup_result = fs.lookup(*root, "blub"); REQUIRE(!lookup_result); - auto new_directory = fs.create_inode(fs.root_inode(), "blub", kapi::filesystem::file_type::directory); + auto new_directory = fs.create_inode(*root, "blub", kapi::filesystem::file_type::directory); REQUIRE(new_directory); REQUIRE(new_directory.value()->is_directory()); - lookup_result = fs.lookup(fs.root_inode(), "blub"); + lookup_result = fs.lookup(*root, "blub"); REQUIRE(lookup_result); } THEN("a directory and a file within can be created") { - auto new_directory = fs.create_inode(fs.root_inode(), "blub", kapi::filesystem::file_type::directory); + auto new_directory = fs.create_inode(*root, "blub", kapi::filesystem::file_type::directory); REQUIRE(new_directory); auto new_file = fs.create_inode(new_directory.value(), "blub_file", kapi::filesystem::file_type::regular); @@ -141,7 +143,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, THEN("a file can be created and written to") { - auto new_inode = fs.create_inode(fs.root_inode(), "blub", kapi::filesystem::file_type::regular); + auto new_inode = fs.create_inode(*root, "blub", kapi::filesystem::file_type::regular); REQUIRE(new_inode); auto buffer = @@ -160,7 +162,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, THEN("a symbolic link is not implemented yet") { - REQUIRE_THROWS_AS(fs.create_inode(fs.root_inode(), "blub", kapi::filesystem::file_type::symbolic_link), + REQUIRE_THROWS_AS(fs.create_inode(*root, "blub", kapi::filesystem::file_type::symbolic_link), kernel::tests::cpu::halt); } } diff --git a/kernel/kernel/filesystem/ext2/inode.tests.cpp b/kernel/kernel/filesystem/ext2/inode.tests.cpp index 13e9d414..d110c16a 100644 --- a/kernel/kernel/filesystem/ext2/inode.tests.cpp +++ b/kernel/kernel/filesystem/ext2/inode.tests.cpp @@ -109,9 +109,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device); auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(dev_inode)); + auto root = fs.mount(dev_inode); + REQUIRE(root); - auto information = fs.lookup(fs.root_inode(), "information"); + auto information = fs.lookup(*root, "information"); REQUIRE(information); auto file = fs.lookup(*information, "info_1.txt"); REQUIRE(file); @@ -303,9 +304,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device); auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(dev_inode)); + auto root = fs.mount(dev_inode); + REQUIRE(root); - auto information = fs.lookup(fs.root_inode(), "information"); + auto information = fs.lookup(*root, "information"); REQUIRE(information); auto file = fs.lookup(*information, "info_1.txt"); REQUIRE(file); diff --git a/kernel/kernel/filesystem/filesystem.cpp b/kernel/kernel/filesystem/filesystem.cpp index 84bbdef6..1d222888 100644 --- a/kernel/kernel/filesystem/filesystem.cpp +++ b/kernel/kernel/filesystem/filesystem.cpp @@ -8,11 +8,13 @@ #include <kstd/result.hpp> #include <kstd/system_error.hpp> +#include <utility> + namespace kernel::filesystem { auto filesystem::probe_and_mount(kstd::shared_ptr<inode> const & backing_inode) - -> kstd::result<kstd::shared_ptr<filesystem>> + -> kstd::result<std::pair<kstd::shared_ptr<filesystem>, kstd::shared_ptr<inode>>> { for (auto & type : type_registry::get().all()) { @@ -22,27 +24,18 @@ namespace kernel::filesystem } auto fs = type->make_instance(); - - if (fs->mount(backing_inode)) + auto root = fs->mount(backing_inode); + if (!root) { - return fs; + continue; } + + return std::pair{fs, *root}; } return kstd::failure(vfs_errc::unsupported_filesystem); } - auto filesystem::mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::result<void> - { - m_backing_inode = backing_inode; - return kstd::success(); - } - - auto filesystem::root_inode() const -> kstd::shared_ptr<inode> const & - { - return m_root_inode; - } - auto filesystem::backing_inode() const -> kstd::shared_ptr<inode> const & { return m_backing_inode; diff --git a/kernel/kernel/filesystem/filesystem.hpp b/kernel/kernel/filesystem/filesystem.hpp index 1a66c11c..f18422b2 100644 --- a/kernel/kernel/filesystem/filesystem.hpp +++ b/kernel/kernel/filesystem/filesystem.hpp @@ -12,6 +12,7 @@ #include <optional> #include <string_view> +#include <utility> namespace kernel::filesystem { @@ -29,9 +30,9 @@ namespace kernel::filesystem //! @warning This function panics if @p backing_inode is null. //! //! @param backing_inode The inode to probe and mount. - //! @return A pointer to the mounted filesystem instance on success, an error otherwise. + //! @return A pointer to the mounted filesystem and the root of it on success, an error otherwise. auto static probe_and_mount(kstd::shared_ptr<inode> const & backing_inode) - -> kstd::result<kstd::shared_ptr<filesystem>>; + -> kstd::result<std::pair<kstd::shared_ptr<filesystem>, kstd::shared_ptr<inode>>>; //! Initializes the filesystem with the given inode. //! @@ -39,8 +40,8 @@ namespace kernel::filesystem //! filesystem data (e.g. a file on an already mounted filesystem). //! //! @param backing_inode The inode to use as the backing inode for the filesystem. - //! @return Nothing on success, and error otherwise. - virtual auto mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::result<void>; + //! @return The root inode of the mounted filesystem on success, and error otherwise. + virtual auto mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::result<kstd::shared_ptr<inode>> = 0; //! Find a child inode below the given parent inode with the specified name. //! @@ -65,18 +66,12 @@ namespace kernel::filesystem std::optional<kapi::filesystem::device_number> raw_device = std::nullopt) -> kstd::result<kstd::shared_ptr<inode>> = 0; - //! Get the root inode of the file system. - //! - //! @return A reference to the root inode. - [[nodiscard]] auto root_inode() const -> kstd::shared_ptr<inode> const &; - //! Get the backing inode of the file system. //! //! @return A reference to the backing inode. [[nodiscard]] auto backing_inode() const -> kstd::shared_ptr<inode> const &; protected: - kstd::shared_ptr<inode> m_root_inode{}; kstd::shared_ptr<inode> m_backing_inode{}; }; diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp index cccfa63c..e7a05d55 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp @@ -45,10 +45,11 @@ namespace kernel::filesystem::rootfs [[gnu::used]] constexpr auto registration = type_registration<type>{}; - auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> kstd::result<void> + auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) + -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> { - m_root_inode = kstd::make_shared<inode>(); - return kstd::success(); + auto root = kstd::make_shared<inode>(); + return root; } auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const &, std::string_view) const diff --git a/kernel/kernel/filesystem/rootfs/filesystem.hpp b/kernel/kernel/filesystem/rootfs/filesystem.hpp index 2a861747..5a2a93c0 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.hpp @@ -25,7 +25,8 @@ namespace kernel::filesystem::rootfs struct filesystem : kernel::filesystem::filesystem { //! @copydoc kernel::filesystem::filesystem::mount - auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> kstd::result<void> override; + auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) + -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> 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 ba1aab0e..cbf8f744 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp @@ -15,19 +15,18 @@ SCENARIO("Rootfs filesystem mount and lookup", "[filesystem][rootfs][filesystem] GIVEN("a mounted rootfs filesystem") { auto fs = kernel::filesystem::rootfs::filesystem{}; - auto result = fs.mount(nullptr); + auto root = fs.mount(nullptr); THEN("the filesystem can be mounted successfully") { - REQUIRE(result); - REQUIRE(fs.root_inode()); + REQUIRE(root); } THEN("looking up a non-existent directory returns an error") { - auto non_existent_inode_1 = fs.lookup(fs.root_inode(), ""); + auto non_existent_inode_1 = fs.lookup(*root, ""); REQUIRE(!non_existent_inode_1); - auto non_existent_inode_2 = fs.lookup(fs.root_inode(), "nonexistent"); + auto non_existent_inode_2 = fs.lookup(*root, "nonexistent"); REQUIRE(!non_existent_inode_2); } @@ -39,7 +38,7 @@ SCENARIO("Rootfs filesystem mount and lookup", "[filesystem][rootfs][filesystem] THEN("create_inode always returns an error") { - auto result = fs.create_inode(fs.root_inode(), "new_device", kapi::filesystem::file_type::directory); + auto result = fs.create_inode(*root, "new_device", kapi::filesystem::file_type::directory); REQUIRE(!result); } } diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index 02c577f2..57ae6c70 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -60,12 +60,13 @@ namespace kernel::filesystem } auto root_fs = (*root_fs_descriptor)->make_instance(); - if (auto result = root_fs->mount(nullptr); !result) + auto root_fs_root_inode = root_fs->mount(nullptr); + if (!root_fs_root_inode) { - kapi::system::panic("[FILESYSTEM] failed to mount root FS", result.error()); + kapi::system::panic("[FILESYSTEM] failed to mount root FS", root_fs_root_inode.error()); } - auto root_fs_root_dentry = kstd::make_shared<dentry>(nullptr, root_fs->root_inode(), "/"); + auto root_fs_root_dentry = kstd::make_shared<dentry>(nullptr, *root_fs_root_inode, "/"); auto root_mount = kstd::make_shared<struct mount>(nullptr, root_fs_root_dentry, root_fs, nullptr, nullptr); m_mount_table.add_mount(root_mount); @@ -77,23 +78,26 @@ namespace kernel::filesystem } auto device_fs = (*device_fs_descriptor)->make_instance(); - if (auto result = device_fs->mount(nullptr); !result) + auto device_fs_root_inode = device_fs->mount(nullptr); + if (!device_fs_root_inode) { - kapi::system::panic("[FILESYSTEM] failed to mount device FS", result.error()); + kapi::system::panic("[FILESYSTEM] failed to mount device FS", device_fs_root_inode.error()); } - graft_persistent_device_fs(device_fs); + graft_persistent_device_fs(device_fs, *device_fs_root_inode); // mount boot fs at / (shadows rootfs), re-graft devfs auto [boot_device_dentry, boot_device_mount_context] = resolve_path_internal("/dev/ram0").value_or(std::pair{nullptr, nullptr}); if (boot_device_dentry && boot_device_mount_context) { - if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode())) + if (auto result = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode())) { + auto [boot_root_fs, boot_root_fs_root_inode] = *result; + if (auto root_dentry = resolve_path("/")) { - do_mount_internal(*root_dentry, root_mount, *boot_root_fs, boot_device_mount_context); - graft_persistent_device_fs(device_fs); + do_mount_internal(*root_dentry, root_mount, boot_root_fs, boot_root_fs_root_inode, boot_device_mount_context); + graft_persistent_device_fs(device_fs, *device_fs_root_inode); } } } @@ -183,7 +187,8 @@ namespace kernel::filesystem return kstd::failure(fs.error()); } - do_mount_internal(mount_point_dentry, mount_context, *fs, source_mount_context); + auto [filesystem, root_inode] = *fs; + do_mount_internal(mount_point_dentry, mount_context, filesystem, root_inode, source_mount_context); return kstd::success(); } @@ -295,15 +300,15 @@ namespace kernel::filesystem } auto vfs::do_mount_internal(dentry_ptr const & mount_point_dentry, mount_ptr const & parent_mount, fs_ptr const & fs, - mount_ptr const & source_mount) -> void + kstd::shared_ptr<inode> const & root_inode, mount_ptr const & source_mount) -> void { - auto new_fs_root = - kstd::make_shared<dentry>(mount_point_dentry->parent(), fs->root_inode(), mount_point_dentry->name()); + auto new_fs_root = kstd::make_shared<dentry>(mount_point_dentry->parent(), root_inode, mount_point_dentry->name()); auto new_mount = kstd::make_shared<struct mount>(mount_point_dentry, new_fs_root, fs, parent_mount, source_mount); m_mount_table.add_mount(new_mount); } - auto vfs::graft_persistent_device_fs(kstd::shared_ptr<filesystem> const & device_fs) -> void + auto vfs::graft_persistent_device_fs(kstd::shared_ptr<filesystem> const & device_fs, + kstd::shared_ptr<inode> const & root_inode) -> void { auto [root_mount_point_dentry, root_mount] = resolve_path_internal("/").value_or(std::pair{nullptr, nullptr}); if (root_mount_point_dentry && root_mount) @@ -311,11 +316,11 @@ namespace kernel::filesystem auto dev_dentry = root_mount_point_dentry->find_child("dev"); if (!dev_dentry) { - dev_dentry = kstd::make_shared<dentry>(root_mount_point_dentry, device_fs->root_inode(), "dev"); + dev_dentry = kstd::make_shared<dentry>(root_mount_point_dentry, root_inode, "dev"); root_mount_point_dentry->add_child(dev_dentry); } - do_mount_internal(dev_dentry, root_mount, device_fs); + do_mount_internal(dev_dentry, root_mount, device_fs, root_inode); } } diff --git a/kernel/kernel/filesystem/vfs.hpp b/kernel/kernel/filesystem/vfs.hpp index 2f30539b..0f29608c 100644 --- a/kernel/kernel/filesystem/vfs.hpp +++ b/kernel/kernel/filesystem/vfs.hpp @@ -112,9 +112,11 @@ namespace kernel::filesystem [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::result<mount_ptr>; auto do_mount_internal(dentry_ptr const & mount_point_dentry, mount_ptr const & parent_mount, fs_ptr const & fs, - mount_ptr const & source_mount = nullptr) -> void; + kstd::shared_ptr<inode> const & root_inode, mount_ptr const & source_mount = nullptr) + -> void; - auto graft_persistent_device_fs(kstd::shared_ptr<filesystem> const & device_fs) -> void; + auto graft_persistent_device_fs(kstd::shared_ptr<filesystem> const & device_fs, + kstd::shared_ptr<inode> const & root_inode) -> void; auto create_inode(std::string_view path, kapi::filesystem::file_type type, std::optional<kapi::filesystem::device_number> raw_device = std::nullopt) -> kstd::result<void>; diff --git a/kernel/kernel/test_support/filesystem/filesystem.cpp b/kernel/kernel/test_support/filesystem/filesystem.cpp index cd08f961..51ce1e9f 100644 --- a/kernel/kernel/test_support/filesystem/filesystem.cpp +++ b/kernel/kernel/test_support/filesystem/filesystem.cpp @@ -14,6 +14,12 @@ namespace kernel::tests::filesystem { + auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) + -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> + { + return kstd::make_shared<inode>(); + } + auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const &, std::string_view) const -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> { diff --git a/kernel/kernel/test_support/filesystem/filesystem.hpp b/kernel/kernel/test_support/filesystem/filesystem.hpp index 7aa14a9f..fa03f176 100644 --- a/kernel/kernel/test_support/filesystem/filesystem.hpp +++ b/kernel/kernel/test_support/filesystem/filesystem.hpp @@ -19,6 +19,9 @@ namespace kernel::tests::filesystem { filesystem() = default; + auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) + -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override; + [[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override; |
