- Implement CcRepinBcb and CcGetFileObjectFromBcb.
authorFilip Navara <filip.navara@gmail.com>
Wed, 25 Aug 2004 15:08:29 +0000 (15:08 +0000)
committerFilip Navara <filip.navara@gmail.com>
Wed, 25 Aug 2004 15:08:29 +0000 (15:08 +0000)
- Partially implement CcUnpinRepinnedBcb, CcPinMappedData,
  CcPinRead, CcPreparePinWrite, CcInitializeCacheMap (Art Yerkes)
  and CcUninitializeCacheMap.
- Fix ReadCacheSegmentChain to handle correctly big request and
  check for MDL request memory overflow.
- Allow passing NULL BCB to CcSetFileSizes.
- Ensure that registry files are opened using lowercase file names.

svn path=/trunk/; revision=10678

reactos/ntoskrnl/cc/cacheman.c
reactos/ntoskrnl/cc/copy.c
reactos/ntoskrnl/cc/fs.c
reactos/ntoskrnl/cc/pin.c
reactos/ntoskrnl/cc/view.c
reactos/ntoskrnl/cm/cm.h
reactos/ntoskrnl/include/internal/cc.h

index bb151cf..7dd5d94 100644 (file)
@@ -57,18 +57,6 @@ CcGetFlushedValidData (
        return i;
 }
 
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-CcRepinBcb (
-       IN      PVOID   Bcb
-       )
-{
-       UNIMPLEMENTED;
-}
-
 /*
  * @unimplemented
  */
@@ -147,17 +135,3 @@ CcSetReadAheadGranularity (
 {
        UNIMPLEMENTED;
 }
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-CcUnpinRepinnedBcb (
-       IN      PVOID                   Bcb,
-       IN      BOOLEAN                 WriteThrough,
-       IN      PIO_STATUS_BLOCK        IoStatus
-       )
-{
-       UNIMPLEMENTED;
-}
index 310573c..6db9c17 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: copy.c,v 1.30 2004/08/15 16:38:59 chorns Exp $
+/* $Id: copy.c,v 1.31 2004/08/25 15:08:28 navaraf Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -22,7 +22,7 @@
 static PFN_TYPE CcZeroPage = 0;
 
 #define MAX_ZERO_LENGTH        (256 * 1024)
-#define MAX_RW_LENGTH  (64 * 1024)
+#define MAX_RW_LENGTH  (256 * 1024)
 
 #if defined(__GNUC__)
 void * alloca(size_t size);
@@ -119,7 +119,7 @@ ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
           */
          current2 = current;
          current_size = 0;
-         while (current2 != NULL && !current2->Valid)
+         while (current2 != NULL && !current2->Valid && current_size < MAX_RW_LENGTH)
            {
              current2 = current2->NextInChain;
              current_size += Bcb->CacheSegmentSize;
@@ -131,8 +131,9 @@ ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
           MmInitializeMdl(Mdl, NULL, current_size);
          Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
          current2 = current;
+         current_size = 0;
          MdlPages = (PPFN_TYPE)(Mdl + 1);
-         while (current2 != NULL && !current2->Valid)
+         while (current2 != NULL && !current2->Valid && current_size < MAX_RW_LENGTH)
            {
              PVOID address = current2->BaseAddress;
              for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++, address += PAGE_SIZE)
@@ -140,6 +141,7 @@ ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
                  *MdlPages++ = MmGetPfnForProcess(NULL, address);
                }
              current2 = current2->NextInChain;
+             current_size += Bcb->CacheSegmentSize;
            }
 
          /*
@@ -157,7 +159,10 @@ ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
             KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
             Status = Iosb.Status;
          }
-          MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);            
+          if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
+          {
+            MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+         }
          if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
            {
              while (current != NULL)
@@ -168,7 +173,8 @@ ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
                }
              return(Status);
            }
-         while (current != NULL && !current->Valid)
+         current_size = 0;
+         while (current != NULL && !current->Valid && current_size < MAX_RW_LENGTH)
            {
              previous = current;
              current = current->NextInChain;
@@ -185,6 +191,7 @@ ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
 #endif
              Length = Length - TempLength; 
              CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
+             current_size += Bcb->CacheSegmentSize;
            }
        }
     }
index 19d6c2f..09b490b 100644 (file)
 #define NDEBUG
 #include <internal/debug.h>
 
+#ifndef VACB_MAPPING_GRANULARITY
+#define VACB_MAPPING_GRANULARITY (256 * 1024)
+#endif
 /* GLOBALS   *****************************************************************/
 
 extern FAST_MUTEX ViewLock;
