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