[NTOSKRNL] Misc fixes to Cc:
[reactos.git] / ntoskrnl / cc / pin.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/cc/pin.c
5 * PURPOSE: Implements cache managers pinning interface
6 *
7 * PROGRAMMERS: ?
8 Pierre Schweitzer (pierre@reactos.org)
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16
17 /* GLOBALS *******************************************************************/
18
19 extern NPAGED_LOOKASIDE_LIST iBcbLookasideList;
20
21 /* FUNCTIONS *****************************************************************/
22
23 /*
24 * @implemented
25 */
26 BOOLEAN
27 NTAPI
28 CcMapData (
29 IN PFILE_OBJECT FileObject,
30 IN PLARGE_INTEGER FileOffset,
31 IN ULONG Length,
32 IN ULONG Flags,
33 OUT PVOID *pBcb,
34 OUT PVOID *pBuffer)
35 {
36 LONGLONG ReadOffset;
37 BOOLEAN Valid;
38 PROS_SHARED_CACHE_MAP SharedCacheMap;
39 PROS_VACB Vacb;
40 NTSTATUS Status;
41 PINTERNAL_BCB iBcb;
42 LONGLONG ROffset;
43
44 DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %lu, Flags 0x%lx,"
45 " pBcb 0x%p, pBuffer 0x%p)\n", FileObject, FileOffset->QuadPart,
46 Length, Flags, pBcb, pBuffer);
47
48 ReadOffset = FileOffset->QuadPart;
49
50 ASSERT(FileObject);
51 ASSERT(FileObject->SectionObjectPointer);
52 ASSERT(FileObject->SectionObjectPointer->SharedCacheMap);
53
54 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
55 ASSERT(SharedCacheMap);
56
57 DPRINT("SectionSize %I64x, FileSize %I64x\n",
58 SharedCacheMap->SectionSize.QuadPart,
59 SharedCacheMap->FileSize.QuadPart);
60
61 if (ReadOffset % VACB_MAPPING_GRANULARITY + Length > VACB_MAPPING_GRANULARITY)
62 {
63 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
64 FileObject, FileOffset, Length, Flags);
65 ExRaiseStatus(STATUS_INVALID_PARAMETER);
66 return FALSE;
67 }
68
69 ROffset = ROUND_DOWN(ReadOffset, VACB_MAPPING_GRANULARITY);
70 Status = CcRosRequestVacb(SharedCacheMap,
71 ROffset,
72 pBuffer,
73 &Valid,
74 &Vacb);
75 if (!NT_SUCCESS(Status))
76 {
77 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
78 FileObject, FileOffset, Length, Flags);
79 ExRaiseStatus(Status);
80 return FALSE;
81 }
82
83 if (!Valid)
84 {
85 if (!(Flags & MAP_WAIT))
86 {
87 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
88 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
89 FileObject, FileOffset, Length, Flags);
90 return FALSE;
91 }
92
93 Status = CcReadVirtualAddress(Vacb);
94 if (!NT_SUCCESS(Status))
95 {
96 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
97 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
98 FileObject, FileOffset, Length, Flags);
99 ExRaiseStatus(Status);
100 return FALSE;
101 }
102 }
103
104 *pBuffer = (PUCHAR)*pBuffer + ReadOffset % VACB_MAPPING_GRANULARITY;
105 iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList);
106 if (iBcb == NULL)
107 {
108 CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
109 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
110 FileObject, FileOffset, Length, Flags);
111 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
112 return FALSE;
113 }
114
115 RtlZeroMemory(iBcb, sizeof(*iBcb));
116 iBcb->PFCB.NodeTypeCode = 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
117 iBcb->PFCB.NodeByteSize = sizeof(PUBLIC_BCB);
118 iBcb->PFCB.MappedLength = Length;
119 iBcb->PFCB.MappedFileOffset = *FileOffset;
120 iBcb->Vacb = Vacb;
121 iBcb->Dirty = FALSE;
122 iBcb->Pinned = FALSE;
123 iBcb->RefCount = 1;
124 ExInitializeResourceLite(&iBcb->Lock);
125 *pBcb = (PVOID)iBcb;
126
127 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> TRUE Bcb=%p\n",
128 FileObject, FileOffset, Length, Flags, iBcb);
129 return TRUE;
130 }
131
132 /*
133 * @unimplemented
134 */
135 BOOLEAN
136 NTAPI
137 CcPinMappedData (
138 IN PFILE_OBJECT FileObject,
139 IN PLARGE_INTEGER FileOffset,
140 IN ULONG Length,
141 IN ULONG Flags,
142 OUT PVOID * Bcb)
143 {
144 PROS_SHARED_CACHE_MAP SharedCacheMap;
145
146 CCTRACE(CC_API_DEBUG, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
147 FileObject, FileOffset, Length, Flags);
148
149 ASSERT(FileObject);
150 ASSERT(FileObject->SectionObjectPointer);
151 ASSERT(FileObject->SectionObjectPointer->SharedCacheMap);
152
153 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
154 ASSERT(SharedCacheMap);
155 ASSERT(SharedCacheMap->PinAccess);
156
157 /* no-op for current implementation. */
158 return TRUE;
159 }
160
161 /*
162 * @unimplemented
163 */
164 BOOLEAN
165 NTAPI
166 CcPinRead (
167 IN PFILE_OBJECT FileObject,
168 IN PLARGE_INTEGER FileOffset,
169 IN ULONG Length,
170 IN ULONG Flags,
171 OUT PVOID * Bcb,
172 OUT PVOID * Buffer)
173 {
174 PINTERNAL_BCB iBcb;
175
176 CCTRACE(CC_API_DEBUG, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
177 FileObject, FileOffset, Length, Flags);
178
179 if (CcMapData(FileObject, FileOffset, Length, Flags, Bcb, Buffer))
180 {
181 if (CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb))
182 {
183 iBcb = *Bcb;
184
185 ASSERT(iBcb->Pinned == FALSE);
186
187 iBcb->Pinned = TRUE;
188 iBcb->Vacb->PinCount++;
189 CcRosReleaseVacbLock(iBcb->Vacb);
190
191 if (Flags & PIN_EXCLUSIVE)
192 {
193 ExAcquireResourceExclusiveLite(&iBcb->Lock, TRUE);
194 }
195 else
196 {
197 ExAcquireResourceSharedLite(&iBcb->Lock, TRUE);
198 }
199
200 return TRUE;
201 }
202 else
203 CcUnpinData(*Bcb);
204 }
205 return FALSE;
206 }
207
208 /*
209 * @unimplemented
210 */
211 BOOLEAN
212 NTAPI
213 CcPreparePinWrite (
214 IN PFILE_OBJECT FileObject,
215 IN PLARGE_INTEGER FileOffset,
216 IN ULONG Length,
217 IN BOOLEAN Zero,
218 IN ULONG Flags,
219 OUT PVOID * Bcb,
220 OUT PVOID * Buffer)
221 {
222 CCTRACE(CC_API_DEBUG, "FileOffset=%p FileOffset=%p Length=%lu Zero=%d Flags=0x%lx\n",
223 FileObject, FileOffset, Length, Zero, Flags);
224
225 /*
226 * FIXME: This is function is similar to CcPinRead, but doesn't
227 * read the data if they're not present. Instead it should just
228 * prepare the VACBs and zero them out if Zero != FALSE.
229 *
230 * For now calling CcPinRead is better than returning error or
231 * just having UNIMPLEMENTED here.
232 */
233 return CcPinRead(FileObject, FileOffset, Length, Flags, Bcb, Buffer);
234 }
235
236 /*
237 * @implemented
238 */
239 VOID NTAPI
240 CcSetDirtyPinnedData (
241 IN PVOID Bcb,
242 IN PLARGE_INTEGER Lsn)
243 {
244 PINTERNAL_BCB iBcb = Bcb;
245
246 CCTRACE(CC_API_DEBUG, "Bcb=%p Lsn=%p\n",
247 Bcb, Lsn);
248
249 iBcb->Dirty = TRUE;
250 if (!iBcb->Vacb->Dirty)
251 {
252 CcRosMarkDirtyVacb(iBcb->Vacb);
253 }
254 }
255
256
257 /*
258 * @implemented
259 */
260 VOID NTAPI
261 CcUnpinData (
262 IN PVOID Bcb)
263 {
264 CCTRACE(CC_API_DEBUG, "Bcb=%p\n", Bcb);
265
266 CcUnpinDataForThread(Bcb, (ERESOURCE_THREAD)PsGetCurrentThread());
267 }
268
269 /*
270 * @unimplemented
271 */
272 VOID
273 NTAPI
274 CcUnpinDataForThread (
275 IN PVOID Bcb,
276 IN ERESOURCE_THREAD ResourceThreadId)
277 {
278 PINTERNAL_BCB iBcb = Bcb;
279
280 CCTRACE(CC_API_DEBUG, "Bcb=%p ResourceThreadId=%lu\n", Bcb, ResourceThreadId);
281
282 if (iBcb->Pinned)
283 {
284 ExReleaseResourceForThreadLite(&iBcb->Lock, ResourceThreadId);
285 iBcb->Pinned = FALSE;
286 CcRosAcquireVacbLock(iBcb->Vacb, NULL);
287 iBcb->Vacb->PinCount--;
288 }
289
290 if (--iBcb->RefCount == 0)
291 {
292 CcRosReleaseVacb(iBcb->Vacb->SharedCacheMap,
293 iBcb->Vacb,
294 TRUE,
295 iBcb->Dirty,
296 FALSE);
297
298 ExDeleteResourceLite(&iBcb->Lock);
299 ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
300 }
301 }
302
303 /*
304 * @implemented
305 */
306 VOID
307 NTAPI
308 CcRepinBcb (
309 IN PVOID Bcb)
310 {
311 PINTERNAL_BCB iBcb = Bcb;
312
313 CCTRACE(CC_API_DEBUG, "Bcb=%p\n", Bcb);
314
315 iBcb->RefCount++;
316 }
317
318 /*
319 * @unimplemented
320 */
321 VOID
322 NTAPI
323 CcUnpinRepinnedBcb (
324 IN PVOID Bcb,
325 IN BOOLEAN WriteThrough,
326 IN PIO_STATUS_BLOCK IoStatus)
327 {
328 PINTERNAL_BCB iBcb = Bcb;
329
330 CCTRACE(CC_API_DEBUG, "Bcb=%p WriteThrough=%d\n", Bcb, WriteThrough);
331
332 IoStatus->Status = STATUS_SUCCESS;
333 if (--iBcb->RefCount == 0)
334 {
335 IoStatus->Information = 0;
336 if (WriteThrough)
337 {
338 CcRosAcquireVacbLock(iBcb->Vacb, NULL);
339 if (iBcb->Vacb->Dirty)
340 {
341 IoStatus->Status = CcRosFlushVacb(iBcb->Vacb);
342 }
343 else
344 {
345 IoStatus->Status = STATUS_SUCCESS;
346 }
347 CcRosReleaseVacbLock(iBcb->Vacb);
348 }
349 else
350 {
351 IoStatus->Status = STATUS_SUCCESS;
352 }
353
354 if (iBcb->Pinned)
355 {
356 ExReleaseResourceLite(&iBcb->Lock);
357 iBcb->Pinned = FALSE;
358 CcRosAcquireVacbLock(iBcb->Vacb, NULL);
359 iBcb->Vacb->PinCount--;
360 }
361 ExDeleteResourceLite(&iBcb->Lock);
362 ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
363 }
364 }