@@ -42,7 +46,7 @@ CcGetDirtyPages (
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 PFILE_OBJECT
 STDCALL
@@ -50,8 +54,8 @@ CcGetFileObjectFromBcb (
        IN      PVOID   Bcb
        )
 {
-       UNIMPLEMENTED;
-       return 0;
+       PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb;
+       return iBcb->CacheSegment->Bcb->FileObject;
 }
 
 /*
@@ -84,7 +88,7 @@ CcInitializeCacheMap (
        IN      PVOID                           LazyWriterContext
        )
 {
-       UNIMPLEMENTED;
+    CcRosInitializeFileCache(FileObject, VACB_MAPPING_GRANULARITY);
 }
 
 /*
@@ -139,7 +143,13 @@ CcSetFileSizes (IN PFILE_OBJECT FileObject,
          (ULONG)FileSizes->ValidDataLength.QuadPart);
 
   Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-  assert(Bcb);
+
+  /*
+   * It is valid to call this function on file objects that weren't
+   * initialized for caching. In this case it's simple no-op.
+   */
+  if (Bcb == NULL)
+     return;
  
   if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart)
   {
@@ -226,6 +236,10 @@ CcUninitializeCacheMap (
        IN      PCACHE_UNINITIALIZE_EVENT       UninitializeCompleteEvent OPTIONAL
        )
 {
+#if 0
        UNIMPLEMENTED;
        return FALSE;
+#else
+    return CcRosReleaseFileCache(FileObject);
+#endif
 }
index 5cbcff0..8d37777 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pin.c,v 1.16 2004/08/15 16:39:00 chorns Exp $
+/* $Id: pin.c,v 1.17 2004/08/25 15:08:29 navaraf Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -97,10 +97,13 @@ CcMapData (IN PFILE_OBJECT FileObject,
       return FALSE;
     }
   memset(iBcb, 0, sizeof(INTERNAL_BCB));
+  iBcb->PFCB.NodeTypeCode = 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
+  iBcb->PFCB.NodeByteSize = sizeof(PUBLIC_BCB);
+  iBcb->PFCB.MappedLength = Length;
+  iBcb->PFCB.MappedFileOffset = *FileOffset;
   iBcb->CacheSegment = CacheSeg;
   iBcb->Dirty = FALSE;
-  iBcb->PFCB.MappedLength = Length;
-  iBcb->PFCB.MappedFileOffset.QuadPart = FileOffset->QuadPart;
+  iBcb->RefCount = 1;
   *pBcb = (PVOID)iBcb;
   return(TRUE);
 }
@@ -118,8 +121,8 @@ CcPinMappedData (
        OUT     PVOID                   * Bcb
        )
 {
-       UNIMPLEMENTED;
-       return FALSE;
+  /* no-op for current implementation. */
+  return TRUE;
 }
 
 /*
@@ -136,8 +139,14 @@ CcPinRead (
        OUT     PVOID                   * Buffer
        )
 {
-       UNIMPLEMENTED;
-       return FALSE;
+  if (CcMapData(FileObject, FileOffset, Length, Wait, Bcb, Buffer))
+  {
+    if (CcPinMappedData(FileObject, FileOffset, Length, Wait, Bcb))
+      return TRUE;
+    else
+      CcUnpinData(Bcb);
+  }
+  return FALSE;
 }
 
 /*
@@ -155,8 +164,15 @@ CcPreparePinWrite (
        OUT     PVOID                   * Buffer
        )
 {
-       UNIMPLEMENTED;
-       return FALSE;
+        /*
+         * FIXME: This is function is similar to CcPinRead, but doesn't
+         * read the data if they're not present. Instead it should just
+         * prepare the cache segments and zero them out if Zero == TRUE.
+         *
+         * For now calling CcPinRead is better than returning error or
+         * just having UNIMPLEMENTED here.
+         */
+        return CcPinRead(FileObject, FileOffset, Length, Wait, Bcb, Buffer);
 }
 
 /*
@@ -179,8 +195,11 @@ CcUnpinData (IN PVOID Bcb)
 {
   PINTERNAL_BCB iBcb = Bcb;
   CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE, 
-                          iBcb->Dirty, FALSE);
-  ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
+                           iBcb->Dirty, FALSE);
+  if (--iBcb->RefCount == 0)
+  {
+    ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
+  }
 }
 
 /*
@@ -195,3 +214,54 @@ CcUnpinDataForThread (
 {
        UNIMPLEMENTED;
 }
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+CcRepinBcb (
+       IN      PVOID   Bcb
+       )
+{
+  PINTERNAL_BCB iBcb = Bcb;
+  iBcb->RefCount++;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+STDCALL
+CcUnpinRepinnedBcb (
+       IN      PVOID                   Bcb,
+       IN      BOOLEAN                 WriteThrough,
+       IN      PIO_STATUS_BLOCK        IoStatus
+       )
+{
+  PINTERNAL_BCB iBcb = Bcb;
+
+  if (--iBcb->RefCount == 0)
+    {
+      IoStatus->Information = 0;
+      if (WriteThrough)
+        {
+          ExAcquireFastMutex(&iBcb->CacheSegment->Lock);
+          if (iBcb->CacheSegment->Dirty)
+            {
+              IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment);
+            }
+          else
+            {
+              IoStatus->Status = STATUS_SUCCESS;
+            }
+          ExReleaseFastMutex(&iBcb->CacheSegment->Lock);
+        }
+      else
+        {
+          IoStatus->Status = STATUS_SUCCESS;
+        }
+
+      ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
+    }
+}
index 5989b26..be59a7d 100644 (file)
@@ -16,7 +16,7 @@
  *  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.76 2004/08/15 16:39:00 chorns Exp $
+/* $Id: view.c,v 1.77 2004/08/25 15:08:29 navaraf Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/cc/view.c
@@ -113,7 +113,7 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg);
 
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS STATIC
+NTSTATUS
 CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment)
 {
   NTSTATUS Status;
index 8e9f471..da9c518 100644 (file)
 #define  SAM_REG_FILE                  L"\\SystemRoot\\System32\\Config\\SAM"
 #define  SEC_REG_FILE                  L"\\SystemRoot\\System32\\Config\\SECURITY"
 
-#define  REG_SYSTEM_FILE_NAME          L"\\SYSTEM"
-#define  REG_SOFTWARE_FILE_NAME                L"\\SOFTWARE"
-#define  REG_DEFAULT_USER_FILE_NAME    L"\\DEFAULT"
-#define  REG_SAM_FILE_NAME             L"\\SAM"
-#define  REG_SEC_FILE_NAME             L"\\SECURITY"
+#define  REG_SYSTEM_FILE_NAME          L"\\system"
+#define  REG_SOFTWARE_FILE_NAME                L"\\software"
+#define  REG_DEFAULT_USER_FILE_NAME    L"\\default"
+#define  REG_SAM_FILE_NAME             L"\\sam"
+#define  REG_SEC_FILE_NAME             L"\\security"
 
 #define  REG_BLOCK_SIZE                4096
 #define  REG_HBIN_DATA_OFFSET          32
index 1601c4a..a50c7e4 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __INCLUDE_INTERNAL_CC_H
 #define __INCLUDE_INTERNAL_CC_H
 
-/* $Id: cc.h,v 1.20 2004/08/01 21:57:34 navaraf Exp $ */
+/* $Id: cc.h,v 1.21 2004/08/25 15:08:29 navaraf Exp $ */
 #include <ddk/ntifs.h>
 #include <reactos/bugcodes.h>
 
@@ -59,12 +59,16 @@ typedef struct _INTERNAL_BCB
   PUBLIC_BCB PFCB;
   PCACHE_SEGMENT CacheSegment;
   BOOLEAN Dirty;
+  CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
 } INTERNAL_BCB, *PINTERNAL_BCB;
 
 VOID STDCALL
 CcMdlReadCompleteDev (IN PMDL          MdlChain,
                      IN PDEVICE_OBJECT DeviceObject);
 
+NTSTATUS
+CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment);
+
 NTSTATUS
 CcRosGetCacheSegment(PBCB Bcb,
                     ULONG FileOffset,