* Sync up to trunk head (r60691).
[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_DBGBREAK();
125 }
126
127 BOOLEAN
128 NTAPI
129 CcCopyWrite(IN PFILE_OBJECT FileObject,
130 IN PLARGE_INTEGER FileOffset,
131 IN ULONG Length,
132 IN BOOLEAN Wait,
133 IN PVOID Buffer)
134 {
135 INT Count = 0;
136 BOOLEAN Result;
137 PNOCC_BCB Bcb;
138 PVOID WriteBuf;
139 ULONG WriteLen;
140 LARGE_INTEGER CurrentOffset = *FileOffset;
141 LARGE_INTEGER EndOffset;
142 LARGE_INTEGER NextOffset;
143
144 EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
145
146 DPRINT("CcCopyWrite(%x,%x,%d,%d,%x)\n",
147 FileObject,
148 FileOffset->LowPart,
149 Length,
150 Wait,
151 Buffer);
152
153 while (CurrentOffset.QuadPart < EndOffset.QuadPart)
154 {
155 NextOffset.HighPart = CurrentOffset.HighPart;
156 NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
157 DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
158 WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
159
160 DPRINT("Copying %x bytes from %08x%08x\n",
161 WriteLen,
162 CurrentOffset.u.HighPart,
163 CurrentOffset.u.LowPart);
164
165 DPRINT("CcPreparePinWrite\n");
166
167 Result = CcPreparePinWrite(FileObject,
168 &CurrentOffset,
169 WriteLen,
170 FALSE,
171 Wait ? PIN_WAIT : PIN_IF_BCB,
172 (PVOID *)&Bcb, &WriteBuf);
173
174 DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
175 if (!Result)
176 {
177 DPRINT1("CcPreparePinWrite Failed?\n");
178 if (Wait)
179 RtlRaiseStatus(STATUS_NOT_MAPPED_DATA);
180 else
181 return FALSE;
182 }
183
184 DPRINT("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n",
185 Bcb - CcCacheSections,
186 WriteBuf,
187 Bcb->BaseAddress);
188
189 //MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
190 RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
191 Count += WriteLen;
192 Length -= WriteLen;
193 CurrentOffset = NextOffset;
194 Bcb->Dirty = TRUE;
195 CcUnpinData(Bcb);
196 }
197
198 DPRINT("Done with CcCopyWrite\n");
199
200 return TRUE;
201 }
202
203 VOID
204 NTAPI
205 CcFastCopyWrite(IN PFILE_OBJECT FileObject,
206 IN ULONG FileOffset,
207 IN ULONG Length,
208 IN PVOID Buffer)
209 {
210 UNIMPLEMENTED_DBGBREAK();
211 }
212
213 BOOLEAN
214 NTAPI
215 CcCanIWrite(IN PFILE_OBJECT FileObject,
216 IN ULONG BytesToWrite,
217 IN BOOLEAN Wait,
218 IN UCHAR Retrying)
219 {
220 UNIMPLEMENTED_DBGBREAK();
221 return FALSE;
222 }
223
224 VOID
225 NTAPI
226 CcDeferWrite(IN PFILE_OBJECT FileObject,
227 IN PCC_POST_DEFERRED_WRITE PostRoutine,
228 IN PVOID Context1,
229 IN PVOID Context2,
230 IN ULONG BytesToWrite,
231 IN BOOLEAN Retrying)
232 {
233 UNIMPLEMENTED_DBGBREAK();
234 }
235
236 /* EOF */