Kernel: VFS caches currently open inodes

This commit is contained in:
Bananymous 2023-03-16 15:31:33 +02:00
parent 1292be71b2
commit 1f2ceeb329
2 changed files with 32 additions and 10 deletions

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <BAN/HashMap.h>
#include <BAN/String.h>
#include <kernel/FS/FileSystem.h> #include <kernel/FS/FileSystem.h>
#include <kernel/Storage/StorageController.h> #include <kernel/Storage/StorageController.h>
@ -13,7 +15,9 @@ namespace Kernel
static VirtualFileSystem& get(); static VirtualFileSystem& get();
virtual ~VirtualFileSystem() {}; virtual ~VirtualFileSystem() {};
virtual const BAN::RefPtr<Inode> root_inode() const override { return m_root_inode; } virtual const BAN::RefPtr<Inode> root_inode() const override;
void close_inode(BAN::StringView);
BAN::ErrorOr<BAN::RefPtr<Inode>> from_absolute_path(BAN::StringView); BAN::ErrorOr<BAN::RefPtr<Inode>> from_absolute_path(BAN::StringView);
@ -22,8 +26,7 @@ namespace Kernel
BAN::ErrorOr<void> initialize_impl(); BAN::ErrorOr<void> initialize_impl();
private: private:
BAN::RefPtr<Inode> m_root_inode; BAN::HashMap<BAN::String, BAN::RefPtr<Inode>> m_open_inodes;
BAN::Vector<StorageController*> m_storage_controllers; BAN::Vector<StorageController*> m_storage_controllers;
}; };

View File

@ -93,7 +93,7 @@ namespace Kernel
{ {
if (partition.name() == "banan-root"sv) if (partition.name() == "banan-root"sv)
{ {
if (m_root_inode) if (root_inode())
dwarnln("multiple root partitions found"); dwarnln("multiple root partitions found");
else else
{ {
@ -103,32 +103,51 @@ namespace Kernel
else else
// FIXME: We leave a dangling pointer to ext2fs. This might be okay since // FIXME: We leave a dangling pointer to ext2fs. This might be okay since
// root fs sould probably be always mounted // root fs sould probably be always mounted
m_root_inode = ext2fs_or_error.release_value()->root_inode(); TRY(m_open_inodes.insert("/"sv, ext2fs_or_error.release_value()->root_inode()));
} }
} }
} }
} }
} }
if (m_root_inode.empty()) if (!root_inode())
derrorln("Could not locate root partition"); derrorln("Could not locate root partition");
return {}; return {};
} }
const BAN::RefPtr<Inode> VirtualFileSystem::root_inode() const
{
if (!m_open_inodes.contains("/"sv))
return nullptr;
return m_open_inodes["/"sv];
}
void VirtualFileSystem::close_inode(BAN::StringView path)
{
ASSERT(m_open_inodes.contains(path));
// Delete the cached inode, if we are the only one holding a reference to it
if (m_open_inodes[path]->ref_count() == 1)
m_open_inodes.remove(path);
}
BAN::ErrorOr<BAN::RefPtr<Inode>> VirtualFileSystem::from_absolute_path(BAN::StringView path) BAN::ErrorOr<BAN::RefPtr<Inode>> VirtualFileSystem::from_absolute_path(BAN::StringView path)
{ {
if (path.front() != '/') ASSERT(path.front() == '/');
return BAN::Error::from_c_string("Path must be an absolute path");
if (m_open_inodes.contains(path))
return m_open_inodes[path];
auto inode = root_inode(); auto inode = root_inode();
if (!inode) if (!inode)
return BAN::Error::from_c_string("No root inode available"); return BAN::Error::from_c_string("No root inode available");
auto path_parts = TRY(path.split('/')); auto path_parts = TRY(path.split('/'));
for (BAN::StringView part : path_parts) for (BAN::StringView part : path_parts)
inode = TRY(inode->directory_find(part)); inode = TRY(inode->directory_find(part));
TRY(m_open_inodes.insert(path, inode));
return inode; return inode;
} }