[NTOSKRNL] When pinning data, try to find an already pinned BCB
authorPierre Schweitzer <pierre@reactos.org>
Fri, 5 Oct 2018 19:14:13 +0000 (21:14 +0200)
committerPierre Schweitzer <pierre@reactos.org>
Fri, 5 Oct 2018 19:26:16 +0000 (21:26 +0200)
If found, attempt to lock it and return it.

This fixes a lot of CcPinRead tests (and seems to speed up a bit ReactOS)

ntoskrnl/cc/pin.c

index 0d23211..f40405e 100644 (file)
@@ -299,6 +299,9 @@ CcPinRead (
     OUT        PVOID * Bcb,
     OUT        PVOID * Buffer)
 {
+    KIRQL OldIrql;
+    BOOLEAN Result;
+    PINTERNAL_BCB iBcb;
     PROS_SHARED_CACHE_MAP SharedCacheMap;
 
     CCTRACE(CC_API_DEBUG, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
@@ -320,17 +323,47 @@ CcPinRead (
         ++CcPinReadNoWait;
     }
 
-    /* Map first */
-    if (!CcpMapData(SharedCacheMap, FileOffset, Length, Flags, Bcb, Buffer))
+    KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
+    iBcb = CcpFindBcb(SharedCacheMap, FileOffset, Length, TRUE);
+    KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
+
+    if (iBcb == NULL)
     {
-        return FALSE;
-    }
+        /* Map first */
+        if (!CcpMapData(SharedCacheMap, FileOffset, Length, Flags, Bcb, Buffer))
+        {
+            return FALSE;
+        }
 
-    /* Pin then */
-    if (!CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb))
+        /* Pin then */
+        if (!CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb))
+        {
+            CcUnpinData(*Bcb);
+            return FALSE;
+        }
+    }
+    /* We found a BCB, lock it and return it */
+    else
     {
-        CcUnpinData(*Bcb);
-        return FALSE;
+        if (BooleanFlagOn(Flags, PIN_EXCLUSIVE))
+        {
+            Result = ExAcquireResourceExclusiveLite(&iBcb->Lock, BooleanFlagOn(Flags, PIN_WAIT));
+        }
+        else
+        {
+            Result = ExAcquireSharedStarveExclusive(&iBcb->Lock, BooleanFlagOn(Flags, PIN_WAIT));
+        }
+
+        if (!Result)
+        {
+            return FALSE;
+        }
+
+        ++iBcb->PinCount;
+        ++iBcb->RefCount;
+
+        *Bcb = iBcb;
+        *Buffer = (PUCHAR)iBcb->Vacb->BaseAddress + FileOffset->QuadPart % VACB_MAPPING_GRANULARITY;
     }
 
     return TRUE;