Kernel: Decrease the number of syncs done by ext2 inodes

Each allocated inode used to call sync(). Each sync reads and writes
a block from the filesystem. Doing a 1 MiB write ended up syncing around
257 times
This commit is contained in:
Bananymous 2026-01-01 23:54:09 +02:00
parent 941e8aa5d5
commit e26aac3067
2 changed files with 27 additions and 8 deletions

View File

@ -84,6 +84,26 @@ namespace Kernel
{}
static BAN::ErrorOr<BAN::RefPtr<Ext2Inode>> create(Ext2FS&, uint32_t);
private:
struct ScopedSync
{
ScopedSync(Ext2Inode& inode)
: inode(inode)
, inode_info(inode.m_inode)
{ }
~ScopedSync()
{
if (memcmp(&inode.m_inode, &inode_info, sizeof(Ext2::Inode)) == 0)
return;
if (auto ret = inode.sync(); ret.is_error())
dwarnln("failed to sync inode: {}", ret.error());
}
Ext2Inode& inode;
Ext2::Inode inode_info;
};
private:
Ext2FS& m_fs;
Ext2::Inode m_inode;

View File

@ -74,8 +74,6 @@ namespace Kernel
auto block_buffer = TRY(m_fs.get_block_buffer());
memset(block_buffer.data(), 0x00, block_buffer.size());
TRY(m_fs.write_block(block, block_buffer));
TRY(sync());
}
return BAN::Optional<uint32_t>(block);
@ -83,7 +81,7 @@ namespace Kernel
auto block_buffer = TRY(m_fs.get_block_buffer());
bool needs_sync = false;
bool needs_write = false;
if (block != 0)
TRY(m_fs.read_block(block, block_buffer));
@ -97,7 +95,7 @@ namespace Kernel
memset(block_buffer.data(), 0, block_buffer.size());
needs_sync = true;
needs_write = true;
}
uint32_t divisor = 1;
@ -109,10 +107,8 @@ namespace Kernel
const auto result = TRY(block_from_indirect_block(new_block, index, depth - 1, allocate));
if (needs_sync || old_block != new_block)
if (needs_write || old_block != new_block)
TRY(m_fs.write_block(block, block_buffer));
if (needs_sync)
TRY(sync());
return result;
}
@ -137,7 +133,6 @@ namespace Kernel
m_inode.block[data_block_index] = block;
m_inode.blocks += inode_blocks_per_fs_block;
TRY(sync());
return BAN::Optional<uint32_t>(block);
}
@ -203,6 +198,8 @@ namespace Kernel
if (static_cast<BAN::make_unsigned_t<decltype(offset)>>(offset) >= m_inode.size)
return 0;
ScopedSync _(*this);
uint32_t count = buffer.size();
if (offset + buffer.size() > m_inode.size)
count = m_inode.size - offset;
@ -247,6 +244,8 @@ namespace Kernel
if (m_inode.size < offset + buffer.size())
TRY(truncate_impl(offset + buffer.size()));
ScopedSync _(*this);
const uint32_t block_size = blksize();
auto block_buffer = TRY(m_fs.get_block_buffer());