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
;
55 DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %lu, Flags 0x%lx,"
56 " pBcb 0x%p, pBuffer 0x%p)\n", FileObject
, FileOffset
->QuadPart
,
57 Length
, Flags
, pBcb
, pBuffer
);
68 ReadOffset
= FileOffset
->QuadPart
;
71 ASSERT(FileObject
->SectionObjectPointer
);
72 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
74 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
75 ASSERT(SharedCacheMap
);
77 DPRINT("SectionSize %I64x, FileSize %I64x\n",
78 SharedCacheMap
->SectionSize
.QuadPart
,
79 SharedCacheMap
->FileSize
.QuadPart
);
81 if (ReadOffset
% VACB_MAPPING_GRANULARITY
+ Length
> VACB_MAPPING_GRANULARITY
)
83 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
84 FileObject
, FileOffset
, Length
, Flags
);
85 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
89 ROffset
= ROUND_DOWN(ReadOffset
, VACB_MAPPING_GRANULARITY
);
90 Status
= CcRosRequestVacb(SharedCacheMap
,
95 if (!NT_SUCCESS(Status
))
97 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
98 FileObject
, FileOffset
, Length
, Flags
);
99 ExRaiseStatus(Status
);
105 if (!(Flags
& MAP_WAIT
))
107 CcRosReleaseVacb(SharedCacheMap
, Vacb
, FALSE
, FALSE
, FALSE
);
108 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
109 FileObject
, FileOffset
, Length
, Flags
);
113 Status
= CcReadVirtualAddress(Vacb
);
114 if (!NT_SUCCESS(Status
))
116 CcRosReleaseVacb(SharedCacheMap
, Vacb
, FALSE
, FALSE
, FALSE
);
117 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
118 FileObject
, FileOffset
, Length
, Flags
);
119 ExRaiseStatus(Status
);
124 *pBuffer
= (PUCHAR
)*pBuffer
+ ReadOffset
% VACB_MAPPING_GRANULARITY
;
125 iBcb
= ExAllocateFromNPagedLookasideList(&iBcbLookasideList
);
128 CcRosReleaseVacb(SharedCacheMap
, Vacb
, TRUE
, FALSE
, FALSE
);
129 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
130 FileObject
, FileOffset
, Length
, Flags
);
131 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
135 RtlZeroMemory(iBcb
, sizeof(*iBcb
));
136 iBcb
->PFCB
.NodeTypeCode
= 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
137 iBcb
->PFCB
.NodeByteSize
= sizeof(PUBLIC_BCB
);
138 iBcb
->PFCB
.MappedLength
= Length
;
139 iBcb
->PFCB
.MappedFileOffset
= *FileOffset
;
142 iBcb
->Pinned
= FALSE
;
144 ExInitializeResourceLite(&iBcb
->Lock
);
147 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> TRUE Bcb=%p\n",
148 FileObject
, FileOffset
, Length
, Flags
, iBcb
);
158 IN PFILE_OBJECT FileObject
,
159 IN PLARGE_INTEGER FileOffset
,
165 PROS_SHARED_CACHE_MAP SharedCacheMap
;
167 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
168 FileObject
, FileOffset
, Length
, Flags
);
171 ASSERT(FileObject
->SectionObjectPointer
);
172 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
174 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
175 ASSERT(SharedCacheMap
);
176 ASSERT(SharedCacheMap
->PinAccess
);
179 ASSERT(iBcb
->Pinned
== FALSE
);
182 iBcb
->Vacb
->PinCount
++;
184 if (Flags
& PIN_EXCLUSIVE
)
186 ExAcquireResourceExclusiveLite(&iBcb
->Lock
, TRUE
);
190 ExAcquireResourceSharedLite(&iBcb
->Lock
, TRUE
);
202 IN PFILE_OBJECT FileObject
,
203 IN PLARGE_INTEGER FileOffset
,
209 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
210 FileObject
, FileOffset
, Length
, Flags
);
212 if (Flags
& PIN_WAIT
)
222 if (!CcMapData(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
))
228 if (!CcPinMappedData(FileObject
, FileOffset
, Length
, Flags
, Bcb
))
243 IN PFILE_OBJECT FileObject
,
244 IN PLARGE_INTEGER FileOffset
,
251 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Zero=%d Flags=0x%lx\n",
252 FileObject
, FileOffset
, Length
, Zero
, Flags
);
255 * FIXME: This is function is similar to CcPinRead, but doesn't
256 * read the data if they're not present. Instead it should just
257 * prepare the VACBs and zero them out if Zero != FALSE.
259 * For now calling CcPinRead is better than returning error or
260 * just having UNIMPLEMENTED here.
262 return CcPinRead(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
);
269 CcSetDirtyPinnedData (
271 IN PLARGE_INTEGER Lsn
)
273 PINTERNAL_BCB iBcb
= Bcb
;
275 CCTRACE(CC_API_DEBUG
, "Bcb=%p Lsn=%p\n",
279 if (!iBcb
->Vacb
->Dirty
)
281 CcRosMarkDirtyVacb(iBcb
->Vacb
);
293 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
295 CcUnpinDataForThread(Bcb
, (ERESOURCE_THREAD
)PsGetCurrentThread());
303 CcUnpinDataForThread (
305 IN ERESOURCE_THREAD ResourceThreadId
)
307 PINTERNAL_BCB iBcb
= Bcb
;
309 CCTRACE(CC_API_DEBUG
, "Bcb=%p ResourceThreadId=%lu\n", Bcb
, ResourceThreadId
);
313 ExReleaseResourceForThreadLite(&iBcb
->Lock
, ResourceThreadId
);
314 iBcb
->Pinned
= FALSE
;
315 iBcb
->Vacb
->PinCount
--;
318 if (--iBcb
->RefCount
== 0)
320 CcRosReleaseVacb(iBcb
->Vacb
->SharedCacheMap
,
326 ExDeleteResourceLite(&iBcb
->Lock
);
327 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);
339 PINTERNAL_BCB iBcb
= Bcb
;
341 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
353 IN BOOLEAN WriteThrough
,
354 IN PIO_STATUS_BLOCK IoStatus
)
356 PINTERNAL_BCB iBcb
= Bcb
;
358 CCTRACE(CC_API_DEBUG
, "Bcb=%p WriteThrough=%d\n", Bcb
, WriteThrough
);
360 IoStatus
->Status
= STATUS_SUCCESS
;
361 if (--iBcb
->RefCount
== 0)
363 IoStatus
->Information
= 0;
366 if (iBcb
->Vacb
->Dirty
)
368 IoStatus
->Status
= CcRosFlushVacb(iBcb
->Vacb
);
372 IoStatus
->Status
= STATUS_SUCCESS
;
377 IoStatus
->Status
= STATUS_SUCCESS
;
382 ExReleaseResourceLite(&iBcb
->Lock
);
383 iBcb
->Pinned
= FALSE
;
384 iBcb
->Vacb
->PinCount
--;
385 ASSERT(iBcb
->Vacb
->PinCount
== 0);
388 CcRosReleaseVacb(iBcb
->Vacb
->SharedCacheMap
,
394 ExDeleteResourceLite(&iBcb
->Lock
);
395 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);