Kernel: Rewrite mounting code

This commit is contained in:
Bananymous
2023-03-29 21:34:48 +03:00
parent 10e0c90fde
commit ab3cdea548
14 changed files with 121 additions and 144 deletions

View File

@@ -45,7 +45,7 @@ namespace Kernel
MUST(m_devices.push_back(device));
}
BAN::ErrorOr<BAN::RefPtr<Inode>> DeviceManager::read_directory_inode_impl(BAN::StringView name)
BAN::ErrorOr<BAN::RefPtr<Inode>> DeviceManager::read_directory_inode(BAN::StringView name)
{
LockGuard _(m_lock);
for (Device* device : m_devices)
@@ -54,7 +54,7 @@ namespace Kernel
return BAN::Error::from_errno(ENOENT);
}
BAN::ErrorOr<BAN::Vector<BAN::String>> DeviceManager::read_directory_entries_impl(size_t index)
BAN::ErrorOr<BAN::Vector<BAN::String>> DeviceManager::read_directory_entries(size_t index)
{
BAN::Vector<BAN::String> result;
if (index > 0)

View File

@@ -169,7 +169,7 @@ namespace Kernel
auto inode_location = TRY(fs.locate_inode(inode_inode));
fs.read_block(inode_location.block, block_buffer.span());
auto& inode = *(Ext2::Inode*)(block_buffer.data() + inode_location.offset);
Ext2Inode* result = new Ext2Inode(fs, inode, name, inode_inode);
Ext2Inode* result = new Ext2Inode(fs, inode, inode_inode, name);
if (result == nullptr)
return BAN::Error::from_errno(ENOMEM);
return BAN::RefPtr<Inode>::adopt(result);
@@ -284,7 +284,7 @@ namespace Kernel
return n_read;
}
BAN::ErrorOr<BAN::Vector<BAN::String>> Ext2Inode::read_directory_entries_impl(size_t index)
BAN::ErrorOr<BAN::Vector<BAN::String>> Ext2Inode::read_directory_entries(size_t index)
{
if (!ifdir())
return BAN::Error::from_errno(ENOTDIR);
@@ -328,7 +328,7 @@ namespace Kernel
BAN::Vector<uint8_t> block_buffer;
TRY(block_buffer.resize(block_size));
auto error_or = read_directory_inode_impl(name);
auto error_or = read_directory_inode(name);
if (!error_or.is_error())
return BAN::Error::from_errno(EEXISTS);
if (error_or.error().get_error_code() != ENOENT)
@@ -401,7 +401,7 @@ namespace Kernel
return {};
}
BAN::ErrorOr<BAN::RefPtr<Inode>> Ext2Inode::read_directory_inode_impl(BAN::StringView file_name)
BAN::ErrorOr<BAN::RefPtr<Inode>> Ext2Inode::read_directory_inode(BAN::StringView file_name)
{
if (!ifdir())
return BAN::Error::from_errno(ENOTDIR);
@@ -425,7 +425,7 @@ namespace Kernel
const auto& entry = *(const Ext2::LinkedDirectoryEntry*)entry_addr;
BAN::StringView entry_name(entry.name, entry.name_len);
if (entry.inode && entry_name == file_name)
return TRY(Ext2Inode::create(m_fs, entry.inode, entry.name));
return TRY(Ext2Inode::create(m_fs, entry.inode, entry_name));
entry_addr += entry.rec_len;
}
}
@@ -433,17 +433,6 @@ namespace Kernel
return BAN::Error::from_errno(ENOENT);
}
bool Ext2Inode::operator==(const Inode& other) const
{
if (type() != other.type())
return false;
const auto& ext2_other = (const Ext2Inode&)other;
if (&m_fs != &ext2_other.m_fs)
return false;
return index() == ext2_other.index();
}
BAN::ErrorOr<Ext2FS*> Ext2FS::create(Partition& partition)
{
Ext2FS* ext2fs = new Ext2FS(partition);

View File

@@ -1,26 +0,0 @@
#include <BAN/StringView.h>
#include <kernel/FS/Inode.h>
#include <kernel/FS/VirtualFileSystem.h>
namespace Kernel
{
BAN::ErrorOr<BAN::RefPtr<Inode>> Inode::read_directory_inode(BAN::StringView name)
{
if (name == ".."sv)
return read_directory_inode_impl(name);
for (const auto& mount : VirtualFileSystem::get().mount_points())
if (*mount.inode == *this)
return mount.target->root_inode()->read_directory_inode_impl(name);
return read_directory_inode_impl(name);
}
BAN::ErrorOr<BAN::Vector<BAN::String>> Inode::read_directory_entries(size_t index)
{
for (const auto& mount : VirtualFileSystem::get().mount_points())
if (*mount.inode == *this)
return mount.target->root_inode()->read_directory_entries_impl(index);
return read_directory_entries_impl(index);
}
}

View File

@@ -144,10 +144,18 @@ namespace Kernel
auto file = TRY(file_from_absolute_path(path));
if (!file.inode->ifdir())
return BAN::Error::from_errno(ENOTDIR);
TRY(m_mount_points.push_back({ file.inode, file_system }));
TRY(m_mount_points.push_back({ file, file_system }));
return {};
}
VirtualFileSystem::MountPoint* VirtualFileSystem::mount_point_for_inode(BAN::RefPtr<Inode> inode)
{
for (MountPoint& mount : m_mount_points)
if (*mount.host.inode == *inode)
return &mount;
return nullptr;
}
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_absolute_path(BAN::StringView path)
{
ASSERT(path.front() == '/');
@@ -156,39 +164,47 @@ namespace Kernel
if (!inode)
return BAN::Error::from_c_string("No root inode available");
auto path_parts = TRY(path.split('/'));
BAN::String canonical_path;
for (size_t i = 0; i < path_parts.size();)
const auto path_parts = TRY(path.split('/'));
for (const auto& path_part : path_parts)
{
if (path_parts[i] == "."sv)
if (path_part.empty() || path_part == "."sv)
{
path_parts.remove(i);
continue;
}
else if (path_parts[i] == ".."sv)
else if (path_part == ".."sv)
{
inode = TRY(inode->read_directory_inode(path_parts[i]));
path_parts.remove(i);
if (i > 0)
if (auto* mount_point = mount_point_for_inode(inode))
inode = TRY(mount_point->host.inode->read_directory_inode(".."sv));
else
inode = TRY(inode->read_directory_inode(".."sv));
if (!canonical_path.empty())
{
path_parts.remove(i - 1);
i--;
while (canonical_path.back() != '/')
canonical_path.pop_back();
canonical_path.pop_back();
}
}
else
{
inode = TRY(inode->read_directory_inode(path_parts[i]));
i++;
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 (canonical_path.empty())
TRY(canonical_path.push_back('/'));
File file;
file.inode = inode;
for (const auto& part : path_parts)
{
TRY(file.canonical_path.push_back('/'));
TRY(file.canonical_path.append(part));
}
file.canonical_path = BAN::move(canonical_path);
if (file.canonical_path.empty())
TRY(file.canonical_path.push_back('/'));

View File

@@ -1,3 +1,4 @@
#include <BAN/Time.h>
#include <BAN/ScopeGuard.h>
#include <kernel/ACPI.h>
#include <kernel/IDT.h>
@@ -5,6 +6,7 @@
#include <kernel/Input/PS2Keyboard.h>
#include <kernel/InterruptController.h>
#include <kernel/IO.h>
#include <kernel/RTC.h>
namespace Kernel::Input
{
@@ -301,7 +303,7 @@ namespace Kernel::Input
// MF2 Keyboard
if (index == 2 && (bytes[0] == 0xAB && bytes[1] == 0x83))
m_devices[device] = TRY(PS2Keyboard::create(*this));
m_devices[device] = TRY(PS2Keyboard::create(*this, device));
if (m_devices[device])
return {};
@@ -331,4 +333,11 @@ namespace Kernel::Input
return {};
}
PS2Device::PS2Device(dev_t dev)
{
m_dev = dev;
m_ino = dev & 1;
m_time = { BAN::to_unix_time(RTC::get_current_time()), 0 };
}
}

View File

@@ -37,9 +37,9 @@ namespace Kernel::Input
}
BAN::ErrorOr<PS2Keyboard*> PS2Keyboard::create(PS2Controller& controller)
BAN::ErrorOr<PS2Keyboard*> PS2Keyboard::create(PS2Controller& controller, dev_t device)
{
PS2Keyboard* keyboard = new PS2Keyboard(controller);
PS2Keyboard* keyboard = new PS2Keyboard(controller, device);
if (keyboard == nullptr)
return BAN::Error::from_errno(ENOMEM);
BAN::ScopeGuard guard([keyboard] { delete keyboard; });

View File

@@ -98,7 +98,7 @@ namespace Kernel
void Shell::run()
{
int fd = MUST(Process::current()->open("/dev/input"sv, O_RDONLY));
int fd = MUST(Process::current()->open("/dev/input0"sv, O_RDONLY));
TTY_PRINT("{}", m_prompt);
for (;;)