Lock the MainResource from fcb, if we are trying to write back a modified cache segment.
[reactos.git] / reactos / ntoskrnl / cc / view.c
index 172f5f4..be73d63 100644 (file)
  */
 //#define CACHE_BITMAP
 
-#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
-#define ROUND_DOWN(N, S) (((N) % (S)) ? ROUND_UP(N, S) - S : N)
-
-#define TAG_CSEG  TAG('C', 'S', 'E', 'G')
-#define TAG_BCB   TAG('B', 'C', 'B', ' ')
-#define TAG_IBCB  TAG('i', 'B', 'C', 'B')
-
 static LIST_ENTRY DirtySegmentListHead;
 static LIST_ENTRY CacheSegmentListHead;
 static LIST_ENTRY CacheSegmentLRUListHead;
@@ -88,13 +81,102 @@ void* _alloca(size_t size);
 #error Unknown compiler for alloca intrinsic stack allocation "function"
 #endif
 
+#if defined(DBG) || defined(KDBG)
+static void CcRosCacheSegmentIncRefCount_ ( PCACHE_SEGMENT cs, const char* file, int line )
+{
+       ++cs->ReferenceCount;
+       if ( cs->Bcb->Trace )
+       {
+               DbgPrint("(%s:%i) CacheSegment %p ++RefCount=%d, Dirty %d, PageOut %d\n",
+                       file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut );
+       }
+}
+static void CcRosCacheSegmentDecRefCount_ ( PCACHE_SEGMENT cs, const char* file, int line )
+{
+       --cs->ReferenceCount;
+       if ( cs->Bcb->Trace )
+       {
+               DbgPrint("(%s:%i) CacheSegment %p --RefCount=%d, Dirty %d, PageOut %d\n",
+                       file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut );
+       }
+}
+#define CcRosCacheSegmentIncRefCount(cs) CcRosCacheSegmentIncRefCount_(cs,__FILE__,__LINE__)
+#define CcRosCacheSegmentDecRefCount(cs) CcRosCacheSegmentDecRefCount_(cs,__FILE__,__LINE__)
+#else
+#define CcRosCacheSegmentIncRefCount(cs) (++((cs)->ReferenceCount))
+#define CcRosCacheSegmentDecRefCount(cs) (--((cs)->ReferenceCount))
+#endif
 
 NTSTATUS
 CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg);
 
+BOOLEAN
+FASTCALL
+CcTryToAcquireBrokenMutex(PFAST_MUTEX FastMutex)
+{
+    KeEnterCriticalRegion();
+    if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1)
+    {
+        FastMutex->Owner = KeGetCurrentThread();
+        return(TRUE);
+    }
+    else
+    {
+        KeLeaveCriticalRegion();
+        return(FALSE);
+    }
+}
+
 /* FUNCTIONS *****************************************************************/
 
+VOID
+STDCALL
+CcRosTraceCacheMap (
+       PBCB Bcb,
+       BOOLEAN Trace )
+{
+#if defined(DBG) || defined(KDBG)
+       KIRQL oldirql;
+       PLIST_ENTRY current_entry;
+       PCACHE_SEGMENT current;
+
+       if ( !Bcb )
+               return;
+
+       Bcb->Trace = Trace;
+
+       if ( Trace )
+       {
+               DPRINT1("Enabling Tracing for CacheMap 0x%p:\n", Bcb );
+
+               ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
+               KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
+
+               current_entry = Bcb->BcbSegmentListHead.Flink;
+               while (current_entry != &Bcb->BcbSegmentListHead)
+               {
+                       current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
+                       current_entry = current_entry->Flink;
+
+                       DPRINT1("  CacheSegment 0x%p enabled, RefCount %d, Dirty %d, PageOut %d\n",
+                               current, current->ReferenceCount, current->Dirty, current->PageOut );
+               }
+               KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
+               ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
+       }
+       else
+       {
+               DPRINT1("Disabling Tracing for CacheMap 0x%p:\n", Bcb );
+       }
+
+#else
+       Bcb = Bcb;
+       Trace = Trace;
+#endif
+}
+
 NTSTATUS
