From 7a6b1c8e47aea0fb1033f8beeefb40755067fdff Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 1 Apr 2023 01:54:35 +0300 Subject: [PATCH] Kernel: Fix traversing back from mount points --- kernel/include/kernel/FS/VirtualFileSystem.h | 3 ++- kernel/kernel/FS/VirtualFileSystem.cpp | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/kernel/include/kernel/FS/VirtualFileSystem.h b/kernel/include/kernel/FS/VirtualFileSystem.h index 49e0b324..d74bfcfb 100644 --- a/kernel/include/kernel/FS/VirtualFileSystem.h +++ b/kernel/include/kernel/FS/VirtualFileSystem.h @@ -35,7 +35,8 @@ namespace Kernel File host; FileSystem* target; }; - MountPoint* mount_point_for_inode(BAN::RefPtr); + MountPoint* mount_from_host_inode(BAN::RefPtr); + MountPoint* mount_from_root_inode(BAN::RefPtr); private: SpinLock m_lock; diff --git a/kernel/kernel/FS/VirtualFileSystem.cpp b/kernel/kernel/FS/VirtualFileSystem.cpp index 0ddb3d9a..7549d175 100644 --- a/kernel/kernel/FS/VirtualFileSystem.cpp +++ b/kernel/kernel/FS/VirtualFileSystem.cpp @@ -65,7 +65,7 @@ namespace Kernel return {}; } - VirtualFileSystem::MountPoint* VirtualFileSystem::mount_point_for_inode(BAN::RefPtr inode) + VirtualFileSystem::MountPoint* VirtualFileSystem::mount_from_host_inode(BAN::RefPtr inode) { ASSERT(m_lock.is_locked()); for (MountPoint& mount : m_mount_points) @@ -74,6 +74,15 @@ namespace Kernel return nullptr; } + VirtualFileSystem::MountPoint* VirtualFileSystem::mount_from_root_inode(BAN::RefPtr inode) + { + ASSERT(m_lock.is_locked()); + for (MountPoint& mount : m_mount_points) + if (*mount.target->root_inode() == *inode) + return &mount; + return nullptr; + } + BAN::ErrorOr VirtualFileSystem::file_from_absolute_path(BAN::StringView path) { LockGuard _(m_lock); @@ -96,13 +105,14 @@ namespace Kernel } else if (path_part == ".."sv) { - if (auto* mount_point = mount_point_for_inode(inode)) + if (auto* mount_point = mount_from_root_inode(inode)) inode = TRY(mount_point->host.inode->read_directory_inode(".."sv)); else inode = TRY(inode->read_directory_inode(".."sv)); if (!canonical_path.empty()) { + ASSERT(canonical_path.front() == '/'); while (canonical_path.back() != '/') canonical_path.pop_back(); canonical_path.pop_back(); @@ -113,10 +123,10 @@ namespace Kernel inode = TRY(inode->read_directory_inode(path_part)); TRY(canonical_path.push_back('/')); TRY(canonical_path.append(path_part)); - } - if (auto* mount_point = mount_point_for_inode(inode)) - inode = mount_point->target->root_inode(); + if (auto* mount_point = mount_from_host_inode(inode)) + inode = mount_point->target->root_inode(); + } } if (canonical_path.empty())