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

commit 64cb138a673fa02d76922963c680bfeb05f1d715
Author: Pierre Schweitzer <pie...@reactos.org>
AuthorDate: Sat Nov 18 17:53:07 2017 +0100

    [NTOSKRNL] In CcPurgeCacheSection(), don't assume the file being purged 
isn't used. Handle that case properly instead of asserting.
    This fixes a triggerable ASSERT from umode where you open a file on a CDFS 
(with MS CDFS) and attempt to lock the volume.
---
 ntoskrnl/cc/fs.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/ntoskrnl/cc/fs.c b/ntoskrnl/cc/fs.c
index 6f6b5568fe..fb5f99aab2 100644
--- a/ntoskrnl/cc/fs.c
+++ b/ntoskrnl/cc/fs.c
@@ -143,6 +143,7 @@ CcPurgeCacheSection (
     PLIST_ENTRY ListEntry;
     PROS_VACB Vacb;
     LONGLONG ViewEnd;
+    BOOLEAN Success;
 
     CCTRACE(CC_API_DEBUG, "SectionObjectPointer=%p\n FileOffset=%p Length=%lu 
UninitializeCacheMaps=%d",
         SectionObjectPointer, FileOffset, Length, UninitializeCacheMaps);
@@ -169,6 +170,9 @@ CcPurgeCacheSection (
 
     InitializeListHead(&FreeList);
 
+    /* Assume success */
+    Success = TRUE;
+
     KeAcquireGuardedMutex(&ViewLock);
     KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &OldIrql);
     ListEntry = SharedCacheMap->CacheMapVacbListHead.Flink;
@@ -189,8 +193,12 @@ CcPurgeCacheSection (
             break;
         }
 
-        ASSERT((Vacb->ReferenceCount == 0) ||
-               (Vacb->ReferenceCount == 1 && Vacb->Dirty));
+        /* Still in use, it cannot be purged, fail */
+        if (Vacb->ReferenceCount != 0 && !Vacb->Dirty)
+        {
+            Success = FALSE;
+            break;
+        }
 
         /* This VACB is in range, so unlink it and mark for free */
         RemoveEntryList(&Vacb->VacbLruListEntry);
@@ -213,7 +221,7 @@ CcPurgeCacheSection (
         CcRosInternalFreeVacb(Vacb);
     }
 
-    return TRUE;
+    return Success;
 }
 
 

Reply via email to