+NTAPI
 CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment)
 {
   NTSTATUS Status;
@@ -102,19 +184,20 @@ CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment)
   Status = WriteCacheSegment(CacheSegment);
   if (NT_SUCCESS(Status))
     {
-      ExAcquireFastMutex(&ViewLock);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
       KeAcquireSpinLock(&CacheSegment->Bcb->BcbLock, &oldIrql);
       CacheSegment->Dirty = FALSE;
       RemoveEntryList(&CacheSegment->DirtySegmentListEntry);
       DirtyPageCount -= CacheSegment->Bcb->CacheSegmentSize / PAGE_SIZE;
-      CacheSegment->ReferenceCount--;
+      CcRosCacheSegmentDecRefCount ( CacheSegment );
       KeReleaseSpinLock(&CacheSegment->Bcb->BcbLock, oldIrql);
-      ExReleaseFastMutex(&ViewLock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
     }
   return(Status);
 }
 
 NTSTATUS
+NTAPI
 CcRosFlushDirtyPages(ULONG Target, PULONG Count)
 {
   PLIST_ENTRY current_entry;
@@ -129,7 +212,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
 
   (*Count) = 0;
 
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
 
   WriteCount[0] = WriteCount[1];
   WriteCount[1] = WriteCount[2];
@@ -161,21 +244,34 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
       current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
                                  DirtySegmentListEntry);
       current_entry = current_entry->Flink;
-      Locked = ExTryToAcquireFastMutex(&current->Lock);
+    
+//      Locked = current->Bcb->Callbacks.AcquireForLazyWrite(current->Bcb->Context, FALSE);
+      Locked = ExTryToAcquireResourceExclusiveLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource);
+      if (!Locked)
+        {
+          continue;
+        }
+      Locked = CcTryToAcquireBrokenMutex(&current->Lock);
       if (!Locked)
        {
+//          current->Bcb->Callbacks.ReleaseFromLazyWrite(current->Bcb->Context);
+          ExReleaseResourceLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource);
          continue;
        }
       ASSERT(current->Dirty);
       if (current->ReferenceCount > 1)
        {
-         ExReleaseFastMutex(&current->Lock);
+         ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&current->Lock);
+//          current->Bcb->Callbacks.ReleaseFromLazyWrite(current->Bcb->Context);
+          ExReleaseResourceLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource);
          continue;
        }
-      ExReleaseFastMutex(&ViewLock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
       PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
       Status = CcRosFlushCacheSegment(current);
-      ExReleaseFastMutex(&current->Lock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&current->Lock);
+//      current->Bcb->Callbacks.ReleaseFromLazyWrite(current->Bcb->Context);
+      ExReleaseResourceLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource);
       if (!NT_SUCCESS(Status) &&  (Status != STATUS_END_OF_FILE))
       {
         DPRINT1("CC: Failed to flush cache segment.\n");
@@ -185,14 +281,14 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
          (*Count) += PagesPerSegment;
          Target -= PagesPerSegment;
       }
-      ExAcquireFastMutex(&ViewLock);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
       current_entry = DirtySegmentListHead.Flink;
     }
   if (*Count < NewTarget)
   {
      WriteCount[1] += (NewTarget - *Count);
   }
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
   DPRINT("CcRosFlushDirtyPages() finished\n");
 
   return(STATUS_SUCCESS);
@@ -222,7 +318,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
 
   InitializeListHead(&FreeList);
 
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   current_entry = CacheSegmentLRUListHead.Flink;
   while (current_entry != &CacheSegmentLRUListHead && Target > 0)
     {
@@ -250,11 +346,11 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
             ULONG i;
             NTSTATUS Status;
 
-             current->ReferenceCount++;
+         CcRosCacheSegmentIncRefCount(current);
             last = current;
             current->PageOut = TRUE;
              KeReleaseSpinLock(&current->Bcb->BcbLock, oldIrql);
-            ExReleaseFastMutex(&ViewLock);
+            ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
             for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE; i++)
               {
                 PFN_TYPE Page;
@@ -265,10 +361,10 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
                     break;
                   }
               }
-             ExAcquireFastMutex(&ViewLock);
+             ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
              KeAcquireSpinLock(&current->Bcb->BcbLock, &oldIrql);
-            current->ReferenceCount--;
-            current->PageOut = FALSE;
+             CcRosCacheSegmentDecRefCount(current);
+             current->PageOut = FALSE;
              KeReleaseSpinLock(&current->Bcb->BcbLock, oldIrql);
              current_entry = &current->CacheSegmentLRUListEntry;
             continue;
