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
8 Pierre Schweitzer (pierre@reactos.org)
11 /* INCLUDES ******************************************************************/
17 /* GLOBALS *******************************************************************/
19 extern NPAGED_LOOKASIDE_LIST iBcbLookasideList
;
22 * - Number of calls to CcMapData that could wait
23 * - Number of calls to CcMapData that couldn't wait
24 * - Number of calls to CcPinRead that could wait
25 * - Number of calls to CcPinRead that couldn't wait
27 ULONG CcMapDataWait
= 0;
28 ULONG CcMapDataNoWait
= 0;
29 ULONG CcPinReadWait
= 0;
30 ULONG CcPinReadNoWait
= 0;
32 /* FUNCTIONS *****************************************************************/
38 IN PFILE_OBJECT FileObject
,
39 IN PLARGE_INTEGER FileOffset
,
47 PROS_SHARED_CACHE_MAP SharedCacheMap
;
54 ReadOffset
= FileOffset
->QuadPart
;
57 ASSERT(FileObject
->SectionObjectPointer
);
58 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
60 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
61 ASSERT(SharedCacheMap
);
63 DPRINT("SectionSize %I64x, FileSize %I64x\n",
64 SharedCacheMap
->SectionSize
.QuadPart
,
65 SharedCacheMap
->FileSize
.QuadPart
);
67 if (ReadOffset
% VACB_MAPPING_GRANULARITY
+ Length
> VACB_MAPPING_GRANULARITY
)
69 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
70 FileObject
, FileOffset
, Length
, Flags
);
74 if (!BooleanFlagOn(Flags
, MAP_NO_READ
))
76 static int Warned
= 0;
78 SetFlag(Flags
, MAP_NO_READ
);
81 DPRINT1("Mapping/pinning with no read not implemented. Forcing read, might fail if wait not allowed\n");
86 ROffset
= ROUND_DOWN(ReadOffset
, VACB_MAPPING_GRANULARITY
);
87 Status
= CcRosRequestVacb(SharedCacheMap
,
92 if (!NT_SUCCESS(Status
))
94 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
95 FileObject
, FileOffset
, Length
, Flags
);
96 ExRaiseStatus(Status
);
100 if (!Valid
&& BooleanFlagOn(Flags
, MAP_NO_READ
))
102 if (!BooleanFlagOn(Flags
, MAP_WAIT
))
104 CcRosReleaseVacb(SharedCacheMap
, Vacb
, FALSE
, FALSE
, FALSE
);
105 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
106 FileObject
, FileOffset
, Length
, Flags
);
110 Status
= CcReadVirtualAddress(Vacb
);
111 if (!NT_SUCCESS(Status
))
113 CcRosReleaseVacb(SharedCacheMap
, Vacb
, FALSE
, FALSE
, FALSE
);
114 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
115 FileObject
, FileOffset
, Length
, Flags
);
116 ExRaiseStatus(Status
);
121 *pBuffer
= (PUCHAR
)*pBuffer
+ ReadOffset
% VACB_MAPPING_GRANULARITY
;
122 iBcb
= ExAllocateFromNPagedLookasideList(&iBcbLookasideList
);
125 CcRosReleaseVacb(SharedCacheMap
, Vacb
, TRUE
, FALSE
, FALSE
);
126 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
127 FileObject
, FileOffset
, Length
, Flags
);
128 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
132 RtlZeroMemory(iBcb
, sizeof(*iBcb
));
133 iBcb
->PFCB
.NodeTypeCode
= 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
134 iBcb
->PFCB
.NodeByteSize
= sizeof(PUBLIC_BCB
);
135 iBcb
->PFCB
.MappedLength
= Length
;
136 iBcb
->PFCB
.MappedFileOffset
= *FileOffset
;
139 iBcb
->Pinned
= FALSE
;
141 ExInitializeResourceLite(&iBcb
->Lock
);
144 KeAcquireSpinLock(&SharedCacheMap
->BcbSpinLock
, &OldIrql
);
145 InsertTailList(&SharedCacheMap
->BcbList
, &iBcb
->BcbEntry
);
146 KeReleaseSpinLock(&SharedCacheMap
->BcbSpinLock
, OldIrql
);
157 IN PFILE_OBJECT FileObject
,
158 IN PLARGE_INTEGER FileOffset
,
166 DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %lu, Flags 0x%lx,"
167 " pBcb 0x%p, pBuffer 0x%p)\n", FileObject
, FileOffset
->QuadPart
,
168 Length
, Flags
, pBcb
, pBuffer
);
170 if (Flags
& MAP_WAIT
)
179 Ret
= CcpMapData(FileObject
, FileOffset
, Length
, Flags
, pBcb
, pBuffer
);
181 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> %d Bcb=%p\n",
182 FileObject
, FileOffset
, Length
, Flags
, Ret
, *pBcb
);
192 IN PFILE_OBJECT FileObject
,
193 IN PLARGE_INTEGER FileOffset
,
200 PROS_SHARED_CACHE_MAP SharedCacheMap
;
202 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
203 FileObject
, FileOffset
, Length
, Flags
);
206 ASSERT(FileObject
->SectionObjectPointer
);
207 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
209 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
210 ASSERT(SharedCacheMap
);
211 if (!SharedCacheMap
->PinAccess
)
213 DPRINT1("FIXME: Pinning a file with no pin access!\n");
218 ASSERT(iBcb
->Pinned
== FALSE
);
221 iBcb
->Vacb
->PinCount
++;
223 if (BooleanFlagOn(Flags
, PIN_EXCLUSIVE
))
225 Result
= ExAcquireResourceExclusiveLite(&iBcb
->Lock
, BooleanFlagOn(Flags
, PIN_WAIT
));
229 Result
= ExAcquireSharedStarveExclusive(&iBcb
->Lock
, BooleanFlagOn(Flags
, PIN_WAIT
));
234 iBcb
->Pinned
= FALSE
;
235 iBcb
->Vacb
->PinCount
--;
247 IN PFILE_OBJECT FileObject
,
248 IN PLARGE_INTEGER FileOffset
,
254 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
255 FileObject
, FileOffset
, Length
, Flags
);
257 if (Flags
& PIN_WAIT
)
267 if (!CcpMapData(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
))
273 if (!CcPinMappedData(FileObject
, FileOffset
, Length
, Flags
, Bcb
))
288 IN PFILE_OBJECT FileObject
,
289 IN PLARGE_INTEGER FileOffset
,
296 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Zero=%d Flags=0x%lx\n",
297 FileObject
, FileOffset
, Length
, Zero
, Flags
);
300 * FIXME: This is function is similar to CcPinRead, but doesn't
301 * read the data if they're not present. Instead it should just
302 * prepare the VACBs and zero them out if Zero != FALSE.
304 * For now calling CcPinRead is better than returning error or
305 * just having UNIMPLEMENTED here.
307 return CcPinRead(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
);
314 CcSetDirtyPinnedData (
316 IN PLARGE_INTEGER Lsn
)
318 PINTERNAL_BCB iBcb
= Bcb
;
320 CCTRACE(CC_API_DEBUG
, "Bcb=%p Lsn=%p\n",
324 if (!iBcb
->Vacb
->Dirty
)
326 CcRosMarkDirtyVacb(iBcb
->Vacb
);
338 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
340 CcUnpinDataForThread(Bcb
, (ERESOURCE_THREAD
)PsGetCurrentThread());
348 CcUnpinDataForThread (
350 IN ERESOURCE_THREAD ResourceThreadId
)
352 PINTERNAL_BCB iBcb
= Bcb
;
354 CCTRACE(CC_API_DEBUG
, "Bcb=%p ResourceThreadId=%lu\n", Bcb
, ResourceThreadId
);
358 ExReleaseResourceForThreadLite(&iBcb
->Lock
, ResourceThreadId
);
359 iBcb
->Pinned
= FALSE
;
360 iBcb
->Vacb
->PinCount
--;
363 if (--iBcb
->RefCount
== 0)
366 PROS_SHARED_CACHE_MAP SharedCacheMap
;
368 SharedCacheMap
= iBcb
->Vacb
->SharedCacheMap
;
369 CcRosReleaseVacb(SharedCacheMap
,
375 KeAcquireSpinLock(&SharedCacheMap
->BcbSpinLock
, &OldIrql
);
376 RemoveEntryList(&iBcb
->BcbEntry
);
377 KeReleaseSpinLock(&SharedCacheMap
->BcbSpinLock
, OldIrql
);
379 ExDeleteResourceLite(&iBcb
->Lock
);
380 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);
392 PINTERNAL_BCB iBcb
= Bcb
;
394 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
406 IN BOOLEAN WriteThrough
,
407 IN PIO_STATUS_BLOCK IoStatus
)
409 PINTERNAL_BCB iBcb
= Bcb
;
411 PROS_SHARED_CACHE_MAP SharedCacheMap
;
413 CCTRACE(CC_API_DEBUG
, "Bcb=%p WriteThrough=%d\n", Bcb
, WriteThrough
);
415 IoStatus
->Status
= STATUS_SUCCESS
;
416 if (--iBcb
->RefCount
== 0)
418 IoStatus
->Information
= 0;
421 if (iBcb
->Vacb
->Dirty
)
423 IoStatus
->Status
= CcRosFlushVacb(iBcb
->Vacb
);
427 IoStatus
->Status
= STATUS_SUCCESS
;
432 IoStatus
->Status
= STATUS_SUCCESS
;
437 ExReleaseResourceLite(&iBcb
->Lock
);
438 iBcb
->Pinned
= FALSE
;
439 iBcb
->Vacb
->PinCount
--;
440 ASSERT(iBcb
->Vacb
->PinCount
== 0);
443 SharedCacheMap
= iBcb
->Vacb
->SharedCacheMap
;
444 CcRosReleaseVacb(iBcb
->Vacb
->SharedCacheMap
,
450 KeAcquireSpinLock(&SharedCacheMap
->BcbSpinLock
, &OldIrql
);
451 RemoveEntryList(&iBcb
->BcbEntry
);
452 KeReleaseSpinLock(&SharedCacheMap
->BcbSpinLock
, OldIrql
);
454 ExDeleteResourceLite(&iBcb
->Lock
);
455 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);