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 *****************************************************************/
40 IN PFILE_OBJECT FileObject
,
41 IN PLARGE_INTEGER FileOffset
,
49 PROS_SHARED_CACHE_MAP SharedCacheMap
;
56 DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %lu, Flags 0x%lx,"
57 " pBcb 0x%p, pBuffer 0x%p)\n", FileObject
, FileOffset
->QuadPart
,
58 Length
, Flags
, pBcb
, pBuffer
);
69 ReadOffset
= FileOffset
->QuadPart
;
72 ASSERT(FileObject
->SectionObjectPointer
);
73 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
75 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
76 ASSERT(SharedCacheMap
);
78 DPRINT("SectionSize %I64x, FileSize %I64x\n",
79 SharedCacheMap
->SectionSize
.QuadPart
,
80 SharedCacheMap
->FileSize
.QuadPart
);
82 if (ReadOffset
% VACB_MAPPING_GRANULARITY
+ Length
> VACB_MAPPING_GRANULARITY
)
84 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
85 FileObject
, FileOffset
, Length
, Flags
);
86 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
90 if (!BooleanFlagOn(Flags
, MAP_NO_READ
))
92 static int Warned
= 0;
94 SetFlag(Flags
, MAP_NO_READ
);
97 DPRINT1("Mapping/pinning with no read not implemented. Forcing read, might fail if wait not allowed\n");
102 ROffset
= ROUND_DOWN(ReadOffset
, VACB_MAPPING_GRANULARITY
);
103 Status
= CcRosRequestVacb(SharedCacheMap
,
108 if (!NT_SUCCESS(Status
))
110 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
111 FileObject
, FileOffset
, Length
, Flags
);
112 ExRaiseStatus(Status
);
116 if (!Valid
&& BooleanFlagOn(Flags
, MAP_NO_READ
))
118 if (!BooleanFlagOn(Flags
, MAP_WAIT
))
120 CcRosReleaseVacb(SharedCacheMap
, Vacb
, FALSE
, FALSE
, FALSE
);
121 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
122 FileObject
, FileOffset
, Length
, Flags
);
126 Status
= CcReadVirtualAddress(Vacb
);
127 if (!NT_SUCCESS(Status
))
129 CcRosReleaseVacb(SharedCacheMap
, Vacb
, FALSE
, FALSE
, FALSE
);
130 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
131 FileObject
, FileOffset
, Length
, Flags
);
132 ExRaiseStatus(Status
);
137 *pBuffer
= (PUCHAR
)*pBuffer
+ ReadOffset
% VACB_MAPPING_GRANULARITY
;
138 iBcb
= ExAllocateFromNPagedLookasideList(&iBcbLookasideList
);
141 CcRosReleaseVacb(SharedCacheMap
, Vacb
, TRUE
, FALSE
, FALSE
);
142 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
143 FileObject
, FileOffset
, Length
, Flags
);
144 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
148 RtlZeroMemory(iBcb
, sizeof(*iBcb
));
149 iBcb
->PFCB
.NodeTypeCode
= 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
150 iBcb
->PFCB
.NodeByteSize
= sizeof(PUBLIC_BCB
);
151 iBcb
->PFCB
.MappedLength
= Length
;
152 iBcb
->PFCB
.MappedFileOffset
= *FileOffset
;
155 iBcb
->Pinned
= FALSE
;
157 ExInitializeResourceLite(&iBcb
->Lock
);
160 KeAcquireSpinLock(&SharedCacheMap
->BcbSpinLock
, &OldIrql
);
161 InsertTailList(&SharedCacheMap
->BcbList
, &iBcb
->BcbEntry
);
162 KeReleaseSpinLock(&SharedCacheMap
->BcbSpinLock
, OldIrql
);
164 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> TRUE Bcb=%p\n",
165 FileObject
, FileOffset
, Length
, Flags
, iBcb
);
175 IN PFILE_OBJECT FileObject
,
176 IN PLARGE_INTEGER FileOffset
,
183 PROS_SHARED_CACHE_MAP SharedCacheMap
;
185 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
186 FileObject
, FileOffset
, Length
, Flags
);
189 ASSERT(FileObject
->SectionObjectPointer
);
190 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
192 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
193 ASSERT(SharedCacheMap
);
194 if (!SharedCacheMap
->PinAccess
)
196 DPRINT1("FIXME: Pinning a file with no pin access!\n");
201 ASSERT(iBcb
->Pinned
== FALSE
);
204 iBcb
->Vacb
->PinCount
++;
206 if (BooleanFlagOn(Flags
, PIN_EXCLUSIVE
))
208 Result
= ExAcquireResourceExclusiveLite(&iBcb
->Lock
, BooleanFlagOn(Flags
, PIN_WAIT
));
212 Result
= ExAcquireSharedStarveExclusive(&iBcb
->Lock
, BooleanFlagOn(Flags
, PIN_WAIT
));
217 iBcb
->Pinned
= FALSE
;
218 iBcb
->Vacb
->PinCount
--;
230 IN PFILE_OBJECT FileObject
,
231 IN PLARGE_INTEGER FileOffset
,
237 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
238 FileObject
, FileOffset
, Length
, Flags
);
240 if (Flags
& PIN_WAIT
)
250 if (!CcMapData(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
))
256 if (!CcPinMappedData(FileObject
, FileOffset
, Length
, Flags
, Bcb
))
271 IN PFILE_OBJECT FileObject
,
272 IN PLARGE_INTEGER FileOffset
,
279 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Zero=%d Flags=0x%lx\n",
280 FileObject
, FileOffset
, Length
, Zero
, Flags
);
283 * FIXME: This is function is similar to CcPinRead, but doesn't
284 * read the data if they're not present. Instead it should just
285 * prepare the VACBs and zero them out if Zero != FALSE.
287 * For now calling CcPinRead is better than returning error or
288 * just having UNIMPLEMENTED here.
290 return CcPinRead(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
);
297 CcSetDirtyPinnedData (
299 IN PLARGE_INTEGER Lsn
)
301 PINTERNAL_BCB iBcb
= Bcb
;
303 CCTRACE(CC_API_DEBUG
, "Bcb=%p Lsn=%p\n",
307 if (!iBcb
->Vacb
->Dirty
)
309 CcRosMarkDirtyVacb(iBcb
->Vacb
);
321 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
323 CcUnpinDataForThread(Bcb
, (ERESOURCE_THREAD
)PsGetCurrentThread());
331 CcUnpinDataForThread (
333 IN ERESOURCE_THREAD ResourceThreadId
)
335 PINTERNAL_BCB iBcb
= Bcb
;
337 CCTRACE(CC_API_DEBUG
, "Bcb=%p ResourceThreadId=%lu\n", Bcb
, ResourceThreadId
);
341 ExReleaseResourceForThreadLite(&iBcb
->Lock
, ResourceThreadId
);
342 iBcb
->Pinned
= FALSE
;
343 iBcb
->Vacb
->PinCount
--;
346 if (--iBcb
->RefCount
== 0)
349 PROS_SHARED_CACHE_MAP SharedCacheMap
;
351 SharedCacheMap
= iBcb
->Vacb
->SharedCacheMap
;
352 CcRosReleaseVacb(SharedCacheMap
,
358 KeAcquireSpinLock(&SharedCacheMap
->BcbSpinLock
, &OldIrql
);
359 RemoveEntryList(&iBcb
->BcbEntry
);
360 KeReleaseSpinLock(&SharedCacheMap
->BcbSpinLock
, OldIrql
);
362 ExDeleteResourceLite(&iBcb
->Lock
);
363 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);
375 PINTERNAL_BCB iBcb
= Bcb
;
377 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
389 IN BOOLEAN WriteThrough
,
390 IN PIO_STATUS_BLOCK IoStatus
)
392 PINTERNAL_BCB iBcb
= Bcb
;
394 PROS_SHARED_CACHE_MAP SharedCacheMap
;
396 CCTRACE(CC_API_DEBUG
, "Bcb=%p WriteThrough=%d\n", Bcb
, WriteThrough
);
398 IoStatus
->Status
= STATUS_SUCCESS
;
399 if (--iBcb
->RefCount
== 0)
401 IoStatus
->Information
= 0;
404 if (iBcb
->Vacb
->Dirty
)
406 IoStatus
->Status
= CcRosFlushVacb(iBcb
->Vacb
);
410 IoStatus
->Status
= STATUS_SUCCESS
;
415 IoStatus
->Status
= STATUS_SUCCESS
;
420 ExReleaseResourceLite(&iBcb
->Lock
);
421 iBcb
->Pinned
= FALSE
;
422 iBcb
->Vacb
->PinCount
--;
423 ASSERT(iBcb
->Vacb
->PinCount
== 0);
426 SharedCacheMap
= iBcb
->Vacb
->SharedCacheMap
;
427 CcRosReleaseVacb(iBcb
->Vacb
->SharedCacheMap
,
433 KeAcquireSpinLock(&SharedCacheMap
->BcbSpinLock
, &OldIrql
);
434 RemoveEntryList(&iBcb
->BcbEntry
);
435 KeReleaseSpinLock(&SharedCacheMap
->BcbSpinLock
, OldIrql
);
437 ExDeleteResourceLite(&iBcb
->Lock
);
438 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);