diff options
Diffstat (limited to 'kernel/src/filesystem/mount_table.cpp')
| -rw-r--r-- | kernel/src/filesystem/mount_table.cpp | 81 |
1 files changed, 16 insertions, 65 deletions
diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 965e83b..daef93e 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -7,42 +7,11 @@ #include <kstd/vector> #include <algorithm> -#include <cstddef> #include <ranges> #include <string_view> namespace kernel::filesystem { - namespace - { - auto is_descendant_of(kstd::shared_ptr<mount> const & candidate, kstd::shared_ptr<mount> const & ancestor) -> bool - { - for (auto current = candidate; current; current = current->get_parent_mount()) - { - if (current == ancestor) - { - return true; - } - } - - return false; - } - - auto is_strict_prefix(std::string_view prefix, std::string_view path) -> bool - { - return prefix != "/" && path.starts_with(prefix) && path.size() > prefix.size() && path[prefix.size()] == '/'; - } - - auto is_visible_mount(kstd::shared_ptr<mount> const & candidate, - kstd::vector<kstd::shared_ptr<mount>> const & mounts) -> bool - { - return std::ranges::none_of(mounts, [&](auto const & other) { - return other != candidate && is_strict_prefix(other->get_mount_path(), candidate->get_mount_path()) && - !is_descendant_of(candidate, other); - }); - } - } // namespace - auto mount_table::has_child_mounts(kstd::shared_ptr<mount> const & parent_mount) const -> bool { return std::ranges::any_of( @@ -52,19 +21,24 @@ namespace kernel::filesystem void mount_table::add_mount(kstd::shared_ptr<mount> const & mount) { m_mounts.push_back(mount); + if (auto mount_dentry = mount->get_mount_dentry()) { - mount_dentry->set_flag(dentry::dentry_flags::mounted); + mount_dentry->set_flag(dentry::dentry_flags::is_mount_point); + } + if (auto root_dentry = mount->get_root_dentry()) + { + root_dentry->set_flag(dentry::dentry_flags::is_mount_root); } } auto mount_table::remove_mount(std::string_view path) -> operation_result { - auto mount_it = std::ranges::find_if(std::ranges::reverse_view(m_mounts), [&](auto const & mount) { - return mount->get_mount_path() == path && is_visible_mount(mount, m_mounts); - }); + auto mount_range = + std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); + auto mount_it = mount_range.begin(); - if (mount_it == std::ranges::reverse_view(m_mounts).end()) + if (mount_it == m_mounts.end()) { return operation_result::mount_not_found; } @@ -75,39 +49,16 @@ namespace kernel::filesystem return operation_result::has_child_mounts; } - mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::mounted); - m_mounts.erase(std::ranges::find(m_mounts, mount)); + mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::is_mount_point); + m_mounts.erase(mount_it); return operation_result::removed; } - auto mount_table::find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr<mount> - { - kstd::shared_ptr<mount> mount_with_longest_prefix = nullptr; - std::size_t best_len = 0; - - for (auto const & mount : m_mounts) - { - auto mp = mount->get_mount_path(); - - // /a/b/c should match /a/b but not /a/bb or /a/b/c/d, / should match everything - bool is_prefix = path.starts_with(mp) && (mp == "/" || path.size() == mp.size() || path[mp.size()] == '/'); - bool visible = is_visible_mount(mount, m_mounts); - - if (is_prefix && visible && mp.size() >= best_len) - { - mount_with_longest_prefix = mount; - best_len = mp.size(); - } - } - - return mount_with_longest_prefix; - } - auto mount_table::find_exact_mount(std::string_view path) const -> kstd::shared_ptr<mount> { - auto reversed_mounts = std::ranges::reverse_view(m_mounts); - auto mount_it = - std::ranges::find_if(reversed_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); - return (mount_it != reversed_mounts.end()) ? *mount_it : nullptr; + auto mount_range = + std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); + auto mount_it = mount_range.begin(); + return (mount_it != m_mounts.end()) ? *mount_it : nullptr; } } // namespace kernel::filesystem
\ No newline at end of file |
