Add missing processor architecture cases
[reactos.git] / reactos / ntoskrnl / cc / pin.c
index 285743e..b845c6c 100644 (file)
@@ -1,40 +1,28 @@
-/* $Id: pin.c,v 1.4 2002/08/14 20:58:32 dwelch Exp $
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/cc/pin.c
  * PURPOSE:         Implements cache managers pinning interface
- * PROGRAMMER:      Hartmut Birr
- * UPDATE HISTORY:
- *                  Created 05.10.2001
+ *
+ * PROGRAMMERS:     Hartmut Birr
  */
 
 /* INCLUDES ******************************************************************/
 
-#include <ddk/ntddk.h>
-#include <ddk/ntifs.h>
-#include <internal/mm.h>
-#include <internal/cc.h>
-#include <internal/pool.h>
-#include <internal/io.h>
-#include <ntos/minmax.h>
-
+#include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
 /* GLOBALS *******************************************************************/
 
-#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
+extern NPAGED_LOOKASIDE_LIST iBcbLookasideList;
 
 /* FUNCTIONS *****************************************************************/
 
-typedef struct _INTERNAL_BCB
-{
-  PUBLIC_BCB PFCB;
-  PCACHE_SEGMENT CacheSegment;
-  BOOLEAN Dirty;
-} INTERNAL_BCB, *PINTERNAL_BCB;
-
+/*
+ * @implemented
+ */
 BOOLEAN STDCALL
 CcMapData (IN PFILE_OBJECT FileObject,
           IN PLARGE_INTEGER FileOffset,
@@ -50,18 +38,19 @@ CcMapData (IN PFILE_OBJECT FileObject,
   NTSTATUS Status;
   PINTERNAL_BCB iBcb;
   ULONG ROffset;
-  
-  DPRINT("CcMapData(FileObject %x, FileOffset %d, Length %d, Wait %d,"
-        " pBcb %x, pBuffer %x)\n", FileObject, (ULONG)FileOffset->QuadPart,
+
+  DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %d, Wait %d,"
+        " pBcb 0x%p, pBuffer 0x%p)\n", FileObject, FileOffset->QuadPart,
         Length, Wait, pBcb, pBuffer);
-  
-  ReadOffset = FileOffset->QuadPart;
-  Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
-  
-  DPRINT("AllocationSize %d, FileSize %d\n",
-         (ULONG)Bcb->AllocationSize.QuadPart,
-         (ULONG)Bcb->FileSize.QuadPart);
-  
+
+  ReadOffset = (ULONG)FileOffset->QuadPart;
+  Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+  ASSERT(Bcb);
+
+  DPRINT("AllocationSize %I64x, FileSize %I64x\n",
+         Bcb->AllocationSize.QuadPart,
+         Bcb->FileSize.QuadPart);
+
   if (ReadOffset % Bcb->CacheSegmentSize + Length > Bcb->CacheSegmentSize)
     {
       return(FALSE);
@@ -85,33 +74,100 @@ CcMapData (IN PFILE_OBJECT FileObject,
        }
       if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
        {
+          CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
          return(FALSE);
        }
     }
-  *pBuffer += ReadOffset % Bcb->CacheSegmentSize;
-  iBcb = ExAllocatePool (NonPagedPool, sizeof(INTERNAL_BCB));
+
+  *pBuffer = (PVOID)((ULONG_PTR)(*pBuffer) + (ReadOffset % Bcb->CacheSegmentSize));
+  iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList);
   if (iBcb == NULL)
     {
       CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
       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);
 }
 
-VOID STDCALL
-CcUnpinData (IN PVOID Bcb)
+/*
+ * @unimplemented
+ */
+BOOLEAN
+STDCALL
+CcPinMappedData (
+       IN      PFILE_OBJECT            FileObject,
+       IN      PLARGE_INTEGER          FileOffset,
+       IN      ULONG                   Length,
+       IN      ULONG                   Flags,
+       OUT     PVOID                   * Bcb
+       )
 {
-  PINTERNAL_BCB iBcb = Bcb;
-  CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE, 
-                          iBcb->Dirty, FALSE);
-  ExFreePool(iBcb);
+  /* no-op for current implementation. */
+  return TRUE;
 }
 
+/*
+ * @unimplemented
+ */
+BOOLEAN
+STDCALL
+CcPinRead (
+       IN      PFILE_OBJECT            FileObject,
+       IN      PLARGE_INTEGER          FileOffset,
+       IN      ULONG                   Length,
+       IN      ULONG                   Flags,
+       OUT     PVOID                   * Bcb,
+       OUT     PVOID                   * Buffer
+       )
+{
+  if (CcMapData(FileObject, FileOffset, Length, Flags, Bcb, Buffer))
+  {
+    if (CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb))
+      return TRUE;
+    else
+      CcUnpinData(Bcb);
+  }
+  return FALSE;
+}
+
+/*
+ * @unimplemented
+ */
+BOOLEAN
+STDCALL
+CcPreparePinWrite (
+       IN      PFILE_OBJECT            FileObject,
+       IN      PLARGE_INTEGER          FileOffset,
+       IN      ULONG                   Length,
+       IN      BOOLEAN                 Zero,
+       IN      ULONG                   Flags,
+       OUT     PVOID                   * Bcb,
+       OUT     PVOID                   * Buffer
+       )
+{
+        /*
+         * 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, Flags, Bcb, Buffer);
+}
+
+/*
+ * @implemented
+ */
 VOID STDCALL
 CcSetDirtyPinnedData (IN PVOID Bcb,
                      IN PLARGE_INTEGER Lsn)
@@ -120,3 +176,82 @@ CcSetDirtyPinnedData (IN PVOID Bcb,
    iBcb->Dirty = TRUE;
 }
 
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+CcUnpinData (IN PVOID Bcb)
+{
+  PINTERNAL_BCB iBcb = Bcb;
+  CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE,
+                           iBcb->Dirty, FALSE);
+  if (--iBcb->RefCount == 0)
+  {
+    ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
+  }
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+STDCALL
+CcUnpinDataForThread (
+       IN      PVOID                   Bcb,
+       IN      ERESOURCE_THREAD        ResourceThreadId
+       )
+{
+       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)
+        {
+          ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&iBcb->CacheSegment->Lock);
+          if (iBcb->CacheSegment->Dirty)
+            {
+              IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment);
+            }
+          else
+            {
+              IoStatus->Status = STATUS_SUCCESS;
+            }
+          ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&iBcb->CacheSegment->Lock);
+        }
+      else
+        {
+          IoStatus->Status = STATUS_SUCCESS;
+        }
+
+      ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
+    }
+}