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