Kernel: add basic support for symlinks

This commit is contained in:
Bananymous
2023-06-01 00:24:45 +03:00
parent 79d1f665f2
commit 835d32814d
6 changed files with 44 additions and 9 deletions

View File

@@ -247,6 +247,14 @@ namespace Kernel
ASSERT_NOT_REACHED();
}
BAN::ErrorOr<BAN::String> Ext2Inode::link_target()
{
ASSERT(mode().iflnk());
if (m_inode.size < sizeof(m_inode.block))
return BAN::String((const char*)m_inode.block);
ASSERT_NOT_REACHED();
}
BAN::ErrorOr<size_t> Ext2Inode::read(size_t offset, void* buffer, size_t count)
{
// FIXME: update atime if needed

View File

@@ -40,7 +40,7 @@ namespace Kernel
BAN::ErrorOr<void> VirtualFileSystem::mount(BAN::StringView partition, BAN::StringView target)
{
auto partition_file = TRY(file_from_absolute_path(partition));
auto partition_file = TRY(file_from_absolute_path(partition, true));
if (partition_file.inode->inode_type() != Inode::InodeType::Device)
return BAN::Error::from_errno(ENOTBLK);
@@ -54,7 +54,7 @@ namespace Kernel
BAN::ErrorOr<void> VirtualFileSystem::mount(FileSystem* file_system, BAN::StringView path)
{
auto file = TRY(file_from_absolute_path(path));
auto file = TRY(file_from_absolute_path(path, true));
if (!file.inode->mode().ifdir())
return BAN::Error::from_errno(ENOTDIR);
@@ -82,7 +82,7 @@ namespace Kernel
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, bool follow_links)
{
LockGuard _(m_lock);
@@ -124,6 +124,28 @@ namespace Kernel
if (auto* mount_point = mount_from_host_inode(inode))
inode = mount_point->target->root_inode();
if (follow_links && inode->mode().iflnk())
{
auto target = TRY(inode->link_target());
if (target.empty())
return BAN::Error::from_errno(ENOENT);
if (target.front() == '/')
{
File file = TRY(file_from_absolute_path(target, follow_links));
inode = file.inode;
canonical_path = BAN::move(file.canonical_path);
}
else
{
while (canonical_path.back() != '/')
canonical_path.pop_back();
TRY(canonical_path.append(target));
File file = TRY(file_from_absolute_path(canonical_path, follow_links));
inode = file.inode;
canonical_path = BAN::move(file.canonical_path);
}
}
}
}

View File

@@ -301,7 +301,7 @@ namespace Kernel
BAN::String absolute_path = TRY(absolute_path_of(path));
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(absolute_path));
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(absolute_path, !(flags & O_NOFOLLOW)));
LockGuard _(m_lock);
int fd = TRY(get_free_fd());
@@ -421,7 +421,7 @@ namespace Kernel
auto directory = absolute_path.sv().substring(0, index);
auto file_name = absolute_path.sv().substring(index);
auto parent_file = TRY(VirtualFileSystem::get().file_from_absolute_path(directory));
auto parent_file = TRY(VirtualFileSystem::get().file_from_absolute_path(directory, true));
TRY(parent_file.inode->create_file(file_name, mode));
return {};
@@ -510,7 +510,7 @@ namespace Kernel
{
BAN::String absolute_path = TRY(absolute_path_of(path));
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(absolute_path));
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(absolute_path, true));
if (!file.inode->mode().ifdir())
return BAN::Error::from_errno(ENOTDIR);