forked from Bananymous/banan-os
Kernel: add basic support for symlinks
This commit is contained in:
parent
0ccc23d544
commit
232fdcb82c
|
@ -141,10 +141,13 @@ namespace Kernel
|
||||||
|
|
||||||
virtual BAN::StringView name() const override { return m_name; }
|
virtual BAN::StringView name() const override { return m_name; }
|
||||||
|
|
||||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
virtual BAN::ErrorOr<BAN::String> link_target() override;
|
||||||
|
|
||||||
virtual BAN::ErrorOr<BAN::Vector<BAN::String>> read_directory_entries(size_t) override;
|
virtual BAN::ErrorOr<BAN::Vector<BAN::String>> read_directory_entries(size_t) override;
|
||||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> read_directory_inode(BAN::StringView) override;
|
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> read_directory_inode(BAN::StringView) override;
|
||||||
|
|
||||||
|
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||||
|
|
||||||
virtual BAN::ErrorOr<void> create_file(BAN::StringView, mode_t) override;
|
virtual BAN::ErrorOr<void> create_file(BAN::StringView, mode_t) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -78,6 +78,8 @@ namespace Kernel
|
||||||
|
|
||||||
virtual BAN::StringView name() const = 0;
|
virtual BAN::StringView name() const = 0;
|
||||||
|
|
||||||
|
virtual BAN::ErrorOr<BAN::String> link_target() { ASSERT_NOT_REACHED(); }
|
||||||
|
|
||||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> read_directory_inode(BAN::StringView) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> read_directory_inode(BAN::StringView) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
||||||
virtual BAN::ErrorOr<BAN::Vector<BAN::String>> read_directory_entries(size_t) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
virtual BAN::ErrorOr<BAN::Vector<BAN::String>> read_directory_entries(size_t) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace Kernel
|
||||||
BAN::RefPtr<Inode> inode;
|
BAN::RefPtr<Inode> inode;
|
||||||
BAN::String canonical_path;
|
BAN::String canonical_path;
|
||||||
};
|
};
|
||||||
BAN::ErrorOr<File> file_from_absolute_path(BAN::StringView);
|
BAN::ErrorOr<File> file_from_absolute_path(BAN::StringView, bool follow_links);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VirtualFileSystem() = default;
|
VirtualFileSystem() = default;
|
||||||
|
@ -39,7 +39,7 @@ namespace Kernel
|
||||||
MountPoint* mount_from_root_inode(BAN::RefPtr<Inode>);
|
MountPoint* mount_from_root_inode(BAN::RefPtr<Inode>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpinLock m_lock;
|
RecursiveSpinLock m_lock;
|
||||||
FileSystem* m_root_fs = nullptr;
|
FileSystem* m_root_fs = nullptr;
|
||||||
BAN::Vector<MountPoint> m_mount_points;
|
BAN::Vector<MountPoint> m_mount_points;
|
||||||
};
|
};
|
||||||
|
|
|
@ -247,6 +247,14 @@ namespace Kernel
|
||||||
ASSERT_NOT_REACHED();
|
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)
|
BAN::ErrorOr<size_t> Ext2Inode::read(size_t offset, void* buffer, size_t count)
|
||||||
{
|
{
|
||||||
// FIXME: update atime if needed
|
// FIXME: update atime if needed
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> VirtualFileSystem::mount(BAN::StringView partition, BAN::StringView target)
|
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)
|
if (partition_file.inode->inode_type() != Inode::InodeType::Device)
|
||||||
return BAN::Error::from_errno(ENOTBLK);
|
return BAN::Error::from_errno(ENOTBLK);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> VirtualFileSystem::mount(FileSystem* file_system, BAN::StringView path)
|
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())
|
if (!file.inode->mode().ifdir())
|
||||||
return BAN::Error::from_errno(ENOTDIR);
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ namespace Kernel
|
||||||
return nullptr;
|
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);
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
|
@ -124,6 +124,28 @@ namespace Kernel
|
||||||
|
|
||||||
if (auto* mount_point = mount_from_host_inode(inode))
|
if (auto* mount_point = mount_from_host_inode(inode))
|
||||||
inode = mount_point->target->root_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::String absolute_path = TRY(absolute_path_of(path));
|
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);
|
LockGuard _(m_lock);
|
||||||
int fd = TRY(get_free_fd());
|
int fd = TRY(get_free_fd());
|
||||||
|
@ -421,7 +421,7 @@ namespace Kernel
|
||||||
auto directory = absolute_path.sv().substring(0, index);
|
auto directory = absolute_path.sv().substring(0, index);
|
||||||
auto file_name = absolute_path.sv().substring(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));
|
TRY(parent_file.inode->create_file(file_name, mode));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -510,7 +510,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
BAN::String absolute_path = TRY(absolute_path_of(path));
|
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())
|
if (!file.inode->mode().ifdir())
|
||||||
return BAN::Error::from_errno(ENOTDIR);
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue