Sync with trunk r63935.
[reactos.git] / ntoskrnl / cache / copysup.c
index 2f8a954..8820779 100644 (file)
@@ -28,6 +28,16 @@ ULONG CcFastReadResourceMiss;
 
 /* FUNCTIONS ******************************************************************/
 
+/*
+
+CcCopyRead can be called for a region of any size and alignment, so we must
+crawl the cache space, focusing one cache stripe after another and using
+RtlCopyMemory to copy the input data into the cache.  In constrained memory,
+pages faulted into new stripes are often taken from old stripes, causing the
+old stripes to be flushed right away.  In the case of many short buffered in
+order writes, like the ones generated by stdio, this can be really efficient.
+
+*/
 BOOLEAN
 NTAPI
 CcCopyRead(IN PFILE_OBJECT FileObject,
@@ -42,61 +52,63 @@ CcCopyRead(IN PFILE_OBJECT FileObject,
     PVOID Bcb;
     PCHAR BufferTarget = (PCHAR)Buffer;
     LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
-    
-    DPRINT
-       ("CcCopyRead(%x,%x,%d,%d,%x)\n", 
-        FileObject, 
-        FileOffset->LowPart,
-        Length,
-        Wait,
-        Buffer);
-    
+
+    DPRINT("CcCopyRead(%x,%x,%d,%d,%x)\n",
+           FileObject,
+           FileOffset->LowPart,
+           Length,
+           Wait,
+           Buffer);
+
     CacheOffset.QuadPart = FileOffset->QuadPart;
     EndOfExtent.QuadPart = FileOffset->QuadPart + Length;
 
     while (CacheOffset.QuadPart < EndOfExtent.QuadPart)
     {
-               NextOffset.QuadPart = CacheOffset.QuadPart;
-               NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
-               ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
-               if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
-               {
-                       ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
-               }
-               
-               DPRINT("Reading %d bytes in this go (at %08x%08x)\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
-               
-               if (!CcPinRead
-                       (FileObject,
-                        &CacheOffset,
-                        ReadLen,
-                        Wait ? PIN_WAIT : PIN_IF_BCB,
-                        &Bcb,
-                        (PVOID*)&ReadBuffer))
-               {
-                       IoStatus->Status = STATUS_UNSUCCESSFUL;
-                       IoStatus->Information = 0;
-                       DPRINT("Failed CcCopyRead\n");
-                       return FALSE;
-               }
-               
-               DPRINT1("Copying %d bytes at %08x%08x\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
-               RtlCopyMemory
-                       (BufferTarget,
-                        ReadBuffer,
-                        ReadLen);
-               
-               BufferTarget += ReadLen;
-               
-               CacheOffset = NextOffset;
-               CcUnpinData(Bcb);
+        NextOffset.QuadPart = CacheOffset.QuadPart;
+        NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
+        ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
+        if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
+        {
+            ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
+        }
+
+        DPRINT("Reading %d bytes in this go (at %08x%08x)\n",
+               ReadLen,
+               CacheOffset.HighPart,
+               CacheOffset.LowPart);
+
+        if (!CcPinRead(FileObject,
+                       &CacheOffset,
+                       ReadLen,
+                       Wait ? PIN_WAIT : PIN_IF_BCB,
+                       &Bcb,
+                       (PVOID*)&ReadBuffer))
+        {
+            IoStatus->Status = STATUS_UNSUCCESSFUL;
+            IoStatus->Information = 0;
+            DPRINT("Failed CcCopyRead\n");
+            return FALSE;
+        }
+
+        DPRINT("Copying %d bytes at %08x%08x\n",
+               ReadLen,
+               CacheOffset.HighPart,
+               CacheOffset.LowPart);
+
+        RtlCopyMemory(BufferTarget, ReadBuffer, ReadLen);
+
+        BufferTarget += ReadLen;
+
+        CacheOffset = NextOffset;
+        CcUnpinData(Bcb);
     }
-       
+
     IoStatus->Status = STATUS_SUCCESS;
     IoStatus->Information = Length;
-    
+
     DPRINT("Done with CcCopyRead\n");
-    
+
     return TRUE;
 }
 
@@ -109,8 +121,7 @@ CcFastCopyRead(IN PFILE_OBJECT FileObject,
                OUT PVOID Buffer,
                OUT PIO_STATUS_BLOCK IoStatus)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
 }
 
 BOOLEAN
@@ -121,58 +132,72 @@ CcCopyWrite(IN PFILE_OBJECT FileObject,
             IN BOOLEAN Wait,
             IN PVOID Buffer)
 {
-       INT Count = 0;
-       BOOLEAN Result;
-       PNOCC_BCB Bcb;
-       PVOID WriteBuf;
-       ULONG WriteLen;
-       LARGE_INTEGER CurrentOffset = *FileOffset;
-       LARGE_INTEGER EndOffset;
-       LARGE_INTEGER NextOffset;
-
-       EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
-
-       DPRINT
-               ("CcCopyWrite(%x,%x,%d,%d,%x)\n", 
-                FileObject, 
-                FileOffset->LowPart,
-                Length,
-                Wait,
-                Buffer);
-
-       while (CurrentOffset.QuadPart < EndOffset.QuadPart)
-       {
-               NextOffset.HighPart = CurrentOffset.HighPart;
-               NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
-               DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
-               WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
-               DPRINT("Copying %x bytes from %08x%08x\n", 
-                               WriteLen, 
-                               CurrentOffset.u.HighPart, CurrentOffset.u.LowPart);
-               DPRINT("CcPreparePinWrite\n");
-               Result = CcPreparePinWrite
-                       (FileObject, &CurrentOffset, WriteLen, FALSE, Wait ? PIN_WAIT : PIN_IF_BCB, 
-                        (PVOID *)&Bcb, &WriteBuf);
-               DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
-               if (!Result)
-               {
-                       DPRINT1("CcPreparePinWrite Failed?\n");
-                       if (Wait) RtlRaiseStatus(STATUS_NOT_MAPPED_DATA); else return FALSE;
-               }
-               DPRINT1("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n", Bcb - CcCacheSections, WriteBuf, Bcb->BaseAddress);
-               
-               //MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
-               RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
-               Count += WriteLen;
-               Length -= WriteLen;
-               CurrentOffset = NextOffset;
-               Bcb->Dirty = TRUE;
-               CcUnpinData(Bcb);
-       }
-
-       DPRINT("Done with CcCopyWrite\n");
-
-       return TRUE;
+    INT Count = 0;
+    BOOLEAN Result;
+    PNOCC_BCB Bcb;
+    PVOID WriteBuf;
+    ULONG WriteLen;
+    LARGE_INTEGER CurrentOffset = *FileOffset;
+    LARGE_INTEGER EndOffset;
+    LARGE_INTEGER NextOffset;
+
+    EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
+
+    DPRINT("CcCopyWrite(%x,%x,%d,%d,%x)\n",
+           FileObject,
+           FileOffset->LowPart,
+           Length,
+           Wait,
+           Buffer);
+
+    while (CurrentOffset.QuadPart < EndOffset.QuadPart)
+    {
+        NextOffset.HighPart = CurrentOffset.HighPart;
+        NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
+        DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
+        WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
+
+        DPRINT("Copying %x bytes from %08x%08x\n",
+               WriteLen,
+               CurrentOffset.u.HighPart,
+               CurrentOffset.u.LowPart);
+
+        DPRINT("CcPreparePinWrite\n");
+
+        Result = CcPreparePinWrite(FileObject,
+                                   &CurrentOffset,
+                                   WriteLen,
+                                   FALSE,
+                                   Wait ? PIN_WAIT : PIN_IF_BCB,
+                                   (PVOID *)&Bcb, &WriteBuf);
+
+        DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
+        if (!Result)
+        {
+            DPRINT1("CcPreparePinWrite Failed?\n");
+            if (Wait)
+                RtlRaiseStatus(STATUS_NOT_MAPPED_DATA);
+            else
+                return FALSE;
+        }
+
+        DPRINT("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n",
+               Bcb - CcCacheSections,
+               WriteBuf,
+               Bcb->BaseAddress);
+
+        //MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
+        RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
+        Count += WriteLen;
+        Length -= WriteLen;
+        CurrentOffset = NextOffset;
+        Bcb->Dirty = TRUE;
+        CcUnpinData(Bcb);
+    }
+
+    DPRINT("Done with CcCopyWrite\n");
+
+    return TRUE;
 }
 
 VOID
@@ -182,8 +207,7 @@ CcFastCopyWrite(IN PFILE_OBJECT FileObject,
                 IN ULONG Length,
                 IN PVOID Buffer)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
 }
 
 BOOLEAN
@@ -193,8 +217,7 @@ CcCanIWrite(IN PFILE_OBJECT FileObject,
             IN BOOLEAN Wait,
             IN UCHAR Retrying)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return FALSE;
 }
 
@@ -207,8 +230,7 @@ CcDeferWrite(IN PFILE_OBJECT FileObject,
              IN ULONG BytesToWrite,
              IN BOOLEAN Retrying)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
 }
 
 /* EOF */