[NTOS:MM] Use inline functions to acquire/release the PFN lock.
[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 RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
190 Count += WriteLen;
191 Length -= WriteLen;
192 CurrentOffset = NextOffset;
193 Bcb->Dirty = TRUE;
194 CcUnpinData(Bcb);
195 }
196
197 DPRINT("Done with CcCopyWrite\n");
198
199 return TRUE;
200 }
201
202 VOID
203 NTAPI
204 CcFastCopyWrite(IN PFILE_OBJECT FileObject,
205 IN ULONG FileOffset,
206 IN ULONG Length,
207 IN PVOID Buffer)
208 {
209 UNIMPLEMENTED_DBGBREAK();
210 }
211
212 BOOLEAN
213 NTAPI
214 CcCanIWrite(IN PFILE_OBJECT FileObject,
215 IN ULONG BytesToWrite,
216 IN BOOLEAN Wait,
217 IN UCHAR Retrying)
218 {
219 UNIMPLEMENTED_DBGBREAK();
220 return FALSE;
221 }
222
223 VOID
224 NTAPI
225 CcDeferWrite(IN PFILE_OBJECT FileObject,
226 IN PCC_POST_DEFERRED_WRITE PostRoutine,
227 IN PVOID Context1,
228 IN PVOID Context2,
229 IN ULONG BytesToWrite,
230 IN BOOLEAN Retrying)
231 {
232 UNIMPLEMENTED_DBGBREAK();
233 }
234
235 /* EOF */