mirror of
https://github.com/SerenityOS/serenity
synced 2026-05-09 08:32:04 +02:00
Kernel/Ext2FS: Cache blocks less aggressively
With this patch, we now only cache at most 2^14 blocks, which greatly relieves memory pressure when working with large files.
This commit is contained in:
committed by
Tim Schumacher
parent
54b8fe1fa4
commit
54bfc3d294
82
Kernel/FileSystem/Ext2FS/BlockView.cpp
Normal file
82
Kernel/FileSystem/Ext2FS/BlockView.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2024, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/FileSystem/Ext2FS/BlockView.h>
|
||||
#include <Kernel/FileSystem/Ext2FS/Inode.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
static constexpr size_t max_blocks_in_view = 16384; // 2^14
|
||||
|
||||
Ext2FSBlockView::Ext2FSBlockView(Ext2FSInode& inode)
|
||||
: m_inode(inode) {};
|
||||
|
||||
ErrorOr<void> Ext2FSBlockView::ensure_block(BlockBasedFileSystem::BlockIndex block)
|
||||
{
|
||||
VERIFY(m_block_list_lock.is_locked());
|
||||
if (block >= m_first_block && block <= m_last_block && m_block_list_initialized.was_set())
|
||||
return {};
|
||||
|
||||
BlockBasedFileSystem::BlockIndex new_first_block = (block.value() / max_blocks_in_view) * max_blocks_in_view;
|
||||
BlockBasedFileSystem::BlockIndex new_last_block = new_first_block.value() + max_blocks_in_view - 1;
|
||||
|
||||
m_block_list = TRY(m_inode.compute_block_list(new_first_block, new_last_block));
|
||||
|
||||
m_first_block = new_first_block;
|
||||
m_last_block = new_last_block;
|
||||
|
||||
m_block_list_initialized.set();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<BlockBasedFileSystem::BlockIndex> Ext2FSBlockView::get_block(BlockBasedFileSystem::BlockIndex block)
|
||||
{
|
||||
MutexLocker block_list_locker(m_block_list_lock);
|
||||
TRY(ensure_block(block));
|
||||
|
||||
auto it = m_block_list.find(block);
|
||||
if (it == m_block_list.end())
|
||||
return BlockBasedFileSystem::BlockIndex { 0 };
|
||||
|
||||
auto on_disk_block = (*it).value;
|
||||
VERIFY(on_disk_block != 0);
|
||||
return on_disk_block;
|
||||
}
|
||||
|
||||
ErrorOr<BlockBasedFileSystem::BlockIndex> Ext2FSBlockView::get_or_allocate_block(BlockBasedFileSystem::BlockIndex block, bool zero_newly_allocated_block, bool allow_cache)
|
||||
{
|
||||
MutexLocker block_list_locker(m_block_list_lock);
|
||||
TRY(ensure_block(block));
|
||||
|
||||
auto it = m_block_list.find(block);
|
||||
if (it != m_block_list.end()) {
|
||||
auto on_disk_block = (*it).value;
|
||||
VERIFY(on_disk_block != 0);
|
||||
return on_disk_block;
|
||||
}
|
||||
|
||||
auto on_disk_block = TRY(m_inode.allocate_block(block, zero_newly_allocated_block, allow_cache));
|
||||
TRY(m_block_list.try_set(block, on_disk_block));
|
||||
|
||||
return on_disk_block;
|
||||
}
|
||||
|
||||
ErrorOr<void> Ext2FSBlockView::write_block_pointer(BlockBasedFileSystem::BlockIndex logical_block_index, BlockBasedFileSystem::BlockIndex on_disk_index)
|
||||
{
|
||||
MutexLocker block_list_locker(m_block_list_lock);
|
||||
|
||||
TRY(m_inode.write_block_pointer(logical_block_index, on_disk_index));
|
||||
|
||||
if (on_disk_index == 0)
|
||||
m_block_list.remove(logical_block_index);
|
||||
else
|
||||
TRY(m_block_list.try_set(logical_block_index, on_disk_index));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user