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;
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:
SpinLock m_lock;

View File

@ -65,7 +65,7 @@ namespace Kernel
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());
for (MountPoint& mount : m_mount_points)
@ -74,6 +74,15 @@ namespace Kernel
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)
{
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,11 +123,11 @@ 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))
if (auto* mount_point = mount_from_host_inode(inode))
inode = mount_point->target->root_inode();
}
}
if (canonical_path.empty())
TRY(canonical_path.push_back('/'));