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 //#define RAISE_FROM_CC_MAP_DATA
21 extern NPAGED_LOOKASIDE_LIST iBcbLookasideList
;
23 /* FUNCTIONS *****************************************************************/
31 IN PFILE_OBJECT FileObject
,
32 IN PLARGE_INTEGER FileOffset
,
40 PROS_SHARED_CACHE_MAP SharedCacheMap
;
46 DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %lu, Flags 0x%lx,"
47 " pBcb 0x%p, pBuffer 0x%p)\n", FileObject
, FileOffset
->QuadPart
,
48 Length
, Flags
, pBcb
, pBuffer
);
50 ReadOffset
= (ULONG
)FileOffset
->QuadPart
;
53 ASSERT(FileObject
->SectionObjectPointer
);
54 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
56 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
57 ASSERT(SharedCacheMap
);
59 DPRINT("SectionSize %I64x, FileSize %I64x\n",
60 SharedCacheMap
->SectionSize
.QuadPart
,
61 SharedCacheMap
->FileSize
.QuadPart
);
63 if (ReadOffset
% VACB_MAPPING_GRANULARITY
+ Length
> VACB_MAPPING_GRANULARITY
)
65 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
66 FileObject
, FileOffset
, Length
, Flags
);
67 #ifdef RAISE_FROM_CC_MAP_DATA
68 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
74 ROffset
= ROUND_DOWN(ReadOffset
, VACB_MAPPING_GRANULARITY
);
75 Status
= CcRosRequestVacb(SharedCacheMap
,
80 if (!NT_SUCCESS(Status
))
82 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
83 FileObject
, FileOffset
, Length
, Flags
);
84 #ifdef RAISE_FROM_CC_MAP_DATA
85 ExRaiseStatus(Status
);
93 if (!(Flags
& MAP_WAIT
))
95 CcRosReleaseVacb(SharedCacheMap
, Vacb
, FALSE
, FALSE
, FALSE
);
96 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
97 FileObject
, FileOffset
, Length
, Flags
);
101 Status
= CcReadVirtualAddress(Vacb
);
102 if (!NT_SUCCESS(Status
))
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
);
107 #ifdef RAISE_FROM_CC_MAP_DATA
108 ExRaiseStatus(Status
);
115 *pBuffer
= (PVOID
)((ULONG_PTR
)(*pBuffer
) + ReadOffset
% VACB_MAPPING_GRANULARITY
);
116 iBcb
= ExAllocateFromNPagedLookasideList(&iBcbLookasideList
);
119 CcRosReleaseVacb(SharedCacheMap
, Vacb
, TRUE
, FALSE
, FALSE
);
120 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
121 FileObject
, FileOffset
, Length
, Flags
);
122 #ifdef RAISE_FROM_CC_MAP_DATA
123 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
129 RtlZeroMemory(iBcb
, sizeof(*iBcb
));
130 iBcb
->PFCB
.NodeTypeCode
= 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
131 iBcb
->PFCB
.NodeByteSize
= sizeof(PUBLIC_BCB
);
132 iBcb
->PFCB
.MappedLength
= Length
;
133 iBcb
->PFCB
.MappedFileOffset
= *FileOffset
;
136 iBcb
->Pinned
= FALSE
;
138 ExInitializeResourceLite(&iBcb
->Lock
);
141 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> TRUE Bcb=%p\n",
142 FileObject
, FileOffset
, Length
, Flags
, iBcb
);
152 IN PFILE_OBJECT FileObject
,
153 IN PLARGE_INTEGER FileOffset
,
158 PROS_SHARED_CACHE_MAP SharedCacheMap
;
160 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
161 FileObject
, FileOffset
, Length
, Flags
);
164 ASSERT(FileObject
->SectionObjectPointer
);
165 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
167 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
168 ASSERT(SharedCacheMap
);
169 ASSERT(SharedCacheMap
->PinAccess
);
171 /* no-op for current implementation. */
181 IN PFILE_OBJECT FileObject
,
182 IN PLARGE_INTEGER FileOffset
,
190 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
191 FileObject
, FileOffset
, Length
, Flags
);
193 if (CcMapData(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
))
195 if (CcPinMappedData(FileObject
, FileOffset
, Length
, Flags
, Bcb
))
199 ASSERT(iBcb
->Pinned
== FALSE
);
202 if (InterlockedIncrement(&iBcb
->Vacb
->PinCount
) == 1)
204 KeReleaseMutex(&iBcb
->Vacb
->Mutex
, FALSE
);
207 if (Flags
& PIN_EXCLUSIVE
)
209 ExAcquireResourceExclusiveLite(&iBcb
->Lock
, TRUE
);
213 ExAcquireResourceSharedLite(&iBcb
->Lock
, TRUE
);
230 IN PFILE_OBJECT FileObject
,
231 IN PLARGE_INTEGER FileOffset
,
238 CCTRACE(CC_API_DEBUG
, "FileOffset=%p FileOffset=%p Length=%lu Zero=%d Flags=0x%lx\n",
239 FileObject
, FileOffset
, Length
, Zero
, Flags
);
242 * FIXME: This is function is similar to CcPinRead, but doesn't
243 * read the data if they're not present. Instead it should just
244 * prepare the VACBs and zero them out if Zero != FALSE.
246 * For now calling CcPinRead is better than returning error or
247 * just having UNIMPLEMENTED here.
249 return CcPinRead(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
);
256 CcSetDirtyPinnedData (
258 IN PLARGE_INTEGER Lsn
)
260 PINTERNAL_BCB iBcb
= Bcb
;
262 CCTRACE(CC_API_DEBUG
, "Bcb=%p Lsn=%p\n",
276 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
278 CcUnpinDataForThread(Bcb
, (ERESOURCE_THREAD
)PsGetCurrentThread());
286 CcUnpinDataForThread (
288 IN ERESOURCE_THREAD ResourceThreadId
)
290 PINTERNAL_BCB iBcb
= Bcb
;
292 CCTRACE(CC_API_DEBUG
, "Bcb=%p ResourceThreadId=%lu\n", Bcb
, ResourceThreadId
);
296 ExReleaseResourceForThreadLite(&iBcb
->Lock
, ResourceThreadId
);
297 iBcb
->Pinned
= FALSE
;
298 if (InterlockedDecrement(&iBcb
->Vacb
->PinCount
) == 0)
300 KeWaitForSingleObject(&iBcb
->Vacb
->Mutex
,
308 CcRosReleaseVacb(iBcb
->Vacb
->SharedCacheMap
,
314 if (--iBcb
->RefCount
== 0)
316 ExDeleteResourceLite(&iBcb
->Lock
);
317 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);
329 PINTERNAL_BCB iBcb
= Bcb
;
331 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
343 IN BOOLEAN WriteThrough
,
344 IN PIO_STATUS_BLOCK IoStatus
)
346 PINTERNAL_BCB iBcb
= Bcb
;
348 CCTRACE(CC_API_DEBUG
, "Bcb=%p WriteThrough=%d\n", Bcb
, WriteThrough
);
350 IoStatus
->Status
= STATUS_SUCCESS
;
351 if (--iBcb
->RefCount
== 0)
353 IoStatus
->Information
= 0;
356 KeWaitForSingleObject(&iBcb
->Vacb
->Mutex
,
361 if (iBcb
->Vacb
->Dirty
)
363 IoStatus
->Status
= CcRosFlushVacb(iBcb
->Vacb
);
367 IoStatus
->Status
= STATUS_SUCCESS
;
369 KeReleaseMutex(&iBcb
->Vacb
->Mutex
, FALSE
);
373 IoStatus
->Status
= STATUS_SUCCESS
;
378 ExReleaseResourceLite(&iBcb
->Lock
);
379 iBcb
->Pinned
= FALSE
;
380 if (InterlockedDecrement(&iBcb
->Vacb
->PinCount
) == 0)
382 KeWaitForSingleObject(&iBcb
->Vacb
->Mutex
,
389 ExDeleteResourceLite(&iBcb
->Lock
);
390 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);