https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cf4138fa2433373081854…
commit cf4138fa2433373081854b44c4bb76541d4fe0cc
Author: Thamatip Chitpong <thamatip.chitpong(a)reactos.org>
AuthorDate: Thu Jul 25 23:09:17 2024 +0700
Commit: Thamatip Chitpong <thamatip.chitpong(a)reactos.org>
CommitDate: Wed Jul 31 18:07:49 2024 +0700
[NTOS:CC] Protect CcFlushCache call with a mutex
Fix crash when the function was called concurrently for the same file by BTRFS
driver.
CORE-19664
---
ntoskrnl/cc/view.c | 9 +++++++--
ntoskrnl/include/internal/cc.h | 1 +
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c
index 90b644560e2..7c13afb3220 100644
--- a/ntoskrnl/cc/view.c
+++ b/ntoskrnl/cc/view.c
@@ -1142,6 +1142,8 @@ CcFlushCache (
IoStatus->Information = 0;
}
+ KeAcquireGuardedMutex(&SharedCacheMap->FlushCacheLock);
+
/*
* We flush the VACBs that we find here.
* If there is no (dirty) VACB, it doesn't mean that there is no data to flush,
so we call Mm to be sure.
@@ -1161,7 +1163,7 @@ CcFlushCache (
if (!NT_SUCCESS(Status))
{
CcRosReleaseVacb(SharedCacheMap, vacb, FALSE, FALSE);
- goto quit;
+ break;
}
DirtyVacb = TRUE;
@@ -1191,7 +1193,7 @@ CcFlushCache (
}
if (!NT_SUCCESS(Status))
- goto quit;
+ break;
if (IoStatus)
IoStatus->Information += MmIosb.Information;
@@ -1211,6 +1213,8 @@ CcFlushCache (
FlushStart -= FlushStart % VACB_MAPPING_GRANULARITY;
}
+ KeReleaseGuardedMutex(&SharedCacheMap->FlushCacheLock);
+
quit:
if (IoStatus)
{
@@ -1319,6 +1323,7 @@ CcRosInitializeFileCache (
KeInitializeSpinLock(&SharedCacheMap->CacheMapLock);
InitializeListHead(&SharedCacheMap->CacheMapVacbListHead);
InitializeListHead(&SharedCacheMap->BcbList);
+ KeInitializeGuardedMutex(&SharedCacheMap->FlushCacheLock);
SharedCacheMap->Flags = SHARED_CACHE_MAP_IN_CREATION;
diff --git a/ntoskrnl/include/internal/cc.h b/ntoskrnl/include/internal/cc.h
index 90c315901d1..b37c5478f05 100644
--- a/ntoskrnl/include/internal/cc.h
+++ b/ntoskrnl/include/internal/cc.h
@@ -193,6 +193,7 @@ typedef struct _ROS_SHARED_CACHE_MAP
LIST_ENTRY CacheMapVacbListHead;
BOOLEAN PinAccess;
KSPIN_LOCK CacheMapLock;
+ KGUARDED_MUTEX FlushCacheLock;
#if DBG
BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
#endif