https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cf4138fa2433373081854b44c4bb76541d4fe0cc

commit cf4138fa2433373081854b44c4bb76541d4fe0cc
Author:     Thamatip Chitpong <thamatip.chitp...@reactos.org>
AuthorDate: Thu Jul 25 23:09:17 2024 +0700
Commit:     Thamatip Chitpong <thamatip.chitp...@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

Reply via email to