fix reference counting output to tell us caller's file and line #
[reactos.git] / reactos / ntoskrnl / cc / view.c
index 86fb01b..ebddf93 100644 (file)
@@ -1,52 +1,33 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
 /* $Id$
  *
+ * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/cc/view.c
  * PURPOSE:         Cache manager
- * PROGRAMMER:      David Welch (welch@mcmail.com)
- * PORTABILITY:     Checked
- * UPDATE HISTORY:
- *                  Created 22/05/98
+ *
+ * PROGRAMMERS:     David Welch (welch@mcmail.com)
  */
 
 /* NOTES **********************************************************************
  *
- * This is not the NT implementation of a file cache nor anything much like 
- * it. 
+ * This is not the NT implementation of a file cache nor anything much like
+ * it.
  *
- * The general procedure for a filesystem to implement a read or write 
+ * The general procedure for a filesystem to implement a read or write
  * dispatch routine is as follows
- * 
+ *
  * (1) If caching for the FCB hasn't been initiated then so do by calling
  * CcInitializeFileCache.
- * 
+ *
  * (2) For each 4k region which is being read or written obtain a cache page
- * by calling CcRequestCachePage. 
+ * by calling CcRequestCachePage.
  *
- * (3) If either the page is being read or not completely written, and it is 
+ * (3) If either the page is being read or not completely written, and it is
  * not up to date then read its data from the underlying medium. If the read
- * fails then call CcReleaseCachePage with VALID as FALSE and return a error.  
- * 
+ * fails then call CcReleaseCachePage with VALID as FALSE and return a error.
+ *
  * (4) Copy the data into or out of the page as necessary.
- * 
+ *
  * (5) Release the cache page
  */
 /* INCLUDES ******************************************************************/
 /* GLOBALS *******************************************************************/
 
 /*
- * If CACHE_BITMAP is defined, the cache manager uses one large memory region 
- * within the kernel address space and allocate/deallocate space from this block 
- * over a bitmap. If CACHE_BITMAP is used, the size of the mdl mapping region 
+ * If CACHE_BITMAP is defined, the cache manager uses one large memory region
+ * within the kernel address space and allocate/deallocate space from this block
+ * over a bitmap. If CACHE_BITMAP is used, the size of the mdl mapping region
  * must be reduced (ntoskrnl\mm\mdl.c, MI_MDLMAPPING_REGION_SIZE).
  */
 //#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;
@@ -100,19 +74,90 @@ static CLIENT_ID LazyCloseThreadId;
 static volatile BOOLEAN LazyCloseThreadShouldTerminate;
 
 #if defined(__GNUC__)
-void * alloca(size_t size);
+/* void * alloca(size_t size); */
 #elif defined(_MSC_VER)
 void* _alloca(size_t size);
 #else
 #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);
 
 /* 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 );
+
+               ExAcquireFastMutex(&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);
+               ExReleaseFastMutex(&ViewLock);
+       }
+       else
+       {
+               DPRINT1("Disabling Tracing for CacheMap 0x%p:\n", Bcb );
+       }
+
+#else
+       Bcb = Bcb;
+       Trace = Trace;
+#endif
+}
+
 NTSTATUS
 CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment)
 {
@@ -126,7 +171,7 @@ CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment)
       CacheSegment->Dirty = FALSE;
       RemoveEntryList(&CacheSegment->DirtySegmentListEntry);
       DirtyPageCount -= CacheSegment->Bcb->CacheSegmentSize / PAGE_SIZE;
-      CacheSegment->ReferenceCount--;
+      CcRosCacheSegmentDecRefCount ( CacheSegment );
       KeReleaseSpinLock(&CacheSegment->Bcb->BcbLock, oldIrql);
       ExReleaseFastMutex(&ViewLock);
     }
@@ -167,7 +212,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
   }
 
   NewTarget = WriteCount[0];
-  
+
   Target = max(NewTarget, Target);
 
   current_entry = DirtySegmentListHead.Flink;
@@ -177,7 +222,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
   }
   while (current_entry != &DirtySegmentListHead && Target > 0)
     {
-      current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, 
+      current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
                                  DirtySegmentListEntry);
       current_entry = current_entry->Flink;
       Locked = ExTryToAcquireFastMutex(&current->Lock);
@@ -193,7 +238,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
        }
       ExReleaseFastMutex(&ViewLock);
       PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
-      Status = CcRosFlushCacheSegment(current);      
+      Status = CcRosFlushCacheSegment(current);
       ExReleaseFastMutex(&current->Lock);
       if (!NT_SUCCESS(Status) &&  (Status != STATUS_END_OF_FILE))
       {
@@ -224,7 +269,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
  * ARGUMENTS:
  *       Target - The number of pages to be freed.
  *       Priority - The priority of free (currently unused).
- *       NrFreed - Points to a variable where the number of pages 
+ *       NrFreed - Points to a variable where the number of pages
  *                 actually freed is returned.
  */
 {
@@ -238,17 +283,17 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
   DPRINT("CcRosTrimCache(Target %d)\n", Target);
 
   *NrFreed = 0;
-  
+
   InitializeListHead(&FreeList);
-  
+
   ExAcquireFastMutex(&ViewLock);
   current_entry = CacheSegmentLRUListHead.Flink;
   while (current_entry != &CacheSegmentLRUListHead && Target > 0)
     {
-      current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, 
+      current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
                                  CacheSegmentLRUListEntry);
       current_entry = current_entry->Flink;
-      
+
       KeAcquireSpinLock(&current->Bcb->BcbLock, &oldIrql);
       if (current->ReferenceCount == 0)
       {
@@ -268,8 +313,8 @@ 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);
@@ -286,8 +331,8 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
               }
              ExAcquireFastMutex(&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;
@@ -300,7 +345,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
   while (!IsListEmpty(&FreeList))
   {
      current_entry = RemoveHeadList(&FreeList);
-     current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, 
+     current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
                                 BcbSegmentListEntry);
      CcRosInternalFreeCacheSegment(current);
   }
@@ -309,7 +354,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
   return(STATUS_SUCCESS);
 }
 
-NTSTATUS 
+NTSTATUS
 CcRosReleaseCacheSegment(PBCB Bcb,
                         PCACHE_SEGMENT CacheSeg,
                         BOOLEAN Valid,
@@ -321,7 +366,7 @@ 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;
@@ -341,23 +386,23 @@ 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);
-  
+
   return(STATUS_SUCCESS);
 }
 
-PCACHE_SEGMENT 
+PCACHE_SEGMENT
 CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
 {
   PLIST_ENTRY current_entry;
@@ -366,18 +411,18 @@ 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;
   while (current_entry != &Bcb->BcbSegmentListHead)
     {
-      current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, 
+      current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
                                  BcbSegmentListEntry);
       if (current->FileOffset <= FileOffset &&
          (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)
        {
-         current->ReferenceCount++;
+      CcRosCacheSegmentIncRefCount(current);
          KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
           ExAcquireFastMutex(&current->Lock);
          return(current);
@@ -396,7 +441,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)
@@ -413,7 +458,7 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset)
   else
   {
      KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
-     CacheSeg->ReferenceCount--;
+     CcRosCacheSegmentDecRefCount(CacheSeg);
      KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
   }
 
@@ -433,7 +478,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);
@@ -456,14 +501,14 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
   }
 
   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);
 
@@ -506,6 +551,12 @@ 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;
@@ -518,20 +569,29 @@ CcRosCreateCacheSegment(PBCB Bcb,
   /* There is window between the call to CcRosLookupCacheSegment
    * and CcRosCreateCacheSegment. We must check if a segment on
    * the fileoffset exist. If there exist a segment, we release
-   * our new created segment and return the existing one. 
+   * our new created segment and return the existing one.
    */
   KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
   current_entry = Bcb->BcbSegmentListHead.Flink;
   previous = NULL;
   while (current_entry != &Bcb->BcbSegmentListHead)
   {
-     current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, 
+     current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
                                 BcbSegmentListEntry);
      if (current->FileOffset <= FileOffset &&
        (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)
      {
-       current->ReferenceCount++;
+       CcRosCacheSegmentIncRefCount(current);
        KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
+#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
        ExReleaseFastMutex(&(*CacheSeg)->Lock);
        ExReleaseFastMutex(&ViewLock);
        ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg);
@@ -573,7 +633,7 @@ CcRosCreateCacheSegment(PBCB Bcb,
   KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
 
   StartingOffset = RtlFindClearBitsAndSet(&CiCacheSegMappingRegionAllocMap, Bcb->CacheSegmentSize / PAGE_SIZE, CiCacheSegMappingRegionHint);
-  
+
   if (StartingOffset == 0xffffffff)
   {
      DPRINT1("Out of CacheSeg mapping space\n");
@@ -584,7 +644,7 @@ CcRosCreateCacheSegment(PBCB Bcb,
 
   if (CiCacheSegMappingRegionHint == StartingOffset)
   {
-     CiCacheSegMappingRegionHint += Bcb->CacheSegmentSize / PAGE_SIZE; 
+     CiCacheSegMappingRegionHint += Bcb->CacheSegmentSize / PAGE_SIZE;
   }
 
   KeReleaseSpinLock(&CiCacheSegMappingRegionLock, oldIrql);
@@ -646,10 +706,10 @@ CcRosGetCacheSegmentChain(PBCB Bcb,
   Length = ROUND_UP(Length, Bcb->CacheSegmentSize);
 
 #if defined(__GNUC__)
-  CacheSegList = alloca(sizeof(PCACHE_SEGMENT) * 
+  CacheSegList = alloca(sizeof(PCACHE_SEGMENT) *
                        (Length / Bcb->CacheSegmentSize));
 #elif defined(_MSC_VER)
-  CacheSegList = _alloca(sizeof(PCACHE_SEGMENT) * 
+  CacheSegList = _alloca(sizeof(PCACHE_SEGMENT) *
                        (Length / Bcb->CacheSegmentSize));
 #else
 #error Unknown compiler for alloca intrinsic stack allocation "function"
@@ -687,7 +747,7 @@ CcRosGetCacheSegmentChain(PBCB Bcb,
        }
     }
   Previous->NextInChain = NULL;
-  
+
   return(STATUS_SUCCESS);
 }
 
@@ -732,7 +792,7 @@ CcRosGetCacheSegment(PBCB Bcb,
    return(STATUS_SUCCESS);
 }
 
-NTSTATUS STDCALL 
+NTSTATUS STDCALL
 CcRosRequestCacheSegment(PBCB Bcb,
                      ULONG FileOffset,
                      PVOID* BaseAddress,
@@ -762,8 +822,8 @@ CcRosRequestCacheSegment(PBCB Bcb,
 }
 #ifdef CACHE_BITMAP
 #else
-STATIC VOID 
-CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, 
+STATIC VOID
+CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
                PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
 {
   ASSERT(SwapEntry == 0);
@@ -773,7 +833,7 @@ CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
     }
 }
 #endif
-NTSTATUS 
+NTSTATUS
 CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
 /*
  * FUNCTION: Releases a cache segment associated with a BCB
@@ -786,14 +846,20 @@ 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;
 
   /* Unmap all the pages. */
   for (i = 0; i < RegionSize; i++)
     {
-      MmDeleteVirtualMapping(NULL, 
+      MmDeleteVirtualMapping(NULL,
                             CacheSeg->BaseAddress + (i * PAGE_SIZE),
                             FALSE,
                             NULL,
@@ -804,7 +870,7 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
   KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
   /* Deallocate all the pages used. */
   Base = (ULONG)(CacheSeg->BaseAddress - CiCacheSegMappingRegionBase) / PAGE_SIZE;
-  
+
   RtlClearBits(&CiCacheSegMappingRegionAllocMap, Base, RegionSize);
 
   CiCacheSegMappingRegionHint = min (CiCacheSegMappingRegionHint, Base);
@@ -830,7 +896,7 @@ 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);
@@ -866,7 +932,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)
@@ -877,12 +943,12 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
       {
         Offset = *FileOffset;
       }
-      else 
+      else
       {
         Offset.QuadPart = (LONGLONG)0;
         Length = Bcb->FileSize.u.LowPart;
       }
-   
+
       if (IoStatus)
       {
         IoStatus->Status = STATUS_SUCCESS;
@@ -904,7 +970,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
            }
             KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
            ExReleaseFastMutex(&current->Lock);
-           current->ReferenceCount--;
+            CcRosCacheSegmentDecRefCount(current);
            KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
         }
 
@@ -928,7 +994,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
    }
 }
 
-NTSTATUS 
+NTSTATUS
 CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
 /*
  * FUNCTION: Releases the BCB associated with a file object
@@ -957,7 +1023,7 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
          Bcb->BcbRemoveListEntry.Flink = NULL;
       }
 
-      FileObject->SectionObjectPointer->SharedCacheMap = NULL;  
+      FileObject->SectionObjectPointer->SharedCacheMap = NULL;
 
       /*
        * Release all cache segments.
@@ -979,7 +1045,10 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
         }
          InsertHeadList(&FreeList, &current->BcbSegmentListEntry);
       }
-      KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);       
+#if defined(DBG) || defined(KDBG)
+      Bcb->Trace = FALSE;
+#endif
+      KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
 
       ExReleaseFastMutex(&ViewLock);
       ObDereferenceObject (Bcb->FileObject);
@@ -990,7 +1059,7 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
          current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
          Status = CcRosInternalFreeCacheSegment(current);
       }
-      ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);   
+      ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
       ExAcquireFastMutex(&ViewLock);
    }
    return(STATUS_SUCCESS);
@@ -1061,7 +1130,7 @@ VOID CcRosDereferenceCache(PFILE_OBJECT FileObject)
   ExReleaseFastMutex(&ViewLock);
 }
 
-NTSTATUS STDCALL 
+NTSTATUS STDCALL
 CcRosReleaseFileCache(PFILE_OBJECT FileObject)
 /*
  * FUNCTION: Called by the file system when a handle to a file object
@@ -1101,7 +1170,7 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject)
   return(STATUS_SUCCESS);
 }
 
-NTSTATUS 
+NTSTATUS
 CcTryToInitializeFileCache(PFILE_OBJECT FileObject)
 {
    PBCB Bcb;
@@ -1134,7 +1203,7 @@ CcTryToInitializeFileCache(PFILE_OBJECT FileObject)
 }
 
 
-NTSTATUS STDCALL 
+NTSTATUS STDCALL
 CcRosInitializeFileCache(PFILE_OBJECT FileObject,
                         ULONG CacheSegmentSize)
 /*
@@ -1144,7 +1213,7 @@ 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);
@@ -1165,9 +1234,9 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject,
       Bcb->CacheSegmentSize = CacheSegmentSize;
       if (FileObject->FsContext)
       {
-         Bcb->AllocationSize = 
+         Bcb->AllocationSize =
           ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->AllocationSize;
-         Bcb->FileSize = 
+         Bcb->FileSize =
           ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize;
       }
       KeInitializeSpinLock(&Bcb->BcbLock);
@@ -1238,7 +1307,7 @@ CmLazyCloseThreadMain(PVOID Ignored)
           DbgPrint("LazyCloseThread: Terminating\n");
          break;
       }
-      
+
       ExAcquireFastMutex(&ViewLock);
       CcTimeStamp++;
       if (CcTimeStamp >= 30)
@@ -1269,7 +1338,7 @@ CcInitView(VOID)
 #endif
   NTSTATUS Status;
   KPRIORITY Priority;
-  
+
   DPRINT("CcInitView()\n");
 #ifdef CACHE_BITMAP
   BoundaryAddressMultiple.QuadPart = 0;
@@ -1300,7 +1369,7 @@ CcInitView(VOID)
   RtlClearAllBits(&CiCacheSegMappingRegionAllocMap);
 
   KeInitializeSpinLock(&CiCacheSegMappingRegionLock);
-#endif  
+#endif
   InitializeListHead(&CacheSegmentListHead);
   InitializeListHead(&DirtySegmentListHead);
   InitializeListHead(&CacheSegmentLRUListHead);
@@ -1329,10 +1398,10 @@ CcInitView(VOID)
                                   20);
 
   MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache);
-  
+
   CcInitCacheZeroPage();
 
-  CcTimeStamp = 0;  
+  CcTimeStamp = 0;
   LazyCloseThreadShouldTerminate = FALSE;
   KeInitializeEvent (&LazyCloseThreadEvent, SynchronizationEvent, FALSE);
   Status = PsCreateSystemThread(&LazyCloseThreadHandle,