From e26aac3067cc4a7619f55a861e6cb9c2b27dd9a6 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 1 Jan 2026 23:54:09 +0200 Subject: [PATCH] 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 --- kernel/include/kernel/FS/Ext2/Inode.h | 20 ++++++++++++++++++++ kernel/kernel/FS/Ext2/Inode.cpp | 15 +++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/kernel/include/kernel/FS/Ext2/Inode.h b/kernel/include/kernel/FS/Ext2/Inode.h index 1616ce0c..ec663752 100644 --- a/kernel/include/kernel/FS/Ext2/Inode.h +++ b/kernel/include/kernel/FS/Ext2/Inode.h @@ -84,6 +84,26 @@ namespace Kernel {} static BAN::ErrorOr> 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; diff --git a/kernel/kernel/FS/Ext2/Inode.cpp b/kernel/kernel/FS/Ext2/Inode.cpp index a30deb10..83861bdd 100644 --- a/kernel/kernel/FS/Ext2/Inode.cpp +++ b/kernel/kernel/FS/Ext2/Inode.cpp @@ -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(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(block); } @@ -203,6 +198,8 @@ namespace Kernel if (static_cast>(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());