xref: /reactos/ntoskrnl/cache/copysup.c (revision c2c66aff)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * COPYRIGHT:       See COPYING in the top level directory
3*c2c66affSColin Finck  * PROJECT:         ReactOS Kernel
4*c2c66affSColin Finck  * FILE:            ntoskrnl/cache/copysup.c
5*c2c66affSColin Finck  * PURPOSE:         Logging and configuration routines
6*c2c66affSColin Finck  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
7*c2c66affSColin Finck  */
8*c2c66affSColin Finck 
9*c2c66affSColin Finck /* INCLUDES *******************************************************************/
10*c2c66affSColin Finck 
11*c2c66affSColin Finck #include <ntoskrnl.h>
12*c2c66affSColin Finck #include "newcc.h"
13*c2c66affSColin Finck #include "section/newmm.h"
14*c2c66affSColin Finck #define NDEBUG
15*c2c66affSColin Finck #include <debug.h>
16*c2c66affSColin Finck 
17*c2c66affSColin Finck /* GLOBALS ********************************************************************/
18*c2c66affSColin Finck 
19*c2c66affSColin Finck ULONG CcFastMdlReadWait;
20*c2c66affSColin Finck ULONG CcFastMdlReadNotPossible;
21*c2c66affSColin Finck ULONG CcFastReadNotPossible;
22*c2c66affSColin Finck ULONG CcFastReadWait;
23*c2c66affSColin Finck ULONG CcFastReadNoWait;
24*c2c66affSColin Finck ULONG CcFastReadResourceMiss;
25*c2c66affSColin Finck 
26*c2c66affSColin Finck #define TAG_COPY_READ  TAG('C', 'o', 'p', 'y')
27*c2c66affSColin Finck #define TAG_COPY_WRITE TAG('R', 'i', 't', 'e')
28*c2c66affSColin Finck 
29*c2c66affSColin Finck /* FUNCTIONS ******************************************************************/
30*c2c66affSColin Finck 
31*c2c66affSColin Finck /*
32*c2c66affSColin Finck 
33*c2c66affSColin Finck CcCopyRead can be called for a region of any size and alignment, so we must
34*c2c66affSColin Finck crawl the cache space, focusing one cache stripe after another and using
35*c2c66affSColin Finck RtlCopyMemory to copy the input data into the cache.  In constrained memory,
36*c2c66affSColin Finck pages faulted into new stripes are often taken from old stripes, causing the
37*c2c66affSColin Finck old stripes to be flushed right away.  In the case of many short buffered in
38*c2c66affSColin Finck order writes, like the ones generated by stdio, this can be really efficient.
39*c2c66affSColin Finck 
40*c2c66affSColin Finck */
41*c2c66affSColin Finck BOOLEAN
42*c2c66affSColin Finck NTAPI
CcCopyRead(IN PFILE_OBJECT FileObject,IN PLARGE_INTEGER FileOffset,IN ULONG Length,IN BOOLEAN Wait,OUT PVOID Buffer,OUT PIO_STATUS_BLOCK IoStatus)43*c2c66affSColin Finck CcCopyRead(IN PFILE_OBJECT FileObject,
44*c2c66affSColin Finck            IN PLARGE_INTEGER FileOffset,
45*c2c66affSColin Finck            IN ULONG Length,
46*c2c66affSColin Finck            IN BOOLEAN Wait,
47*c2c66affSColin Finck            OUT PVOID Buffer,
48*c2c66affSColin Finck            OUT PIO_STATUS_BLOCK IoStatus)
49*c2c66affSColin Finck {
50*c2c66affSColin Finck     PCHAR ReadBuffer;
51*c2c66affSColin Finck     ULONG ReadLen;
52*c2c66affSColin Finck     PVOID Bcb;
53*c2c66affSColin Finck     PCHAR BufferTarget = (PCHAR)Buffer;
54*c2c66affSColin Finck     LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
55*c2c66affSColin Finck 
56*c2c66affSColin Finck     DPRINT("CcCopyRead(%x,%x,%d,%d,%x)\n",
57*c2c66affSColin Finck            FileObject,
58*c2c66affSColin Finck            FileOffset->LowPart,
59*c2c66affSColin Finck            Length,
60*c2c66affSColin Finck            Wait,
61*c2c66affSColin Finck            Buffer);
62*c2c66affSColin Finck 
63*c2c66affSColin Finck     CacheOffset.QuadPart = FileOffset->QuadPart;
64*c2c66affSColin Finck     EndOfExtent.QuadPart = FileOffset->QuadPart + Length;
65*c2c66affSColin Finck 
66*c2c66affSColin Finck     while (CacheOffset.QuadPart < EndOfExtent.QuadPart)
67*c2c66affSColin Finck     {
68*c2c66affSColin Finck         NextOffset.QuadPart = CacheOffset.QuadPart;
69*c2c66affSColin Finck         NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
70*c2c66affSColin Finck         ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
71*c2c66affSColin Finck         if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
72*c2c66affSColin Finck         {
73*c2c66affSColin Finck             ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
74*c2c66affSColin Finck         }
75*c2c66affSColin Finck 
76*c2c66affSColin Finck         DPRINT("Reading %d bytes in this go (at %08x%08x)\n",
77*c2c66affSColin Finck                ReadLen,
78*c2c66affSColin Finck                CacheOffset.HighPart,
79*c2c66affSColin Finck                CacheOffset.LowPart);
80*c2c66affSColin Finck 
81*c2c66affSColin Finck         if (!CcPinRead(FileObject,
82*c2c66affSColin Finck                        &CacheOffset,
83*c2c66affSColin Finck                        ReadLen,
84*c2c66affSColin Finck                        Wait ? PIN_WAIT : PIN_IF_BCB,
85*c2c66affSColin Finck                        &Bcb,
86*c2c66affSColin Finck                        (PVOID*)&ReadBuffer))
87*c2c66affSColin Finck         {
88*c2c66affSColin Finck             IoStatus->Status = STATUS_UNSUCCESSFUL;
89*c2c66affSColin Finck             IoStatus->Information = 0;
90*c2c66affSColin Finck             DPRINT("Failed CcCopyRead\n");
91*c2c66affSColin Finck             return FALSE;
92*c2c66affSColin Finck         }
93*c2c66affSColin Finck 
94*c2c66affSColin Finck         DPRINT("Copying %d bytes at %08x%08x\n",
95*c2c66affSColin Finck                ReadLen,
96*c2c66affSColin Finck                CacheOffset.HighPart,
97*c2c66affSColin Finck                CacheOffset.LowPart);
98*c2c66affSColin Finck 
99*c2c66affSColin Finck         RtlCopyMemory(BufferTarget, ReadBuffer, ReadLen);
100*c2c66affSColin Finck 
101*c2c66affSColin Finck         BufferTarget += ReadLen;
102*c2c66affSColin Finck 
103*c2c66affSColin Finck         CacheOffset = NextOffset;
104*c2c66affSColin Finck         CcUnpinData(Bcb);
105*c2c66affSColin Finck     }
106*c2c66affSColin Finck 
107*c2c66affSColin Finck     IoStatus->Status = STATUS_SUCCESS;
108*c2c66affSColin Finck     IoStatus->Information = Length;
109*c2c66affSColin Finck 
110*c2c66affSColin Finck     DPRINT("Done with CcCopyRead\n");
111*c2c66affSColin Finck 
112*c2c66affSColin Finck     return TRUE;
113*c2c66affSColin Finck }
114*c2c66affSColin Finck 
115*c2c66affSColin Finck VOID
116*c2c66affSColin Finck NTAPI
CcFastCopyRead(IN PFILE_OBJECT FileObject,IN ULONG FileOffset,IN ULONG Length,IN ULONG PageCount,OUT PVOID Buffer,OUT PIO_STATUS_BLOCK IoStatus)117*c2c66affSColin Finck CcFastCopyRead(IN PFILE_OBJECT FileObject,
118*c2c66affSColin Finck                IN ULONG FileOffset,
119*c2c66affSColin Finck                IN ULONG Length,
120*c2c66affSColin Finck                IN ULONG PageCount,
121*c2c66affSColin Finck                OUT PVOID Buffer,
122*c2c66affSColin Finck                OUT PIO_STATUS_BLOCK IoStatus)
123*c2c66affSColin Finck {
124*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
125*c2c66affSColin Finck }
126*c2c66affSColin Finck 
127*c2c66affSColin Finck BOOLEAN
128*c2c66affSColin Finck NTAPI
CcCopyWrite(IN PFILE_OBJECT FileObject,IN PLARGE_INTEGER FileOffset,IN ULONG Length,IN BOOLEAN Wait,IN PVOID Buffer)129*c2c66affSColin Finck CcCopyWrite(IN PFILE_OBJECT FileObject,
130*c2c66affSColin Finck             IN PLARGE_INTEGER FileOffset,
131*c2c66affSColin Finck             IN ULONG Length,
132*c2c66affSColin Finck             IN BOOLEAN Wait,
133*c2c66affSColin Finck             IN PVOID Buffer)
134*c2c66affSColin Finck {
135*c2c66affSColin Finck     INT Count = 0;
136*c2c66affSColin Finck     BOOLEAN Result;
137*c2c66affSColin Finck     PNOCC_BCB Bcb;
138*c2c66affSColin Finck     PVOID WriteBuf;
139*c2c66affSColin Finck     ULONG WriteLen;
140*c2c66affSColin Finck     LARGE_INTEGER CurrentOffset = *FileOffset;
141*c2c66affSColin Finck     LARGE_INTEGER EndOffset;
142*c2c66affSColin Finck     LARGE_INTEGER NextOffset;
143*c2c66affSColin Finck 
144*c2c66affSColin Finck     EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
145*c2c66affSColin Finck 
146*c2c66affSColin Finck     DPRINT("CcCopyWrite(%x,%x,%d,%d,%x)\n",
147*c2c66affSColin Finck            FileObject,
148*c2c66affSColin Finck            FileOffset->LowPart,
149*c2c66affSColin Finck            Length,
150*c2c66affSColin Finck            Wait,
151*c2c66affSColin Finck            Buffer);
152*c2c66affSColin Finck 
153*c2c66affSColin Finck     while (CurrentOffset.QuadPart < EndOffset.QuadPart)
154*c2c66affSColin Finck     {
155*c2c66affSColin Finck         NextOffset.HighPart = CurrentOffset.HighPart;
156*c2c66affSColin Finck         NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
157*c2c66affSColin Finck         DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
158*c2c66affSColin Finck         WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
159*c2c66affSColin Finck 
160*c2c66affSColin Finck         DPRINT("Copying %x bytes from %08x%08x\n",
161*c2c66affSColin Finck                WriteLen,
162*c2c66affSColin Finck                CurrentOffset.u.HighPart,
163*c2c66affSColin Finck                CurrentOffset.u.LowPart);
164*c2c66affSColin Finck 
165*c2c66affSColin Finck         DPRINT("CcPreparePinWrite\n");
166*c2c66affSColin Finck 
167*c2c66affSColin Finck         Result = CcPreparePinWrite(FileObject,
168*c2c66affSColin Finck                                    &CurrentOffset,
169*c2c66affSColin Finck                                    WriteLen,
170*c2c66affSColin Finck                                    FALSE,
171*c2c66affSColin Finck                                    Wait ? PIN_WAIT : PIN_IF_BCB,
172*c2c66affSColin Finck                                    (PVOID *)&Bcb, &WriteBuf);
173*c2c66affSColin Finck 
174*c2c66affSColin Finck         DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
175*c2c66affSColin Finck         if (!Result)
176*c2c66affSColin Finck         {
177*c2c66affSColin Finck             DPRINT1("CcPreparePinWrite Failed?\n");
178*c2c66affSColin Finck             if (Wait)
179*c2c66affSColin Finck                 RtlRaiseStatus(STATUS_NOT_MAPPED_DATA);
180*c2c66affSColin Finck             else
181*c2c66affSColin Finck                 return FALSE;
182*c2c66affSColin Finck         }
183*c2c66affSColin Finck 
184*c2c66affSColin Finck         DPRINT("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n",
185*c2c66affSColin Finck                Bcb - CcCacheSections,
186*c2c66affSColin Finck                WriteBuf,
187*c2c66affSColin Finck                Bcb->BaseAddress);
188*c2c66affSColin Finck 
189*c2c66affSColin Finck         RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
190*c2c66affSColin Finck         Count += WriteLen;
191*c2c66affSColin Finck         Length -= WriteLen;
192*c2c66affSColin Finck         CurrentOffset = NextOffset;
193*c2c66affSColin Finck         Bcb->Dirty = TRUE;
194*c2c66affSColin Finck         CcUnpinData(Bcb);
195*c2c66affSColin Finck     }
196*c2c66affSColin Finck 
197*c2c66affSColin Finck     DPRINT("Done with CcCopyWrite\n");
198*c2c66affSColin Finck 
199*c2c66affSColin Finck     return TRUE;
200*c2c66affSColin Finck }
201*c2c66affSColin Finck 
202*c2c66affSColin Finck VOID
203*c2c66affSColin Finck NTAPI
CcFastCopyWrite(IN PFILE_OBJECT FileObject,IN ULONG FileOffset,IN ULONG Length,IN PVOID Buffer)204*c2c66affSColin Finck CcFastCopyWrite(IN PFILE_OBJECT FileObject,
205*c2c66affSColin Finck                 IN ULONG FileOffset,
206*c2c66affSColin Finck                 IN ULONG Length,
207*c2c66affSColin Finck                 IN PVOID Buffer)
208*c2c66affSColin Finck {
209*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
210*c2c66affSColin Finck }
211*c2c66affSColin Finck 
212*c2c66affSColin Finck BOOLEAN
213*c2c66affSColin Finck NTAPI
CcCanIWrite(IN PFILE_OBJECT FileObject,IN ULONG BytesToWrite,IN BOOLEAN Wait,IN UCHAR Retrying)214*c2c66affSColin Finck CcCanIWrite(IN PFILE_OBJECT FileObject,
215*c2c66affSColin Finck             IN ULONG BytesToWrite,
216*c2c66affSColin Finck             IN BOOLEAN Wait,
217*c2c66affSColin Finck             IN UCHAR Retrying)
218*c2c66affSColin Finck {
219*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
220*c2c66affSColin Finck     return FALSE;
221*c2c66affSColin Finck }
222*c2c66affSColin Finck 
223*c2c66affSColin Finck VOID
224*c2c66affSColin Finck NTAPI
CcDeferWrite(IN PFILE_OBJECT FileObject,IN PCC_POST_DEFERRED_WRITE PostRoutine,IN PVOID Context1,IN PVOID Context2,IN ULONG BytesToWrite,IN BOOLEAN Retrying)225*c2c66affSColin Finck CcDeferWrite(IN PFILE_OBJECT FileObject,
226*c2c66affSColin Finck              IN PCC_POST_DEFERRED_WRITE PostRoutine,
227*c2c66affSColin Finck              IN PVOID Context1,
228*c2c66affSColin Finck              IN PVOID Context2,
229*c2c66affSColin Finck              IN ULONG BytesToWrite,
230*c2c66affSColin Finck              IN BOOLEAN Retrying)
231*c2c66affSColin Finck {
232*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
233*c2c66affSColin Finck }
234*c2c66affSColin Finck 
235*c2c66affSColin Finck /* EOF */
236