Kernel/FS: Fix check-then-act concurrency bug in FileSystem/Inode

When the FileSystem does a sync, it gathers up all the inodes with
dirty metadata into a vector. The inode mutex is not held while
checking the inode dirty bit, which can lead to a kernel panic
due to concurrent inode modifications.

Fixes: #21796
This commit is contained in:
Blake Smith 2023-11-19 19:15:37 -06:00 committed by Andreas Kling
parent 2372584b18
commit e346331424
Notes: sideshowbarker 2024-07-16 23:54:15 +09:00
2 changed files with 4 additions and 3 deletions

View file

@ -494,6 +494,9 @@ InodeMetadata Ext2FSInode::metadata() const
ErrorOr<void> Ext2FSInode::flush_metadata()
{
MutexLocker locker(m_inode_lock);
if (!is_metadata_dirty())
return {};
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::flush_metadata(): Flushing inode", identifier());
TRY(fs().write_ext2_inode(index(), m_raw_inode));
if (is_directory()) {

View file

@ -39,15 +39,13 @@ void Inode::sync_all()
});
for (auto& inode : inodes) {
VERIFY(inode->is_metadata_dirty());
(void)inode->flush_metadata();
}
}
void Inode::sync()
{
if (is_metadata_dirty())
(void)flush_metadata();
(void)flush_metadata();
auto result = fs().flush_writes();
if (result.is_error()) {
// TODO: Figure out how to propagate error to a higher function.