mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 01:57:44 +00:00
Kernel: Fix race condition in TmpFSInode::notify_watchers()
We were doing this dance in notify_watchers(): set_metadata_dirty(true); set_metadata_dirty(false); This was done in order to force out inode watcher events immediately. Unfortunately, this was racy, as if SyncTask got scheduled at the wrong moment, it would try to flush metadata for a clean inode. This then got trapped by the VERIFY() statement in Inode::sync_all(): VERIFY(inode.is_metadata_dirty()); This patch fixes the issue by replacing notify_watchers() with lazy metadata notifications like all other filesystems.
This commit is contained in:
parent
b24dc84ad9
commit
416b0374fb
2 changed files with 7 additions and 14 deletions
|
@ -176,7 +176,7 @@ ErrorOr<size_t> TmpFSInode::write_bytes(off_t offset, size_t size, const UserOrK
|
||||||
m_content = move(tmp);
|
m_content = move(tmp);
|
||||||
}
|
}
|
||||||
m_metadata.size = new_size;
|
m_metadata.size = new_size;
|
||||||
notify_watchers();
|
set_metadata_dirty(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY(buffer.read(m_content->data() + offset, size)); // TODO: partial reads?
|
TRY(buffer.read(m_content->data() + offset, size)); // TODO: partial reads?
|
||||||
|
@ -210,12 +210,6 @@ TmpFSInode::Child* TmpFSInode::find_child_by_name(StringView name)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TmpFSInode::notify_watchers()
|
|
||||||
{
|
|
||||||
set_metadata_dirty(true);
|
|
||||||
set_metadata_dirty(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorOr<void> TmpFSInode::flush_metadata()
|
ErrorOr<void> TmpFSInode::flush_metadata()
|
||||||
{
|
{
|
||||||
// We don't really have any metadata that could become dirty.
|
// We don't really have any metadata that could become dirty.
|
||||||
|
@ -232,7 +226,7 @@ ErrorOr<void> TmpFSInode::chmod(mode_t mode)
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
|
|
||||||
m_metadata.mode = mode;
|
m_metadata.mode = mode;
|
||||||
notify_watchers();
|
set_metadata_dirty(true);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +236,7 @@ ErrorOr<void> TmpFSInode::chown(UserID uid, GroupID gid)
|
||||||
|
|
||||||
m_metadata.uid = uid;
|
m_metadata.uid = uid;
|
||||||
m_metadata.gid = gid;
|
m_metadata.gid = gid;
|
||||||
notify_watchers();
|
set_metadata_dirty(true);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +326,7 @@ ErrorOr<void> TmpFSInode::truncate(u64 size)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_metadata.size = size;
|
m_metadata.size = size;
|
||||||
notify_watchers();
|
set_metadata_dirty(true);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +335,7 @@ ErrorOr<void> TmpFSInode::set_atime(time_t time)
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
|
|
||||||
m_metadata.atime = time;
|
m_metadata.atime = time;
|
||||||
notify_watchers();
|
set_metadata_dirty(true);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +344,7 @@ ErrorOr<void> TmpFSInode::set_ctime(time_t time)
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
|
|
||||||
m_metadata.ctime = time;
|
m_metadata.ctime = time;
|
||||||
notify_watchers();
|
set_metadata_dirty(true);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +353,7 @@ ErrorOr<void> TmpFSInode::set_mtime(time_t t)
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
|
|
||||||
m_metadata.mtime = t;
|
m_metadata.mtime = t;
|
||||||
notify_watchers();
|
set_metadata_dirty(true);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,6 @@ private:
|
||||||
TmpFSInode(TmpFS& fs, const InodeMetadata& metadata, InodeIdentifier parent);
|
TmpFSInode(TmpFS& fs, const InodeMetadata& metadata, InodeIdentifier parent);
|
||||||
static ErrorOr<NonnullRefPtr<TmpFSInode>> try_create(TmpFS&, InodeMetadata const& metadata, InodeIdentifier parent);
|
static ErrorOr<NonnullRefPtr<TmpFSInode>> try_create(TmpFS&, InodeMetadata const& metadata, InodeIdentifier parent);
|
||||||
static ErrorOr<NonnullRefPtr<TmpFSInode>> try_create_root(TmpFS&);
|
static ErrorOr<NonnullRefPtr<TmpFSInode>> try_create_root(TmpFS&);
|
||||||
void notify_watchers();
|
|
||||||
|
|
||||||
struct Child {
|
struct Child {
|
||||||
NonnullOwnPtr<KString> name;
|
NonnullOwnPtr<KString> name;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue