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 ULONG CcMapDataWait
= 0;
22 ULONG CcMapDataNoWait
= 0;
24 /* FUNCTIONS *****************************************************************/
32 IN PFILE_OBJECT FileObject
,
33 IN PLARGE_INTEGER FileOffset
,
41 PROS_SHARED_CACHE_MAP SharedCacheMap
;
47 DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %lu, Flags 0x%lx,"
48 " pBcb 0x%p, pBuffer 0x%p)\n", FileObject
, FileOffset
->QuadPart
,
49 Length
, Flags
, pBcb
, pBuffer
);
60 ReadOffset
= FileOffset
->QuadPart
;
63 ASSERT(FileObject
->SectionObjectPointer
);
64 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
66 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
67 ASSERT(SharedCacheMap
);
69 DPRINT("SectionSize %I64x, FileSize %I64x\n",
70 SharedCacheMap
->SectionSize
.QuadPart
,
71 SharedCacheMap
->FileSize
.QuadPart
);
73 if (ReadOffset
% VACB_MAPPING_GRANULARITY
+ Length
> VACB_MAPPING_GRANULARITY
)
75 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
76 FileObject
, FileOffset
, Length
, Flags
);
77 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
81 ROffset
= ROUND_DOWN(ReadOffset
, VACB_MAPPING_GRANULARITY
);
82 Status
= CcRosRequestVacb(SharedCacheMap
,
87 if (!NT_SUCCESS(Status
))
89 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
90 FileObject
, FileOffset
, Length
, Flags
);
91 ExRaiseStatus(Status
);
97 if (!(Flags
& MAP_WAIT
))
99 CcRosReleaseVacb(SharedCacheMap
, Vacb
, FALSE
, FALSE
, FALSE
);
100 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
101 FileObject
, FileOffset
, Length
, Flags
);
105 Status
= CcReadVirtualAddress(Vacb
);
106 if (!NT_SUCCESS(Status
))
108 CcRosReleaseVacb(SharedCacheMap
, Vacb
, FALSE
, 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
);
116 *pBuffer
= (PUCHAR
)*pBuffer
+ ReadOffset
% VACB_MAPPING_GRANULARITY
;
117 iBcb
= ExAllocateFromNPagedLookasideList(&iBcbLookasideList
);
120 CcRosReleaseVacb(SharedCacheMap
, Vacb
, TRUE
, FALSE
, FALSE
);
121 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
122 FileObject
, FileOffset
, Length
, Flags
);
123 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
127 RtlZeroMemory(iBcb
, sizeof(*iBcb
));
128 iBcb
->PFCB
.NodeTypeCode
= 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
129 iBcb
->PFCB
.NodeByteSize
= sizeof(PUBLIC_BCB
);
130 iBcb
->PFCB
.MappedLength
= Length
;
131 iBcb
->PFCB
.MappedFileOffset
= *FileOffset
;
134 iBcb
->Pinned
= FALSE
;
136 ExInitializeResourceLite(&iBcb
->Lock
);
139 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> TRUE Bcb=%p\n",
140 FileObject
, FileOffset
, Length
, Flags
, iBcb
);
150 IN PFILE_OBJECT FileObject
,
151 IN PLARGE_INTEGER FileOffset
,
156 PROS_SHARED_CACHE_MAP SharedCacheMap
;
158 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
159 FileObject
, FileOffset
, Length
, Flags
);
162 ASSERT(FileObject
->SectionObjectPointer
);
163 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
165 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
166 ASSERT(SharedCacheMap
);
167 ASSERT(SharedCacheMap
->PinAccess
);
169 /* no-op for current implementation. */
179 IN PFILE_OBJECT FileObject
,
180 IN PLARGE_INTEGER FileOffset
,
188 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
189 FileObject
, FileOffset
, Length
, Flags
);
191 if (CcMapData(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
))
193 if (CcPinMappedData(FileObject
, FileOffset
, Length
, Flags
, Bcb
))
197 ASSERT(iBcb
->Pinned
== FALSE
);
200 iBcb
->Vacb
->PinCount
++;
201 CcRosReleaseVacbLock(iBcb
->Vacb
);
203 if (Flags
& PIN_EXCLUSIVE
)
205 ExAcquireResourceExclusiveLite(&iBcb
->Lock
, TRUE
);
209 ExAcquireResourceSharedLite(&iBcb
->Lock
, TRUE
);
226 IN PFILE_OBJECT FileObject
,
227 IN PLARGE_INTEGER FileOffset
,
234 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Zero=%d Flags=0x%lx\n",
235 FileObject
, FileOffset
, Length
, Zero
, Flags
);
238 * FIXME: This is function is similar to CcPinRead, but doesn't
239 * read the data if they're not present. Instead it should just
240 * prepare the VACBs and zero them out if Zero != FALSE.
242 * For now calling CcPinRead is better than returning error or
243 * just having UNIMPLEMENTED here.
245 return CcPinRead(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
);
252 CcSetDirtyPinnedData (
254 IN PLARGE_INTEGER Lsn
)
256 PINTERNAL_BCB iBcb
= Bcb
;
258 CCTRACE(CC_API_DEBUG
, "Bcb=%p Lsn=%p\n",
272 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
274 CcUnpinDataForThread(Bcb
, (ERESOURCE_THREAD
)PsGetCurrentThread());
282 CcUnpinDataForThread (
284 IN ERESOURCE_THREAD ResourceThreadId
)
286 PINTERNAL_BCB iBcb
= Bcb
;
288 CCTRACE(CC_API_DEBUG
, "Bcb=%p ResourceThreadId=%lu\n", Bcb
, ResourceThreadId
);
292 ExReleaseResourceForThreadLite(&iBcb
->Lock
, ResourceThreadId
);
293 iBcb
->Pinned
= FALSE
;
294 CcRosAcquireVacbLock(iBcb
->Vacb
, NULL
);
295 iBcb
->Vacb
->PinCount
--;
298 if (--iBcb
->RefCount
== 0)
300 CcRosReleaseVacb(iBcb
->Vacb
->SharedCacheMap
,
306 ExDeleteResourceLite(&iBcb
->Lock
);
307 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);
319 PINTERNAL_BCB iBcb
= Bcb
;
321 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
333 IN BOOLEAN WriteThrough
,
334 IN PIO_STATUS_BLOCK IoStatus
)
336 PINTERNAL_BCB iBcb
= Bcb
;
338 CCTRACE(CC_API_DEBUG
, "Bcb=%p WriteThrough=%d\n", Bcb
, WriteThrough
);
340 IoStatus
->Status
= STATUS_SUCCESS
;
341 if (--iBcb
->RefCount
== 0)
343 IoStatus
->Information
= 0;
346 CcRosAcquireVacbLock(iBcb
->Vacb
, NULL
);
347 if (iBcb
->Vacb
->Dirty
)
349 IoStatus
->Status
= CcRosFlushVacb(iBcb
->Vacb
);
353 IoStatus
->Status
= STATUS_SUCCESS
;
355 CcRosReleaseVacbLock(iBcb
->Vacb
);
359 IoStatus
->Status
= STATUS_SUCCESS
;
364 ExReleaseResourceLite(&iBcb
->Lock
);
365 iBcb
->Pinned
= FALSE
;
366 CcRosAcquireVacbLock(iBcb
->Vacb
, NULL
);
367 iBcb
->Vacb
->PinCount
--;
369 ExDeleteResourceLite(&iBcb
->Lock
);
370 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);