Kernel: VFS caches currently open inodes
This commit is contained in:
parent
1292be71b2
commit
1f2ceeb329
|
@ -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,9 +26,8 @@ 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue