forget update de.rc
[reactos.git] / reactos / ntoskrnl / cc / view.c
index 0fa2bf7..fb15002 100644 (file)
@@ -1,90 +1,62 @@
-/*
- *  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: view.c,v 1.56 2003/01/30 18:30:53 hbirr Exp $
+/* $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 ******************************************************************/
 
-#include <ddk/ntddk.h>
-#include <ddk/ntifs.h>
-#include <internal/mm.h>
-#include <internal/cc.h>
-#include <internal/pool.h>
-#include <ntos/minmax.h>
-
+#include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, CcInitView)
+#endif
+
 /* 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;
 static LIST_ENTRY ClosedListHead;
-static ULONG DirtyPageCount=0;
+ULONG DirtyPageCount=0;
 
-static FAST_MUTEX ViewLock;
+FAST_MUTEX ViewLock;
 
 #ifdef CACHE_BITMAP
 #define        CI_CACHESEG_MAPPING_REGION_SIZE (128*1024*1024)
@@ -105,14 +77,110 @@ static HANDLE LazyCloseThreadHandle;
 static CLIENT_ID LazyCloseThreadId;
 static volatile BOOLEAN LazyCloseThreadShouldTerminate;
 
-void * alloca(size_t size);
+#if defined(__GNUC__)
+/* 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);
 
+BOOLEAN
+FASTCALL
+CcTryToAcquireBrokenMutex(PFAST_MUTEX FastMutex)
+{
+    KeEnterCriticalRegion();
+    if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1)
+    {
+        FastMutex->Owner = KeGetCurrentThread();
+        return(TRUE);
+    }
+    else
+    {
+        KeLeaveCriticalRegion();
+        return(FALSE);
+    }
+}
+
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS STATIC
+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;
@@ -120,22 +188,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);
 }
 
-VOID CcRosRemoveUnusedFiles(VOID);
-
-
 NTSTATUS
+NTAPI
 CcRosFlushDirtyPages(ULONG Target, PULONG Count)
 {
   PLIST_ENTRY current_entry;
@@ -150,7 +216,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
 
   (*Count) = 0;
 
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
 
   WriteCount[0] = WriteCount[1];
   WriteCount[1] = WriteCount[2];
@@ -169,7 +235,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
   }
 
   NewTarget = WriteCount[0];
-  
+
   Target = max(NewTarget, Target);
 
   current_entry = DirtySegmentListHead.Flink;
@@ -179,41 +245,54 @@ 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);
+    
+//      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);
+      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);
-      if (!NT_SUCCESS(Status))
+      Status = CcRosFlushCacheSegment(current);
+      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");
       }
       else
       {
          (*Count) += PagesPerSegment;
-         Target -= 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);
@@ -226,12 +305,12 @@ 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.
  */
 {
   PLIST_ENTRY current_entry;
-  PCACHE_SEGMENT current;
+  PCACHE_SEGMENT current, last = NULL;
   ULONG PagesPerSegment;
   ULONG PagesFreed;
   KIRQL oldIrql;
@@ -240,17 +319,17 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
   DPRINT("CcRosTrimCache(Target %d)\n", Target);
 
   *NrFreed = 0;
-  
+
   InitializeListHead(&FreeList);
-  
-  ExAcquireFastMutex(&ViewLock);
+
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&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)
       {
@@ -259,23 +338,51 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
          RemoveEntryList(&current->CacheSegmentListEntry);
          RemoveEntryList(&current->CacheSegmentLRUListEntry);
         InsertHeadList(&FreeList, &current->BcbSegmentListEntry);
+         PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
+         PagesFreed = min(PagesPerSegment, Target);
+         Target -= PagesFreed;
+         (*NrFreed) += PagesFreed;
       }
       else
       {
-         KeReleaseSpinLock(&current->Bcb->BcbLock, oldIrql);
+         if (last != current && current->MappedCount > 0 && !current->Dirty && !current->PageOut)
+          {
+            ULONG i;
+            NTSTATUS Status;
+
+         CcRosCacheSegmentIncRefCount(current);
+            last = current;
+            current->PageOut = TRUE;
+             KeReleaseSpinLock(&current->Bcb->BcbLock, oldIrql);
+            ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
+            for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE; i++)
+              {
+                PFN_TYPE Page;
+                Page = MmGetPhysicalAddress((char*)current->BaseAddress + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT;
+                 Status = MmPageOutPhysicalAddress(Page);
+                if (!NT_SUCCESS(Status))
+                  {
+                    break;
+                  }
+              }
+             ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
+             KeAcquireSpinLock(&current->Bcb->BcbLock, &oldIrql);
+             CcRosCacheSegmentDecRefCount(current);
+             current->PageOut = FALSE;
+             KeReleaseSpinLock(&current->Bcb->BcbLock, oldIrql);
+             current_entry = &current->CacheSegmentLRUListEntry;
+            continue;
+          }
+        KeReleaseSpinLock(&current->Bcb->BcbLock, oldIrql);
       }
   }
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
   while (!IsListEmpty(&FreeList))
   {
      current_entry = RemoveHeadList(&FreeList);
-     current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, 
+     current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
                                 BcbSegmentListEntry);
-     PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
-     PagesFreed = min(PagesPerSegment, Target);
-     Target -= PagesFreed;
-     (*NrFreed) += PagesFreed;
      CcRosInternalFreeCacheSegment(current);
   }
 
@@ -283,7 +390,8 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
   return(STATUS_SUCCESS);
 }
 
-NTSTATUS 
+NTSTATUS
+NTAPI
 CcRosReleaseCacheSegment(PBCB Bcb,
                         PCACHE_SEGMENT CacheSeg,
                         BOOLEAN Valid,
@@ -293,15 +401,15 @@ CcRosReleaseCacheSegment(PBCB Bcb,
   BOOLEAN WasDirty = CacheSeg->Dirty;
   KIRQL oldIrql;
 
-  assert(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);
@@ -315,44 +423,46 @@ 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 
+PCACHE_SEGMENT
+NTAPI
 CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
 {
   PLIST_ENTRY current_entry;
   PCACHE_SEGMENT current;
   KIRQL oldIrql;
 
-  assert(Bcb);
+  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);
+          ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&current->Lock);
          return(current);
        }
       current_entry = current_entry->Flink;
@@ -362,52 +472,53 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
 }
 
 NTSTATUS
+NTAPI
 CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset)
 {
   PCACHE_SEGMENT CacheSeg;
   KIRQL oldIrql;
 
-  assert(Bcb);
+  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)
     {
-      KeBugCheck(0);
+      KEBUGCHECKCC;
     }
-  ExAcquireFastMutex(&CacheSeg->Lock);
   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;
   BOOLEAN WasDirty;
   KIRQL oldIrql;
 
-  assert(Bcb);
+  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);
@@ -415,7 +526,6 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
     {
       return(STATUS_UNSUCCESSFUL);
     }
-  ExAcquireFastMutex(&CacheSeg->Lock);
 
   WasDirty = CacheSeg->Dirty;
   CacheSeg->Dirty = CacheSeg->Dirty || NowDirty;
@@ -424,161 +534,201 @@ 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);
 }
 
 NTSTATUS STATIC
 CcRosCreateCacheSegment(PBCB Bcb,
                        ULONG FileOffset,
-                       PCACHE_SEGMENT* CacheSeg,
-                       BOOLEAN Lock)
+                       PCACHE_SEGMENT* CacheSeg)
 {
   ULONG i;
   PCACHE_SEGMENT current;
+  PCACHE_SEGMENT previous;
   PLIST_ENTRY current_entry;
   NTSTATUS Status;
   KIRQL oldIrql;
+  PPFN_TYPE Pfn;
 #ifdef CACHE_BITMAP
   ULONG StartingOffset;
+#else
 #endif
+  PHYSICAL_ADDRESS BoundaryAddressMultiple;
 
-  assert(Bcb);
+  ASSERT(Bcb);
 
   DPRINT("CcRosCreateCacheSegment()\n");
 
+  BoundaryAddressMultiple.QuadPart = 0;
+  if (FileOffset >= Bcb->FileSize.u.LowPart)
+  {
+     CacheSeg = NULL;
+     return STATUS_INVALID_PARAMETER;
+  }
+
   current = ExAllocateFromNPagedLookasideList(&CacheSegLookasideList);
   current->Valid = FALSE;
   current->Dirty = FALSE;
+  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
    * 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);
-       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;
-       if (Lock)
+        ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&current->Lock);
+       return STATUS_SUCCESS;
+     }
+     if (current->FileOffset < FileOffset)
+     {
+        if (previous == NULL)
        {
-          ExAcquireFastMutex(&current->Lock);
+          previous = current;
+       }
+       else
+       {
+          if (previous->FileOffset < current->FileOffset)
+          {
+             previous = current;
+          }
        }
-       return STATUS_SUCCESS;
      }
      current_entry = current_entry->Flink;
   }
   /* There was no existing segment. */
   current = *CacheSeg;
-  InsertTailList(&Bcb->BcbSegmentListHead, &current->BcbSegmentListEntry);
+  if (previous)
+  {
+     InsertHeadList(&previous->BcbSegmentListEntry, &current->BcbSegmentListEntry);
+  }
+  else
+  {
+     InsertHeadList(&Bcb->BcbSegmentListHead, &current->BcbSegmentListEntry);
+  }
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
   InsertTailList(&CacheSegmentListHead, &current->CacheSegmentListEntry);
   InsertTailList(&CacheSegmentLRUListHead, &current->CacheSegmentLRUListEntry);
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 #ifdef CACHE_BITMAP
   KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
 
   StartingOffset = RtlFindClearBitsAndSet(&CiCacheSegMappingRegionAllocMap, Bcb->CacheSegmentSize / PAGE_SIZE, CiCacheSegMappingRegionHint);
-  
+
   if (StartingOffset == 0xffffffff)
   {
      DPRINT1("Out of CacheSeg mapping space\n");
-     KeBugCheck(0);
+     KEBUGCHECKCC;
   }
 
   current->BaseAddress = CiCacheSegMappingRegionBase + StartingOffset * PAGE_SIZE;
 
   if (CiCacheSegMappingRegionHint == StartingOffset)
   {
-     CiCacheSegMappingRegionHint += Bcb->CacheSegmentSize / PAGE_SIZE; 
+     CiCacheSegMappingRegionHint += Bcb->CacheSegmentSize / PAGE_SIZE;
   }
 
   KeReleaseSpinLock(&CiCacheSegMappingRegionLock, oldIrql);
 #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))
   {
-     KeBugCheck(0);
+     KEBUGCHECKCC;
   }
 #endif
+  Pfn = alloca(sizeof(PFN_TYPE) * (Bcb->CacheSegmentSize / PAGE_SIZE));
   for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++)
   {
-     PHYSICAL_ADDRESS Page;
-      
-     Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page);
-     if (!NT_SUCCESS(Status))
-     {
-       KeBugCheck(0);
-     }
-      
-     Status = MmCreateVirtualMapping(NULL,
-                                    current->BaseAddress + (i * PAGE_SIZE),
-                                    PAGE_READWRITE,
-                                    Page,
-                                    TRUE);
+     Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Pfn[i]);
      if (!NT_SUCCESS(Status))
      {
-       KeBugCheck(0);
+       KEBUGCHECKCC;
      }
   }
-  if (!Lock)
+  Status = MmCreateVirtualMapping(NULL,
+                                 current->BaseAddress,
+                                 PAGE_READWRITE,
+                                 Pfn,
+                                 Bcb->CacheSegmentSize / PAGE_SIZE);
+  if (!NT_SUCCESS(Status))
   {
-     ExReleaseFastMutex(&current->Lock);
+    KEBUGCHECKCC;
   }
-
   return(STATUS_SUCCESS);
 }
 
 NTSTATUS
+NTAPI
 CcRosGetCacheSegmentChain(PBCB Bcb,
                          ULONG FileOffset,
                          ULONG Length,
@@ -589,14 +739,21 @@ CcRosGetCacheSegmentChain(PBCB Bcb,
   PCACHE_SEGMENT* CacheSegList;
   PCACHE_SEGMENT Previous = NULL;
 
-  assert(Bcb);
+  ASSERT(Bcb);
 
   DPRINT("CcRosGetCacheSegmentChain()\n");
 
   Length = ROUND_UP(Length, Bcb->CacheSegmentSize);
 
-  CacheSegList = alloca(sizeof(PCACHE_SEGMENT) * 
+#if defined(__GNUC__)
+  CacheSegList = alloca(sizeof(PCACHE_SEGMENT) *
+                       (Length / Bcb->CacheSegmentSize));
+#elif defined(_MSC_VER)
+  CacheSegList = _alloca(sizeof(PCACHE_SEGMENT) *
                        (Length / Bcb->CacheSegmentSize));
+#else
+#error Unknown compiler for alloca intrinsic stack allocation "function"
+#endif
 
   /*
    * Look for a cache segment already mapping the same data.
@@ -611,14 +768,13 @@ CcRosGetCacheSegmentChain(PBCB Bcb,
        }
       else
        {
-         CcRosCreateCacheSegment(Bcb, CurrentOffset, &current, FALSE);
+         CcRosCreateCacheSegment(Bcb, CurrentOffset, &current);
          CacheSegList[i] = current;
        }
     }
 
   for (i = 0; i < (Length / Bcb->CacheSegmentSize); i++)
     {
-      ExAcquireFastMutex(&CacheSegList[i]->Lock);
       if (i == 0)
        {
          *CacheSeg = CacheSegList[i];
@@ -631,11 +787,12 @@ CcRosGetCacheSegmentChain(PBCB Bcb,
        }
     }
   Previous->NextInChain = NULL;
-  
+
   return(STATUS_SUCCESS);
 }
 
 NTSTATUS
+NTAPI
 CcRosGetCacheSegment(PBCB Bcb,
                     ULONG FileOffset,
                     PULONG BaseOffset,
@@ -646,7 +803,7 @@ CcRosGetCacheSegment(PBCB Bcb,
    PCACHE_SEGMENT current;
    NTSTATUS Status;
 
-   assert(Bcb);
+   ASSERT(Bcb);
 
    DPRINT("CcRosGetCacheSegment()\n");
 
@@ -654,16 +811,16 @@ CcRosGetCacheSegment(PBCB Bcb,
     * Look for a cache segment already mapping the same data.
     */
    current = CcRosLookupCacheSegment(Bcb, FileOffset);
-   if (current != NULL)
-   {
-      ExAcquireFastMutex(&current->Lock);
-   }
-   else
+   if (current == NULL)
    {
      /*
       * Otherwise create a new segment.
       */
-      Status = CcRosCreateCacheSegment(Bcb, FileOffset, &current, TRUE);
+      Status = CcRosCreateCacheSegment(Bcb, FileOffset, &current);
+      if (!NT_SUCCESS(Status))
+      {
+       return Status;
+      }
    }
    /*
     * Return information about the segment to the caller.
@@ -676,7 +833,7 @@ CcRosGetCacheSegment(PBCB Bcb,
    return(STATUS_SUCCESS);
 }
 
-NTSTATUS STDCALL 
+NTSTATUS STDCALL
 CcRosRequestCacheSegment(PBCB Bcb,
                      ULONG FileOffset,
                      PVOID* BaseAddress,
@@ -688,13 +845,13 @@ CcRosRequestCacheSegment(PBCB Bcb,
 {
   ULONG BaseOffset;
 
-  assert(Bcb);
+  ASSERT(Bcb);
 
   if ((FileOffset % Bcb->CacheSegmentSize) != 0)
     {
       CPRINT("Bad fileoffset %x should be multiple of %x",
         FileOffset, Bcb->CacheSegmentSize);
-      KeBugCheck(0);
+      KEBUGCHECKCC;
     }
 
   return(CcRosGetCacheSegment(Bcb,
@@ -706,18 +863,18 @@ CcRosRequestCacheSegment(PBCB Bcb,
 }
 #ifdef CACHE_BITMAP
 #else
-STATIC VOID 
-CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, 
-               PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty)
+STATIC VOID
+CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
+               PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
 {
-  assert(SwapEntry == 0);
-  if (PhysAddr.QuadPart != 0)
+  ASSERT(SwapEntry == 0);
+  if (Page != 0)
     {
-      MmReleasePageMemoryConsumer(MC_CACHE, PhysAddr);
+      MmReleasePageMemoryConsumer(MC_CACHE, Page);
     }
 }
 #endif
-NTSTATUS 
+NTSTATUS
 CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
 /*
  * FUNCTION: Releases a cache segment associated with a BCB
@@ -727,28 +884,34 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
   ULONG i;
   ULONG RegionSize;
   ULONG Base;
-  PHYSICAL_ADDRESS PhysicalAddr;
+  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,
-                            &PhysicalAddr);
-      MmReleasePageMemoryConsumer(MC_CACHE, PhysicalAddr);
+                            &Page);
+      MmReleasePageMemoryConsumer(MC_CACHE, Page);
     }
 
   KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
   /* Deallocate all the pages used. */
   Base = (ULONG)(CacheSeg->BaseAddress - CiCacheSegMappingRegionBase) / PAGE_SIZE;
-  
+
   RtlClearBits(&CiCacheSegMappingRegionAllocMap, Base, RegionSize);
 
   CiCacheSegMappingRegionHint = min (CiCacheSegMappingRegionHint, Base);
@@ -757,8 +920,7 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
 #else
   MmLockAddressSpace(MmGetKernelAddressSpace());
   MmFreeMemoryArea(MmGetKernelAddressSpace(),
-                  CacheSeg->BaseAddress,
-                  CacheSeg->Bcb->CacheSegmentSize,
+                  CacheSeg->MemoryArea,
                   CcFreeCachePage,
                   NULL);
   MmUnlockAddressSpace(MmGetKernelAddressSpace());
@@ -768,17 +930,18 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
 }
 
 NTSTATUS
+NTAPI
 CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg)
 {
   NTSTATUS Status;
   KIRQL oldIrql;
 
-  assert(Bcb);
+  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);
@@ -790,12 +953,15 @@ CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg)
 
   }
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
   Status = CcRosInternalFreeCacheSegment(CacheSeg);
   return(Status);
 }
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
             IN PLARGE_INTEGER FileOffset OPTIONAL,
@@ -808,23 +974,23 @@ 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)
    {
       Bcb = (PBCB)SectionObjectPointers->SharedCacheMap;
-      assert(Bcb);
+      ASSERT(Bcb);
       if (FileOffset)
       {
         Offset = *FileOffset;
       }
-      else 
+      else
       {
-        Offset.QuadPart = 0LL;
+        Offset.QuadPart = (LONGLONG)0;
         Length = Bcb->FileSize.u.LowPart;
       }
-   
+
       if (IoStatus)
       {
         IoStatus->Status = STATUS_SUCCESS;
@@ -836,7 +1002,6 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
         current = CcRosLookupCacheSegment (Bcb, Offset.u.LowPart);
         if (current != NULL)
         {
-           ExAcquireFastMutex(&current->Lock);
            if (current->Dirty)
            {
               Status = CcRosFlushCacheSegment(current);
@@ -846,8 +1011,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);
         }
 
@@ -871,7 +1036,8 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
    }
 }
 
-NTSTATUS 
+NTSTATUS
+NTAPI
 CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
 /*
  * FUNCTION: Releases the BCB associated with a file object
@@ -883,14 +1049,14 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
    LIST_ENTRY FreeList;
    KIRQL oldIrql;
 
-   assert(Bcb);
-   
+   ASSERT(Bcb);
+
    Bcb->RefCount++;
-   ExReleaseFastMutex(&ViewLock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
-   CcFlushCache(FileObject->SectionObjectPointers, NULL, 0, NULL);
+   CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
 
-   ExAcquireFastMutex(&ViewLock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
    Bcb->RefCount--;
    if (Bcb->RefCount == 0)
    {
@@ -900,7 +1066,7 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
          Bcb->BcbRemoveListEntry.Flink = NULL;
       }
 
-      FileObject->SectionObjectPointers->SharedCacheMap = NULL;  
+      FileObject->SectionObjectPointer->SharedCacheMap = NULL;
 
       /*
        * Release all cache segments.
@@ -922,9 +1088,12 @@ 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);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
       ObDereferenceObject (Bcb->FileObject);
 
       while (!IsListEmpty(&FreeList))
@@ -933,27 +1102,42 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
          current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
          Status = CcRosInternalFreeCacheSegment(current);
       }
-      ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);   
-      ExAcquireFastMutex(&ViewLock);
+      ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
    }
    return(STATUS_SUCCESS);
 }
 
-VOID CcRosReferenceCache(PFILE_OBJECT FileObject)
+VOID
+NTAPI
+CcRosReferenceCache(PFILE_OBJECT FileObject)
 {
   PBCB Bcb;
-  ExAcquireFastMutex(&ViewLock);
-  Bcb = (PBCB)FileObject->SectionObjectPointers->SharedCacheMap;
-  assert(Bcb);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
+  Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
+  ASSERT(Bcb);
+  if (Bcb->RefCount == 0)
+  {
+     ASSERT(Bcb->BcbRemoveListEntry.Flink != NULL);
+     RemoveEntryList(&Bcb->BcbRemoveListEntry);
+     Bcb->BcbRemoveListEntry.Flink = NULL;
+
+  }
+  else
+  {
+     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;
-//  DPRINT1("CcRosSetRemoveOnClose()\n");
-  ExAcquireFastMutex(&ViewLock);
+  DPRINT("CcRosSetRemoveOnClose()\n");
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   Bcb = (PBCB)SectionObjectPointer->SharedCacheMap;
   if (Bcb)
   {
@@ -963,16 +1147,18 @@ 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);
-  Bcb = (PBCB)FileObject->SectionObjectPointers->SharedCacheMap;
-  assert(Bcb);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
+  Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
+  ASSERT(Bcb);
   if (Bcb->RefCount > 0)
   {
     Bcb->RefCount--;
@@ -990,22 +1176,23 @@ VOID CcRosDereferenceCache(PFILE_OBJECT FileObject)
        }
     }
   }
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 }
 
-NTSTATUS STDCALL 
-CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
+NTSTATUS STDCALL
+CcRosReleaseFileCache(PFILE_OBJECT FileObject)
 /*
  * FUNCTION: Called by the file system when a handle to a file object
  * has been closed.
  */
 {
-  assert(Bcb);
+  PBCB Bcb;
 
-  ExAcquireFastMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
 
-  if (FileObject->SectionObjectPointers->SharedCacheMap != NULL)
+  if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
   {
+    Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
     if (FileObject->PrivateCacheMap != NULL)
     {
       FileObject->PrivateCacheMap = NULL;
@@ -1014,6 +1201,7 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
          Bcb->RefCount--;
         if (Bcb->RefCount == 0)
         {
+            MmFreeSectionSegments(Bcb->FileObject);
            if (Bcb->RemoveOnClose)
            {
               CcRosDeleteFileCache(FileObject, Bcb);
@@ -1027,64 +1215,102 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
       }
     }
   }
-  ExReleaseFastMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
   return(STATUS_SUCCESS);
 }
 
-NTSTATUS STDCALL 
+NTSTATUS
+NTAPI
+CcTryToInitializeFileCache(PFILE_OBJECT FileObject)
+{
+   PBCB Bcb;
+   NTSTATUS Status;
+
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
+
+   Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+   if (Bcb == NULL)
+   {
+      Status = STATUS_UNSUCCESSFUL;
+   }
+   else
+   {
+      if (FileObject->PrivateCacheMap == NULL)
+      {
+         FileObject->PrivateCacheMap = Bcb;
+         Bcb->RefCount++;
+      }
+      if (Bcb->BcbRemoveListEntry.Flink != NULL)
+      {
+         RemoveEntryList(&Bcb->BcbRemoveListEntry);
+         Bcb->BcbRemoveListEntry.Flink = NULL;
+      }
+      Status = STATUS_SUCCESS;
+   }
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
+
+   return Status;
+}
+
+
+NTSTATUS STDCALL
 CcRosInitializeFileCache(PFILE_OBJECT FileObject,
-                        PBCB* Bcb,
                         ULONG CacheSegmentSize)
 /*
  * FUNCTION: Initializes a BCB for a file object
  */
 {
-   DPRINT("CcRosInitializeFileCache(FileObject %x, *Bcb %x, CacheSegmentSize %d)\n",
-           FileObject, Bcb, CacheSegmentSize);
+   PBCB Bcb;
 
-   ExAcquireFastMutex(&ViewLock);
+   Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+   DPRINT("CcRosInitializeFileCache(FileObject 0x%p, Bcb 0x%p, CacheSegmentSize %d)\n",
+           FileObject, Bcb, CacheSegmentSize);
 
-   if (*Bcb == NULL)
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
+   if (Bcb == NULL)
    {
-      (*Bcb) = ExAllocateFromNPagedLookasideList(&BcbLookasideList);   
-      if ((*Bcb) == NULL)
+      Bcb = ExAllocateFromNPagedLookasideList(&BcbLookasideList);
+      if (Bcb == NULL)
       {
-        ExReleaseFastMutex(&ViewLock);
+        ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
        return(STATUS_UNSUCCESSFUL);
       }
-      memset((*Bcb), 0, sizeof(BCB));      
+      memset(Bcb, 0, sizeof(BCB));
       ObReferenceObjectByPointer(FileObject,
                                 FILE_ALL_ACCESS,
                                 NULL,
                                 KernelMode);
-      (*Bcb)->FileObject = FileObject;
-      (*Bcb)->CacheSegmentSize = CacheSegmentSize;
+      Bcb->FileObject = FileObject;
+      Bcb->CacheSegmentSize = CacheSegmentSize;
       if (FileObject->FsContext)
       {
-         (*Bcb)->AllocationSize = 
-          ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->AllocationSize;
-         (*Bcb)->FileSize = 
-          ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->FileSize;
+         Bcb->AllocationSize =
+          ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->AllocationSize;
+         Bcb->FileSize =
+          ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize;
       }
-      KeInitializeSpinLock(&(*Bcb)->BcbLock);
-      InitializeListHead(&(*Bcb)->BcbSegmentListHead);
-      FileObject->SectionObjectPointers->SharedCacheMap = *Bcb;
+      KeInitializeSpinLock(&Bcb->BcbLock);
+      InitializeListHead(&Bcb->BcbSegmentListHead);
+      FileObject->SectionObjectPointer->SharedCacheMap = Bcb;
    }
    if (FileObject->PrivateCacheMap == NULL)
    {
-      FileObject->PrivateCacheMap = *Bcb;
-      (*Bcb)->RefCount++;
+      FileObject->PrivateCacheMap = Bcb;
+      Bcb->RefCount++;
    }
-   if ((*Bcb)->BcbRemoveListEntry.Flink != NULL)
+   if (Bcb->BcbRemoveListEntry.Flink != NULL)
    {
-      RemoveEntryList(&(*Bcb)->BcbRemoveListEntry);
-      (*Bcb)->BcbRemoveListEntry.Flink = NULL;
+      RemoveEntryList(&Bcb->BcbRemoveListEntry);
+      Bcb->BcbRemoveListEntry.Flink = NULL;
    }
-   ExReleaseFastMutex(&ViewLock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
    return(STATUS_SUCCESS);
 }
 
+/*
+ * @implemented
+ */
 PFILE_OBJECT STDCALL
 CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointers)
 {
@@ -1092,7 +1318,7 @@ CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointers
    if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap)
    {
       Bcb = (PBCB)SectionObjectPointers->SharedCacheMap;
-      assert(Bcb);
+      ASSERT(Bcb);
       return Bcb->FileObject;
    }
    return NULL;
@@ -1111,7 +1337,7 @@ CmLazyCloseThreadMain(PVOID Ignored)
 
    while (1)
    {
-      Timeout.QuadPart += 100000000LL; // 10sec
+      Timeout.QuadPart += (LONGLONG)100000000; // 10sec
       Status = KeWaitForSingleObject(&LazyCloseThreadEvent,
                                     0,
                                     KernelMode,
@@ -1123,7 +1349,7 @@ CmLazyCloseThreadMain(PVOID Ignored)
       if (!NT_SUCCESS(Status))
       {
          DbgPrint("LazyCloseThread: Wait failed\n");
-         KeBugCheck(0);
+         KEBUGCHECKCC;
          break;
       }
       if (LazyCloseThreadShouldTerminate)
@@ -1131,8 +1357,8 @@ CmLazyCloseThreadMain(PVOID Ignored)
           DbgPrint("LazyCloseThread: Terminating\n");
          break;
       }
-      
-      ExAcquireFastMutex(&ViewLock);
+
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
       CcTimeStamp++;
       if (CcTimeStamp >= 30)
       {
@@ -1148,39 +1374,44 @@ CmLazyCloseThreadMain(PVOID Ignored)
             CcRosDeleteFileCache(current->FileObject, current);
         }
       }
-      ExReleaseFastMutex(&ViewLock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
    }
 }
 
 VOID
+INIT_FUNCTION
+NTAPI
 CcInitView(VOID)
 {
 #ifdef CACHE_BITMAP
   PMEMORY_AREA marea;
   PVOID Buffer;
+  PHYSICAL_ADDRESS BoundaryAddressMultiple;
 #endif
   NTSTATUS Status;
   KPRIORITY Priority;
 
   DPRINT("CcInitView()\n");
 #ifdef CACHE_BITMAP
+  BoundaryAddressMultiple.QuadPart = 0;
   CiCacheSegMappingRegionHint = 0;
   CiCacheSegMappingRegionBase = NULL;
 
   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))
     {
-      KeBugCheck(0);
+      KEBUGCHECKCC;
     }
 
   Buffer = ExAllocatePool(NonPagedPool, CI_CACHESEG_MAPPING_REGION_SIZE / (PAGE_SIZE * 8));
@@ -1189,7 +1420,7 @@ CcInitView(VOID)
   RtlClearAllBits(&CiCacheSegMappingRegionAllocMap);
 
   KeInitializeSpinLock(&CiCacheSegMappingRegionLock);
-#endif  
+#endif
   InitializeListHead(&CacheSegmentListHead);
   InitializeListHead(&DirtySegmentListHead);
   InitializeListHead(&CacheSegmentLRUListHead);
@@ -1218,10 +1449,10 @@ CcInitView(VOID)
                                   20);
 
   MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache);
-  
+
   CcInitCacheZeroPage();
 
-  CcTimeStamp = 0;  
+  CcTimeStamp = 0;
   LazyCloseThreadShouldTerminate = FALSE;
   KeInitializeEvent (&LazyCloseThreadEvent, SynchronizationEvent, FALSE);
   Status = PsCreateSystemThread(&LazyCloseThreadHandle,