@@ -276,7 +372,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
         KeReleaseSpinLock(&current->Bcb->BcbLock, oldIrql);
       }
   }
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
   while (!IsListEmpty(&FreeList))
   {
@@ -291,6 +387,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
 }
 
 NTSTATUS
+NTAPI
 CcRosReleaseCacheSegment(PBCB Bcb,
                         PCACHE_SEGMENT CacheSeg,
                         BOOLEAN Valid,
@@ -302,13 +399,13 @@ CcRosReleaseCacheSegment(PBCB Bcb,
 
   ASSERT(Bcb);
 
-  DPRINT("CcReleaseCacheSegment(Bcb %x, CacheSeg %x, Valid %d)\n",
+  DPRINT("CcReleaseCacheSegment(Bcb 0x%p, CacheSeg 0x%p, Valid %d)\n",
         Bcb, CacheSeg, Valid);
 
   CacheSeg->Valid = Valid;
   CacheSeg->Dirty = CacheSeg->Dirty || Dirty;
 
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   if (!WasDirty && CacheSeg->Dirty)
     {
       InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
@@ -322,23 +419,24 @@ CcRosReleaseCacheSegment(PBCB Bcb,
      CacheSeg->MappedCount++;
   }
   KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
-  CacheSeg->ReferenceCount--;
+  CcRosCacheSegmentDecRefCount(CacheSeg);
   if (Mapped && CacheSeg->MappedCount == 1)
   {
-      CacheSeg->ReferenceCount++;
+      CcRosCacheSegmentIncRefCount(CacheSeg);
   }
   if (!WasDirty && CacheSeg->Dirty)
   {
-      CacheSeg->ReferenceCount++;
+      CcRosCacheSegmentIncRefCount(CacheSeg);
   }
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
-  ExReleaseFastMutex(&ViewLock);
-  ExReleaseFastMutex(&CacheSeg->Lock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
 
   return(STATUS_SUCCESS);
 }
 
 PCACHE_SEGMENT
+NTAPI
 CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
 {
   PLIST_ENTRY current_entry;
@@ -347,7 +445,7 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
 
   ASSERT(Bcb);
 
-  DPRINT("CcRosLookupCacheSegment(Bcb %x, FileOffset %d)\n", Bcb, FileOffset);
+  DPRINT("CcRosLookupCacheSegment(Bcb -x%p, FileOffset %d)\n", Bcb, FileOffset);
 
   KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
   current_entry = Bcb->BcbSegmentListHead.Flink;
@@ -358,9 +456,9 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
       if (current->FileOffset <= FileOffset &&
          (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)
        {
-         current->ReferenceCount++;
+          CcRosCacheSegmentIncRefCount(current);
          KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
-          ExAcquireFastMutex(&current->Lock);
+          ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&current->Lock);
          return(current);
        }
       current_entry = current_entry->Flink;
@@ -370,6 +468,7 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
 }
 
 NTSTATUS
+NTAPI
 CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset)
 {
   PCACHE_SEGMENT CacheSeg;
@@ -377,7 +476,7 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset)
 
   ASSERT(Bcb);
 
-  DPRINT("CcRosMarkDirtyCacheSegment(Bcb %x, FileOffset %d)\n", Bcb, FileOffset);
+  DPRINT("CcRosMarkDirtyCacheSegment(Bcb 0x%p, FileOffset %d)\n", Bcb, FileOffset);
 
   CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset);
   if (CacheSeg == NULL)
@@ -386,26 +485,27 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset)
     }
   if (!CacheSeg->Dirty)
     {
-      ExAcquireFastMutex(&ViewLock);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
       InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
       DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE;
-      ExReleaseFastMutex(&ViewLock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
     }
   else
   {
      KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
-     CacheSeg->ReferenceCount--;
+     CcRosCacheSegmentDecRefCount(CacheSeg);
      KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
   }
 
 
   CacheSeg->Dirty = TRUE;
-  ExReleaseFastMutex(&CacheSeg->Lock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
 
   return(STATUS_SUCCESS);
 }
 
 NTSTATUS
+NTAPI
 CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
 {
   PCACHE_SEGMENT CacheSeg;
@@ -414,7 +514,7 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
 
   ASSERT(Bcb);
 
-  DPRINT("CcRosUnmapCacheSegment(Bcb %x, FileOffset %d, NowDirty %d)\n",
+  DPRINT("CcRosUnmapCacheSegment(Bcb 0x%p, FileOffset %d, NowDirty %d)\n",
           Bcb, FileOffset, NowDirty);
 
   CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset);
@@ -430,25 +530,25 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
 
   if (!WasDirty && NowDirty)
   {
-     ExAcquireFastMutex(&ViewLock);
+     ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
      InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
      DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE;
-     ExReleaseFastMutex(&ViewLock);
+     ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
   }
 
   KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
-  CacheSeg->ReferenceCount--;
+  CcRosCacheSegmentDecRefCount(CacheSeg);
   if (!WasDirty && NowDirty)
   {
-     CacheSeg->ReferenceCount++;
+     CcRosCacheSegmentIncRefCount(CacheSeg);
   }
   if (CacheSeg->MappedCount == 0)
   {
-     CacheSeg->ReferenceCount--;
+     CcRosCacheSegmentDecRefCount(CacheSeg);
   }
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
 
-  ExReleaseFastMutex(&CacheSeg->Lock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
   return(STATUS_SUCCESS);
 }
 
@@ -487,13 +587,19 @@ CcRosCreateCacheSegment(PBCB Bcb,
   current->PageOut = FALSE;
   current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize);
   current->Bcb = Bcb;
+#if defined(DBG) || defined(KDBG)
+  if ( Bcb->Trace )
+  {
+    DPRINT1("CacheMap 0x%p: new Cache Segment: 0x%p\n", Bcb, current );
+  }
+#endif
   current->MappedCount = 0;
   current->DirtySegmentListEntry.Flink = NULL;
   current->DirtySegmentListEntry.Blink = NULL;
   current->ReferenceCount = 1;
   ExInitializeFastMutex(&current->Lock);
-  ExAcquireFastMutex(&current->Lock);
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&current->Lock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
 
   *CacheSeg = current;
   /* There is window between the call to CcRosLookupCacheSegment
@@ -511,13 +617,22 @@ CcRosCreateCacheSegment(PBCB Bcb,
      if (current->FileOffset <= FileOffset &&
        (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)
      {
-       current->ReferenceCount++;
+       CcRosCacheSegmentIncRefCount(current);
        KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
-       ExReleaseFastMutex(&(*CacheSeg)->Lock);
-       ExReleaseFastMutex(&ViewLock);
+#if defined(DBG) || defined(KDBG)
+       if ( Bcb->Trace )
+       {
+               DPRINT1("CacheMap 0x%p: deleting newly created Cache Segment 0x%p ( found existing one 0x%p )\n",
+                       Bcb,
+                       (*CacheSeg),
+                       current );
+       }
+#endif
+       ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&(*CacheSeg)->Lock);
+       ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
        ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg);
        *CacheSeg = current;
-        ExAcquireFastMutex(&current->Lock);
+        ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&current->Lock);
        return STATUS_SUCCESS;
      }
      if (current->FileOffset < FileOffset)
@@ -549,7 +664,7 @@ CcRosCreateCacheSegment(PBCB Bcb,
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
   InsertTailList(&CacheSegmentListHead, &current->CacheSegmentListEntry);
   InsertTailList(&CacheSegmentLRUListHead, &current->CacheSegmentLRUListEntry);
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 #ifdef CACHE_BITMAP
   KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
 
@@ -572,15 +687,14 @@ CcRosCreateCacheSegment(PBCB Bcb,
 #else
   MmLockAddressSpace(MmGetKernelAddressSpace());
   current->BaseAddress = NULL;
-  Status = MmCreateMemoryArea(NULL,
-                             MmGetKernelAddressSpace(),
+  Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
                              MEMORY_AREA_CACHE_SEGMENT,
                              &current->BaseAddress,
                              Bcb->CacheSegmentSize,
                              PAGE_READWRITE,
                              (PMEMORY_AREA*)&current->MemoryArea,
                              FALSE,
-                             FALSE,
+                             0,
                              BoundaryAddressMultiple);
   MmUnlockAddressSpace(MmGetKernelAddressSpace());
   if (!NT_SUCCESS(Status))
@@ -610,6 +724,7 @@ CcRosCreateCacheSegment(PBCB Bcb,
 }
 
 NTSTATUS
+NTAPI
 CcRosGetCacheSegmentChain(PBCB Bcb,
                          ULONG FileOffset,
                          ULONG Length,
@@ -673,6 +788,7 @@ CcRosGetCacheSegmentChain(PBCB Bcb,
 }
 
 NTSTATUS
+NTAPI
 CcRosGetCacheSegment(PBCB Bcb,
                     ULONG FileOffset,
                     PULONG BaseOffset,
@@ -767,7 +883,13 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
   PFN_TYPE Page;
   KIRQL oldIrql;
 #endif
-  DPRINT("Freeing cache segment %x\n", CacheSeg);
+  DPRINT("Freeing cache segment 0x%p\n", CacheSeg);
+#if defined(DBG) || defined(KDBG)
+       if ( CacheSeg->Bcb->Trace )
+       {
+               DPRINT1("CacheMap 0x%p: deleting Cache Segment: 0x%p\n", CacheSeg->Bcb, CacheSeg );
+       }
+#endif
 #ifdef CACHE_BITMAP
   RegionSize = CacheSeg->Bcb->CacheSegmentSize / PAGE_SIZE;
 
@@ -804,6 +926,7 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
 }
 
 NTSTATUS
+NTAPI
 CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg)
 {
   NTSTATUS Status;
@@ -811,10 +934,10 @@ CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg)
 
   ASSERT(Bcb);
 
-  DPRINT("CcRosFreeCacheSegment(Bcb %x, CacheSeg %x)\n",
+  DPRINT("CcRosFreeCacheSegment(Bcb 0x%p, CacheSeg 0x%p)\n",
          Bcb, CacheSeg);
 
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
   RemoveEntryList(&CacheSeg->BcbSegmentListEntry);
   RemoveEntryList(&CacheSeg->CacheSegmentListEntry);
@@ -826,7 +949,7 @@ CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg)
 
   }
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
   Status = CcRosInternalFreeCacheSegment(CacheSeg);
   return(Status);
@@ -847,7 +970,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
    NTSTATUS Status;
    KIRQL oldIrql;
 
-   DPRINT("CcFlushCache(SectionObjectPointers %x, FileOffset %x, Length %d, IoStatus %x)\n",
+   DPRINT("CcFlushCache(SectionObjectPointers 0x%p, FileOffset 0x%p, Length %d, IoStatus 0x%p)\n",
            SectionObjectPointers, FileOffset, Length, IoStatus);
 
    if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap)
@@ -884,8 +1007,8 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
               }
            }
             KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
-           ExReleaseFastMutex(&current->Lock);
-           current->ReferenceCount--;
+           ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&current->Lock);
+            CcRosCacheSegmentDecRefCount(current);
            KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
         }
 
@@ -910,6 +1033,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
 }
 
 NTSTATUS
+NTAPI
 CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
 /*
  * FUNCTION: Releases the BCB associated with a file object
@@ -924,11 +1048,11 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
    ASSERT(Bcb);
 
    Bcb->RefCount++;
-   ExReleaseFastMutex(&ViewLock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
    CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
 
-   ExAcquireFastMutex(&ViewLock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
    Bcb->RefCount--;
    if (Bcb->RefCount == 0)
    {
@@ -960,9 +1084,12 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
         }
          InsertHeadList(&FreeList, &current->BcbSegmentListEntry);
       }
+#if defined(DBG) || defined(KDBG)
+      Bcb->Trace = FALSE;
+#endif
       KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
 
-      ExReleaseFastMutex(&ViewLock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
       ObDereferenceObject (Bcb->FileObject);
 
       while (!IsListEmpty(&FreeList))
@@ -972,15 +1099,17 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
          Status = CcRosInternalFreeCacheSegment(current);
       }
       ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
-      ExAcquireFastMutex(&ViewLock);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
    }
    return(STATUS_SUCCESS);
 }
 
-VOID CcRosReferenceCache(PFILE_OBJECT FileObject)
+VOID
+NTAPI
+CcRosReferenceCache(PFILE_OBJECT FileObject)
 {
   PBCB Bcb;
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
   ASSERT(Bcb);
   if (Bcb->RefCount == 0)
@@ -995,14 +1124,16 @@ VOID CcRosReferenceCache(PFILE_OBJECT FileObject)
      ASSERT(Bcb->BcbRemoveListEntry.Flink == NULL);
   }
   Bcb->RefCount++;
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 }
 
-VOID CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer)
+VOID
+NTAPI
+CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer)
 {
   PBCB Bcb;
   DPRINT("CcRosSetRemoveOnClose()\n");
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   Bcb = (PBCB)SectionObjectPointer->SharedCacheMap;
   if (Bcb)
   {
@@ -1012,14 +1143,16 @@ VOID CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer)
       CcRosDeleteFileCache(Bcb->FileObject, Bcb);
     }
   }
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 }
 
 
-VOID CcRosDereferenceCache(PFILE_OBJECT FileObject)
+VOID
+NTAPI
+CcRosDereferenceCache(PFILE_OBJECT FileObject)
 {
   PBCB Bcb;
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
   ASSERT(Bcb);
   if (Bcb->RefCount > 0)
@@ -1039,7 +1172,7 @@ VOID CcRosDereferenceCache(PFILE_OBJECT FileObject)
        }
     }
   }
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 }
 
 NTSTATUS STDCALL
@@ -1051,7 +1184,7 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject)
 {
   PBCB Bcb;
 
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
 
   if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
   {
@@ -1078,17 +1211,18 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject)
       }
     }
   }
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
   return(STATUS_SUCCESS);
 }
 
 NTSTATUS
+NTAPI
 CcTryToInitializeFileCache(PFILE_OBJECT FileObject)
 {
    PBCB Bcb;
    NTSTATUS Status;
 
-   ExAcquireFastMutex(&ViewLock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
 
    Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
    if (Bcb == NULL)
@@ -1109,7 +1243,7 @@ CcTryToInitializeFileCache(PFILE_OBJECT FileObject)
       }
       Status = STATUS_SUCCESS;
    }
-   ExReleaseFastMutex(&ViewLock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
    return Status;
 }
@@ -1125,16 +1259,16 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject,
    PBCB Bcb;
 
    Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-   DPRINT("CcRosInitializeFileCache(FileObject %x, *Bcb %x, CacheSegmentSize %d)\n",
+   DPRINT("CcRosInitializeFileCache(FileObject 0x%p, Bcb 0x%p, CacheSegmentSize %d)\n",
            FileObject, Bcb, CacheSegmentSize);
 
-   ExAcquireFastMutex(&ViewLock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
    if (Bcb == NULL)
    {
       Bcb = ExAllocateFromNPagedLookasideList(&BcbLookasideList);
       if (Bcb == NULL)
       {
-        ExReleaseFastMutex(&ViewLock);
+        ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
        return(STATUS_UNSUCCESSFUL);
       }
       memset(Bcb, 0, sizeof(BCB));
@@ -1165,7 +1299,7 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject,
       RemoveEntryList(&Bcb->BcbRemoveListEntry);
       Bcb->BcbRemoveListEntry.Flink = NULL;
    }
-   ExReleaseFastMutex(&ViewLock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
    return(STATUS_SUCCESS);
 }
@@ -1220,7 +1354,7 @@ CmLazyCloseThreadMain(PVOID Ignored)
          break;
       }
 
-      ExAcquireFastMutex(&ViewLock);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
       CcTimeStamp++;
       if (CcTimeStamp >= 30)
       {
@@ -1236,11 +1370,13 @@ CmLazyCloseThreadMain(PVOID Ignored)
             CcRosDeleteFileCache(current->FileObject, current);
         }
       }
-      ExReleaseFastMutex(&ViewLock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
    }
 }
 
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
 CcInitView(VOID)
 {
 #ifdef CACHE_BITMAP
@@ -1259,15 +1395,14 @@ CcInitView(VOID)
 
   MmLockAddressSpace(MmGetKernelAddressSpace());
 
-  Status = MmCreateMemoryArea(NULL,
-                             MmGetKernelAddressSpace(),
+  Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
                              MEMORY_AREA_CACHE_SEGMENT,
                              &CiCacheSegMappingRegionBase,
                              CI_CACHESEG_MAPPING_REGION_SIZE,
-                             0,
+                             PAGE_READWRITE,
                              &marea,
                              FALSE,
-                             FALSE,
+                             0,
                              BoundaryAddressMultiple);
   MmUnlockAddressSpace(MmGetKernelAddressSpace());
   if (!NT_SUCCESS(Status))