Ext2FS: Flush the super block and block group descriptors lazily

Keep dirty bits for these and override flush_writes() so that we can
coalesce writes. Looks like a ~5x write performance bump on the
disk_benchmark.
This commit is contained in:
Andreas Kling 2019-11-02 11:36:56 +01:00
parent f2a9bbe96e
commit e4b7786b66
2 changed files with 23 additions and 6 deletions

View file

@ -501,7 +501,7 @@ void Ext2FS::free_inode(Ext2FSInode& inode)
auto& bgd = const_cast<ext2_group_desc&>(group_descriptor(group_index_from_inode(inode.index())));
--bgd.bg_used_dirs_count;
dbgprintf("Ext2FS: decremented bg_used_dirs_count %u -> %u\n", bgd.bg_used_dirs_count - 1, bgd.bg_used_dirs_count);
flush_block_group_descriptor_table();
m_block_group_descriptors_dirty = true;
}
}
@ -513,6 +513,19 @@ void Ext2FS::flush_block_group_descriptor_table()
write_blocks(first_block_of_bgdt, blocks_to_write, m_cached_group_descriptor_table.data());
}
void Ext2FS::flush_writes()
{
if (m_super_block_dirty) {
write_super_block(super_block());
m_super_block_dirty = false;
}
if (m_block_group_descriptors_dirty) {
flush_block_group_descriptor_table();
m_block_group_descriptors_dirty = false;
}
DiskBackedFS::flush_writes();
}
Ext2FSInode::Ext2FSInode(Ext2FS& fs, unsigned index)
: Inode(fs, index)
{
@ -1188,7 +1201,7 @@ bool Ext2FS::set_inode_allocation_state(InodeIndex inode_index, bool new_state)
--sb.s_free_inodes_count;
else
++sb.s_free_inodes_count;
write_super_block(sb);
m_super_block_dirty = true;
// Update BGD
auto& mutable_bgd = const_cast<ext2_group_desc&>(bgd);
@ -1200,7 +1213,7 @@ bool Ext2FS::set_inode_allocation_state(InodeIndex inode_index, bool new_state)
dbgprintf("Ext2FS: group free inode count %u -> %u\n", bgd.bg_free_inodes_count, bgd.bg_free_inodes_count - 1);
#endif
flush_block_group_descriptor_table();
m_block_group_descriptors_dirty = true;
return true;
}
@ -1252,7 +1265,7 @@ bool Ext2FS::set_block_allocation_state(BlockIndex block_index, bool new_state)
--sb.s_free_blocks_count;
else
++sb.s_free_blocks_count;
write_super_block(sb);
m_super_block_dirty = true;
// Update BGD
auto& mutable_bgd = const_cast<ext2_group_desc&>(bgd);
@ -1264,7 +1277,7 @@ bool Ext2FS::set_block_allocation_state(BlockIndex block_index, bool new_state)
dbgprintf("Ext2FS: group %u free block count %u -> %u\n", group_index, bgd.bg_free_blocks_count, bgd.bg_free_blocks_count - 1);
#endif
flush_block_group_descriptor_table();
m_block_group_descriptors_dirty = true;
return true;
}
@ -1306,7 +1319,7 @@ RefPtr<Inode> Ext2FS::create_directory(InodeIdentifier parent_id, const String&
dbgprintf("Ext2FS: incremented bg_used_dirs_count %u -> %u\n", bgd.bg_used_dirs_count - 1, bgd.bg_used_dirs_count);
#endif
flush_block_group_descriptor_table();
m_block_group_descriptors_dirty = true;
error = 0;
return inode;

View file

@ -98,6 +98,7 @@ private:
virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override;
virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override;
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
virtual void flush_writes() override;
BlockIndex first_block_index() const;
InodeIndex allocate_inode(GroupIndex preferred_group, off_t expected_size);
@ -132,6 +133,9 @@ private:
mutable ByteBuffer m_cached_group_descriptor_table;
mutable HashMap<BlockIndex, RefPtr<Ext2FSInode>> m_inode_cache;
bool m_super_block_dirty { false };
bool m_block_group_descriptors_dirty { false };
};
inline Ext2FS& Ext2FSInode::fs()