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
10 /* INCLUDES ******************************************************************/
16 /* GLOBALS *******************************************************************/
18 extern NPAGED_LOOKASIDE_LIST iBcbLookasideList
;
20 /* FUNCTIONS *****************************************************************/
28 IN PFILE_OBJECT FileObject
,
29 IN PLARGE_INTEGER FileOffset
,
38 PCACHE_SEGMENT CacheSeg
;
43 DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %d, Flags %d,"
44 " pBcb 0x%p, pBuffer 0x%p)\n", FileObject
, FileOffset
->QuadPart
,
45 Length
, Flags
, pBcb
, pBuffer
);
47 ReadOffset
= (ULONG
)FileOffset
->QuadPart
;
50 ASSERT(FileObject
->SectionObjectPointer
);
51 ASSERT(FileObject
->SectionObjectPointer
->SharedCacheMap
);
53 Bcb
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
56 DPRINT("AllocationSize %I64x, FileSize %I64x\n",
57 Bcb
->AllocationSize
.QuadPart
,
58 Bcb
->FileSize
.QuadPart
);
60 if (ReadOffset
% Bcb
->CacheSegmentSize
+ Length
> Bcb
->CacheSegmentSize
)
64 ROffset
= ROUND_DOWN (ReadOffset
, Bcb
->CacheSegmentSize
);
65 Status
= CcRosRequestCacheSegment(Bcb
, ROffset
,
68 if (!NT_SUCCESS(Status
))
74 if (!(Flags
& MAP_WAIT
))
76 CcRosReleaseCacheSegment(Bcb
, CacheSeg
, FALSE
, FALSE
, FALSE
);
79 if (!NT_SUCCESS(ReadCacheSegment(CacheSeg
)))
81 CcRosReleaseCacheSegment(Bcb
, CacheSeg
, FALSE
, FALSE
, FALSE
);
86 *pBuffer
= (PVOID
)((ULONG_PTR
)(*pBuffer
) + (ReadOffset
% Bcb
->CacheSegmentSize
));
87 iBcb
= ExAllocateFromNPagedLookasideList(&iBcbLookasideList
);
90 CcRosReleaseCacheSegment(Bcb
, CacheSeg
, TRUE
, FALSE
, FALSE
);
93 memset(iBcb
, 0, sizeof(INTERNAL_BCB
));
94 iBcb
->PFCB
.NodeTypeCode
= 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
95 iBcb
->PFCB
.NodeByteSize
= sizeof(PUBLIC_BCB
);
96 iBcb
->PFCB
.MappedLength
= Length
;
97 iBcb
->PFCB
.MappedFileOffset
= *FileOffset
;
98 iBcb
->CacheSegment
= CacheSeg
;
111 IN PFILE_OBJECT FileObject
,
112 IN PLARGE_INTEGER FileOffset
,
118 /* no-op for current implementation. */
128 IN PFILE_OBJECT FileObject
,
129 IN PLARGE_INTEGER FileOffset
,
136 if (CcMapData(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
))
138 if (CcPinMappedData(FileObject
, FileOffset
, Length
, Flags
, Bcb
))
152 IN PFILE_OBJECT FileObject
,
153 IN PLARGE_INTEGER FileOffset
,
162 * FIXME: This is function is similar to CcPinRead, but doesn't
163 * read the data if they're not present. Instead it should just
164 * prepare the cache segments and zero them out if Zero == TRUE.
166 * For now calling CcPinRead is better than returning error or
167 * just having UNIMPLEMENTED here.
169 return CcPinRead(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
);
176 CcSetDirtyPinnedData (IN PVOID Bcb
,
177 IN PLARGE_INTEGER Lsn
)
179 PINTERNAL_BCB iBcb
= Bcb
;
188 CcUnpinData (IN PVOID Bcb
)
190 PINTERNAL_BCB iBcb
= Bcb
;
191 CcRosReleaseCacheSegment(iBcb
->CacheSegment
->Bcb
, iBcb
->CacheSegment
, TRUE
,
193 if (--iBcb
->RefCount
== 0)
195 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);
204 CcUnpinDataForThread (
206 IN ERESOURCE_THREAD ResourceThreadId
221 PINTERNAL_BCB iBcb
= Bcb
;
232 IN BOOLEAN WriteThrough
,
233 IN PIO_STATUS_BLOCK IoStatus
236 PINTERNAL_BCB iBcb
= Bcb
;
238 if (--iBcb
->RefCount
== 0)
240 IoStatus
->Information
= 0;
243 KeWaitForSingleObject(&iBcb
->CacheSegment
->Mutex
,
248 if (iBcb
->CacheSegment
->Dirty
)
250 IoStatus
->Status
= CcRosFlushCacheSegment(iBcb
->CacheSegment
);
254 IoStatus
->Status
= STATUS_SUCCESS
;
256 KeReleaseMutex(&iBcb
->CacheSegment
->Mutex
, 0);
260 IoStatus
->Status
= STATUS_SUCCESS
;
263 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);