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
;
21 /* FUNCTIONS *****************************************************************/
29 IN PFILE_OBJECT FileObject
,
30 IN PLARGE_INTEGER FileOffset
,
38 PROS_SHARED_CACHE_MAP SharedCacheMap
;
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
);
48 ReadOffset
= (ULONG
)FileOffset
->QuadPart
;
51 ASSERT(FileObject
->SectionObjectPointer
);
52 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
54 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
55 ASSERT(SharedCacheMap
);
57 DPRINT("SectionSize %I64x, FileSize %I64x\n",
58 SharedCacheMap
->SectionSize
.QuadPart
,
59 SharedCacheMap
->FileSize
.QuadPart
);
61 if (ReadOffset
% VACB_MAPPING_GRANULARITY
+ Length
> VACB_MAPPING_GRANULARITY
)
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
);
69 ROffset
= ROUND_DOWN(ReadOffset
, VACB_MAPPING_GRANULARITY
);
70 Status
= CcRosRequestVacb(SharedCacheMap
,
75 if (!NT_SUCCESS(Status
))
77 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
78 FileObject
, FileOffset
, Length
, Flags
);
79 ExRaiseStatus(Status
);
85 if (!(Flags
& MAP_WAIT
))
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
);
93 Status
= CcReadVirtualAddress(Vacb
);
94 if (!NT_SUCCESS(Status
))
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
);
104 *pBuffer
= (PVOID
)((ULONG_PTR
)(*pBuffer
) + ReadOffset
% VACB_MAPPING_GRANULARITY
);
105 iBcb
= ExAllocateFromNPagedLookasideList(&iBcbLookasideList
);
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
);
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
;
122 iBcb
->Pinned
= FALSE
;
124 ExInitializeResourceLite(&iBcb
->Lock
);
127 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> TRUE Bcb=%p\n",
128 FileObject
, FileOffset
, Length
, Flags
, iBcb
);
138 IN PFILE_OBJECT FileObject
,
139 IN PLARGE_INTEGER FileOffset
,
144 PROS_SHARED_CACHE_MAP SharedCacheMap
;
146 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
147 FileObject
, FileOffset
, Length
, Flags
);
150 ASSERT(FileObject
->SectionObjectPointer
);
151 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
153 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
154 ASSERT(SharedCacheMap
);
155 ASSERT(SharedCacheMap
->PinAccess
);
157 /* no-op for current implementation. */
167 IN PFILE_OBJECT FileObject
,
168 IN PLARGE_INTEGER FileOffset
,
176 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
177 FileObject
, FileOffset
, Length
, Flags
);
179 if (CcMapData(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
))
181 if (CcPinMappedData(FileObject
, FileOffset
, Length
, Flags
, Bcb
))
185 ASSERT(iBcb
->Pinned
== FALSE
);
188 if (InterlockedIncrement(&iBcb
->Vacb
->PinCount
) == 1)
190 KeReleaseMutex(&iBcb
->Vacb
->Mutex
, FALSE
);
193 if (Flags
& PIN_EXCLUSIVE
)
195 ExAcquireResourceExclusiveLite(&iBcb
->Lock
, TRUE
);
199 ExAcquireResourceSharedLite(&iBcb
->Lock
, TRUE
);
216 IN PFILE_OBJECT FileObject
,
217 IN PLARGE_INTEGER FileOffset
,
224 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Zero=%d Flags=0x%lx\n",
225 FileObject
, FileOffset
, Length
, Zero
, Flags
);
228 * FIXME: This is function is similar to CcPinRead, but doesn't
229 * read the data if they're not present. Instead it should just
230 * prepare the VACBs and zero them out if Zero != FALSE.
232 * For now calling CcPinRead is better than returning error or
233 * just having UNIMPLEMENTED here.
235 return CcPinRead(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
);
242 CcSetDirtyPinnedData (
244 IN PLARGE_INTEGER Lsn
)
246 PINTERNAL_BCB iBcb
= Bcb
;
248 CCTRACE(CC_API_DEBUG
, "Bcb=%p Lsn=%p\n",
262 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
264 CcUnpinDataForThread(Bcb
, (ERESOURCE_THREAD
)PsGetCurrentThread());
272 CcUnpinDataForThread (
274 IN ERESOURCE_THREAD ResourceThreadId
)
276 PINTERNAL_BCB iBcb
= Bcb
;
278 CCTRACE(CC_API_DEBUG
, "Bcb=%p ResourceThreadId=%lu\n", Bcb
, ResourceThreadId
);
282 ExReleaseResourceForThreadLite(&iBcb
->Lock
, ResourceThreadId
);
283 iBcb
->Pinned
= FALSE
;
284 if (InterlockedDecrement(&iBcb
->Vacb
->PinCount
) == 0)
286 KeWaitForSingleObject(&iBcb
->Vacb
->Mutex
,
294 CcRosReleaseVacb(iBcb
->Vacb
->SharedCacheMap
,
300 if (--iBcb
->RefCount
== 0)
302 ExDeleteResourceLite(&iBcb
->Lock
);
303 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);
315 PINTERNAL_BCB iBcb
= Bcb
;
317 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
329 IN BOOLEAN WriteThrough
,
330 IN PIO_STATUS_BLOCK IoStatus
)
332 PINTERNAL_BCB iBcb
= Bcb
;
334 CCTRACE(CC_API_DEBUG
, "Bcb=%p WriteThrough=%d\n", Bcb
, WriteThrough
);
336 IoStatus
->Status
= STATUS_SUCCESS
;
337 if (--iBcb
->RefCount
== 0)
339 IoStatus
->Information
= 0;
342 KeWaitForSingleObject(&iBcb
->Vacb
->Mutex
,
347 if (iBcb
->Vacb
->Dirty
)
349 IoStatus
->Status
= CcRosFlushVacb(iBcb
->Vacb
);
353 IoStatus
->Status
= STATUS_SUCCESS
;
355 KeReleaseMutex(&iBcb
->Vacb
->Mutex
, FALSE
);
359 IoStatus
->Status
= STATUS_SUCCESS
;
364 ExReleaseResourceLite(&iBcb
->Lock
);
365 iBcb
->Pinned
= FALSE
;
366 if (InterlockedDecrement(&iBcb
->Vacb
->PinCount
) == 0)
368 KeWaitForSingleObject(&iBcb
->Vacb
->Mutex
,
375 ExDeleteResourceLite(&iBcb
->Lock
);
376 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);