Kernel: Fix traversing back from mount points

This commit is contained in:
Bananymous 2023-04-01 01:54:35 +03:00
parent 8988ce2766
commit 7a6b1c8e47
2 changed files with 17 additions and 6 deletions

View File

@ -35,7 +35,8 @@ namespace Kernel
File host; File host;
FileSystem* target; FileSystem* target;
}; };
MountPoint* mount_point_for_inode(BAN::RefPtr<Inode>); MountPoint* mount_from_host_inode(BAN::RefPtr<Inode>);
MountPoint* mount_from_root_inode(BAN::RefPtr<Inode>);
private: private:
SpinLock m_lock; SpinLock m_lock;

View File

@ -65,7 +65,7 @@ namespace Kernel
return {}; return {};
} }
VirtualFileSystem::MountPoint* VirtualFileSystem::mount_point_for_inode(BAN::RefPtr<Inode> inode) VirtualFileSystem::MountPoint* VirtualFileSystem::mount_from_host_inode(BAN::RefPtr<Inode> inode)
{ {
ASSERT(m_lock.is_locked()); ASSERT(m_lock.is_locked());
for (MountPoint& mount : m_mount_points) for (MountPoint& mount : m_mount_points)
@ -74,6 +74,15 @@ namespace Kernel
return nullptr; return nullptr;
} }
VirtualFileSystem::MountPoint* VirtualFileSystem::mount_from_root_inode(BAN::RefPtr<Inode> 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> VirtualFileSystem::file_from_absolute_path(BAN::StringView path) BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_absolute_path(BAN::StringView path)
{ {
LockGuard _(m_lock); LockGuard _(m_lock);
@ -96,13 +105,14 @@ namespace Kernel
} }
else if (path_part == ".."sv) 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)); inode = TRY(mount_point->host.inode->read_directory_inode(".."sv));
else else
inode = TRY(inode->read_directory_inode(".."sv)); inode = TRY(inode->read_directory_inode(".."sv));
if (!canonical_path.empty()) if (!canonical_path.empty())
{ {
ASSERT(canonical_path.front() == '/');
while (canonical_path.back() != '/') while (canonical_path.back() != '/')
canonical_path.pop_back(); canonical_path.pop_back();
canonical_path.pop_back(); canonical_path.pop_back();
@ -113,10 +123,10 @@ namespace Kernel
inode = TRY(inode->read_directory_inode(path_part)); inode = TRY(inode->read_directory_inode(path_part));
TRY(canonical_path.push_back('/')); TRY(canonical_path.push_back('/'));
TRY(canonical_path.append(path_part)); TRY(canonical_path.append(path_part));
}
if (auto* mount_point = mount_point_for_inode(inode)) if (auto* mount_point = mount_from_host_inode(inode))
inode = mount_point->target->root_inode(); inode = mount_point->target->root_inode();
}
} }
if (canonical_path.empty()) if (canonical_path.empty())