mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 09:48:11 +00:00
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:
parent
2372584b18
commit
e346331424
2 changed files with 4 additions and 3 deletions
|
@ -494,6 +494,9 @@ InodeMetadata Ext2FSInode::metadata() const
|
||||||
ErrorOr<void> Ext2FSInode::flush_metadata()
|
ErrorOr<void> Ext2FSInode::flush_metadata()
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
|
if (!is_metadata_dirty())
|
||||||
|
return {};
|
||||||
|
|
||||||
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::flush_metadata(): Flushing inode", identifier());
|
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::flush_metadata(): Flushing inode", identifier());
|
||||||
TRY(fs().write_ext2_inode(index(), m_raw_inode));
|
TRY(fs().write_ext2_inode(index(), m_raw_inode));
|
||||||
if (is_directory()) {
|
if (is_directory()) {
|
||||||
|
|
|
@ -39,15 +39,13 @@ void Inode::sync_all()
|
||||||
});
|
});
|
||||||
|
|
||||||
for (auto& inode : inodes) {
|
for (auto& inode : inodes) {
|
||||||
VERIFY(inode->is_metadata_dirty());
|
|
||||||
(void)inode->flush_metadata();
|
(void)inode->flush_metadata();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inode::sync()
|
void Inode::sync()
|
||||||
{
|
{
|
||||||
if (is_metadata_dirty())
|
(void)flush_metadata();
|
||||||
(void)flush_metadata();
|
|
||||||
auto result = fs().flush_writes();
|
auto result = fs().flush_writes();
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
// TODO: Figure out how to propagate error to a higher function.
|
// TODO: Figure out how to propagate error to a higher function.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue