Kernel: VFS caches currently open inodes
This commit is contained in:
parent
1292be71b2
commit
1f2ceeb329
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/HashMap.h>
|
||||
#include <BAN/String.h>
|
||||
#include <kernel/FS/FileSystem.h>
|
||||
#include <kernel/Storage/StorageController.h>
|
||||
|
||||
|
@ -13,7 +15,9 @@ namespace Kernel
|
|||
static VirtualFileSystem& get();
|
||||
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);
|
||||
|
||||
|
@ -22,9 +26,8 @@ namespace Kernel
|
|||
BAN::ErrorOr<void> initialize_impl();
|
||||
|
||||
private:
|
||||
BAN::RefPtr<Inode> m_root_inode;
|
||||
|
||||
BAN::Vector<StorageController*> m_storage_controllers;
|
||||
BAN::HashMap<BAN::String, BAN::RefPtr<Inode>> m_open_inodes;
|
||||
BAN::Vector<StorageController*> m_storage_controllers;
|
||||
};
|
||||
|
||||
}
|
|
@ -93,7 +93,7 @@ namespace Kernel
|
|||
{
|
||||
if (partition.name() == "banan-root"sv)
|
||||
{
|
||||
if (m_root_inode)
|
||||
if (root_inode())
|
||||
dwarnln("multiple root partitions found");
|
||||
else
|
||||
{
|
||||
|
@ -103,32 +103,51 @@ namespace Kernel
|
|||
else
|
||||
// FIXME: We leave a dangling pointer to ext2fs. This might be okay since
|
||||
// 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");
|
||||
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)
|
||||
{
|
||||
if (path.front() != '/')
|
||||
return BAN::Error::from_c_string("Path must be an absolute path");
|
||||
ASSERT(path.front() == '/');
|
||||
|
||||
if (m_open_inodes.contains(path))
|
||||
return m_open_inodes[path];
|
||||
|
||||
auto inode = root_inode();
|
||||
if (!inode)
|
||||
return BAN::Error::from_c_string("No root inode available");
|
||||
|
||||
auto path_parts = TRY(path.split('/'));
|
||||
|
||||
for (BAN::StringView part : path_parts)
|
||||
inode = TRY(inode->directory_find(part));
|
||||
|
||||
TRY(m_open_inodes.insert(path, inode));
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue