diff options
| -rw-r--r-- | kernel/include/kernel/filesystem/dentry.hpp | 4 | ||||
| -rw-r--r-- | kernel/src/filesystem/dentry.cpp | 27 | ||||
| -rw-r--r-- | kernel/src/filesystem/dentry.tests.cpp | 39 | ||||
| -rw-r--r-- | kernel/src/filesystem/vfs.cpp | 4 |
4 files changed, 50 insertions, 24 deletions
diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index bd62735..226f2b9 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -34,7 +34,7 @@ namespace kernel::filesystem @param inode The associated inode for this dentry. @param name The name of the dentry (optional). */ - dentry(kstd::shared_ptr<dentry> const & parent, kstd::shared_ptr<inode> const & inode, std::string_view name = {}); + dentry(kstd::shared_ptr<dentry> const & parent, kstd::shared_ptr<inode> const & inode, std::string_view name); /** @brief Get the associated inode. @@ -58,7 +58,7 @@ namespace kernel::filesystem @brief Get the full path of the dentry by traversing up to the root. @return The full path of the dentry. */ - [[nodiscard]] auto get_full_path() const -> kstd::string; + [[nodiscard]] auto get_absolute_path() const -> kstd::string; /** @brief Add a @p child dentry. diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 1cf8730..a77ce23 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -22,6 +22,10 @@ namespace kernel::filesystem { kapi::system::panic("[FILESYSTEM] dentry constructed with null inode."); } + if (m_name.empty()) + { + kapi::system::panic("[FILESYSTEM] dentry constructed with empty name."); + } } auto dentry::get_inode() const -> kstd::shared_ptr<inode> const & @@ -39,20 +43,27 @@ namespace kernel::filesystem return m_name.view(); } - // NOLINTNEXTLINE(misc-no-recursion) - auto dentry::get_full_path() const -> kstd::string + auto dentry::get_absolute_path() const -> kstd::string { - if (m_parent) + kstd::string path = m_name; + + auto parent = m_parent; + while (parent) { - auto parent_path = m_parent->get_full_path(); - if (parent_path != "/") + auto parent_name = parent->m_name; + if (parent_name == "/") { - parent_path += '/'; + path = "/" + path; } - return parent_path + m_name.view(); + else + { + path = parent_name + "/" + path; + } + + parent = parent->m_parent; } - return m_name.view(); + return path; } auto dentry::add_child(kstd::shared_ptr<dentry> const & child) -> void diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index c42c405..dd01394 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -13,7 +13,7 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") GIVEN("A parent dentry and inode") { auto inode = kstd::make_shared<kernel::tests::filesystem::inode>(); - auto parent_dentry = kstd::make_shared<kernel::filesystem::dentry>(nullptr, inode); + auto parent_dentry = kstd::make_shared<kernel::filesystem::dentry>(nullptr, inode, "parent"); WHEN("constructing a dentry") { @@ -34,18 +34,9 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") WHEN("constructing a dentry with an empty name") { - auto child_dentry = kernel::filesystem::dentry{parent_dentry, inode}; - THEN("the dentry has the correct parent and inode, and an empty name") { - REQUIRE(child_dentry.get_parent() == parent_dentry); - REQUIRE(child_dentry.get_inode() == inode); - REQUIRE(child_dentry.get_name().empty()); - } - - THEN("no flag is set") - { - REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_THROWS_AS((kernel::filesystem::dentry{parent_dentry, inode, ""}), kernel::tests::cpu::halt); } } @@ -81,7 +72,7 @@ SCENARIO("Dentry child logic", "[filesystem][dentry]") GIVEN("A parent dentry and inode") { auto inode = kstd::make_shared<kernel::tests::filesystem::inode>(); - auto parent_dentry = kstd::make_shared<kernel::filesystem::dentry>(nullptr, inode); + auto parent_dentry = kstd::make_shared<kernel::filesystem::dentry>(nullptr, inode, "parent"); WHEN("adding child dentries") { @@ -133,3 +124,27 @@ SCENARIO("Dentry Flag logic", "[filesystem][dentry]") } } } + +SCENARIO("Dentry path resolution", "[filesystem][dentry]") +{ + GIVEN("A dentry with a parent hierarchy") + { + auto root_inode = kstd::make_shared<kernel::tests::filesystem::inode>(); + auto root_dentry = kstd::make_shared<kernel::filesystem::dentry>(nullptr, root_inode, "/"); + + auto home_inode = kstd::make_shared<kernel::tests::filesystem::inode>(); + auto home_dentry = kstd::make_shared<kernel::filesystem::dentry>(root_dentry, home_inode, "home"); + root_dentry->add_child(home_dentry); + + auto user_inode = kstd::make_shared<kernel::tests::filesystem::inode>(); + auto user_dentry = kstd::make_shared<kernel::filesystem::dentry>(home_dentry, user_inode, "user"); + home_dentry->add_child(user_dentry); + + THEN("the full path is constructed correctly") + { + REQUIRE(root_dentry->get_absolute_path() == "/"); + REQUIRE(home_dentry->get_absolute_path() == "/home"); + REQUIRE(user_dentry->get_absolute_path() == "/home/user"); + } + } +}
\ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 519550b..1410b2a 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -138,7 +138,7 @@ namespace kernel::filesystem auto vfs::do_mount_internal(kstd::shared_ptr<dentry> const & mount_point_dentry, kstd::shared_ptr<filesystem> const & fs) -> void { - auto mount_path = mount_point_dentry->get_full_path(); + auto mount_path = mount_point_dentry->get_absolute_path(); // TODO BA-FS26 refactoring, implement dentry lookup to get the parent mount... auto parent_mount = m_mount_table.find_longest_prefix_mount(mount_path.view()); @@ -216,7 +216,7 @@ namespace kernel::filesystem } else if (next_dentry->has_flag(dentry::dentry_flags::mounted)) { - current_mount = m_mount_table.find_exact_mount(next_dentry->get_full_path().view()); + current_mount = m_mount_table.find_exact_mount(next_dentry->get_absolute_path().view()); if (!current_mount) { kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); |
