3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/cc/pin.c
6 * PURPOSE: Implements cache managers pinning interface
7 * PROGRAMMER: Hartmut Birr
12 /* INCLUDES ******************************************************************/
16 #include <internal/debug.h>
18 /* GLOBALS *******************************************************************/
20 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
22 extern NPAGED_LOOKASIDE_LIST iBcbLookasideList
;
24 /* FUNCTIONS *****************************************************************/
30 CcMapData (IN PFILE_OBJECT FileObject
,
31 IN PLARGE_INTEGER FileOffset
,
40 PCACHE_SEGMENT CacheSeg
;
45 DPRINT("CcMapData(FileObject %x, FileOffset %d, Length %d, Wait %d,"
46 " pBcb %x, pBuffer %x)\n", FileObject
, (ULONG
)FileOffset
->QuadPart
,
47 Length
, Wait
, pBcb
, pBuffer
);
49 ReadOffset
= (ULONG
)FileOffset
->QuadPart
;
50 Bcb
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
53 DPRINT("AllocationSize %d, FileSize %d\n",
54 (ULONG
)Bcb
->AllocationSize
.QuadPart
,
55 (ULONG
)Bcb
->FileSize
.QuadPart
);
57 if (ReadOffset
% Bcb
->CacheSegmentSize
+ Length
> Bcb
->CacheSegmentSize
)
61 ROffset
= ROUND_DOWN (ReadOffset
, Bcb
->CacheSegmentSize
);
62 Status
= CcRosRequestCacheSegment(Bcb
,
67 if (!NT_SUCCESS(Status
))
75 CcRosReleaseCacheSegment(Bcb
, CacheSeg
, FALSE
, FALSE
, FALSE
);
78 if (!NT_SUCCESS(ReadCacheSegment(CacheSeg
)))
80 CcRosReleaseCacheSegment(Bcb
, CacheSeg
, FALSE
, FALSE
, FALSE
);
85 *pBuffer
+= ReadOffset
% Bcb
->CacheSegmentSize
;
88 char* pTemp
= *pBuffer
;
89 pTemp
+= ReadOffset
% Bcb
->CacheSegmentSize
;
93 iBcb
= ExAllocateFromNPagedLookasideList(&iBcbLookasideList
);
96 CcRosReleaseCacheSegment(Bcb
, CacheSeg
, TRUE
, FALSE
, FALSE
);
99 memset(iBcb
, 0, sizeof(INTERNAL_BCB
));
100 iBcb
->PFCB
.NodeTypeCode
= 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
101 iBcb
->PFCB
.NodeByteSize
= sizeof(PUBLIC_BCB
);
102 iBcb
->PFCB
.MappedLength
= Length
;
103 iBcb
->PFCB
.MappedFileOffset
= *FileOffset
;
104 iBcb
->CacheSegment
= CacheSeg
;
117 IN PFILE_OBJECT FileObject
,
118 IN PLARGE_INTEGER FileOffset
,
124 /* no-op for current implementation. */
134 IN PFILE_OBJECT FileObject
,
135 IN PLARGE_INTEGER FileOffset
,
142 if (CcMapData(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
))
144 if (CcPinMappedData(FileObject
, FileOffset
, Length
, Flags
, Bcb
))
158 IN PFILE_OBJECT FileObject
,
159 IN PLARGE_INTEGER FileOffset
,
168 * FIXME: This is function is similar to CcPinRead, but doesn't
169 * read the data if they're not present. Instead it should just
170 * prepare the cache segments and zero them out if Zero == TRUE.
172 * For now calling CcPinRead is better than returning error or
173 * just having UNIMPLEMENTED here.
175 return CcPinRead(FileObject
, FileOffset
, Length
, Flags
, Bcb
, Buffer
);
182 CcSetDirtyPinnedData (IN PVOID Bcb
,
183 IN PLARGE_INTEGER Lsn
)
185 PINTERNAL_BCB iBcb
= Bcb
;
194 CcUnpinData (IN PVOID Bcb
)
196 PINTERNAL_BCB iBcb
= Bcb
;
197 CcRosReleaseCacheSegment(iBcb
->CacheSegment
->Bcb
, iBcb
->CacheSegment
, TRUE
,
199 if (--iBcb
->RefCount
== 0)
201 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);
210 CcUnpinDataForThread (
212 IN ERESOURCE_THREAD ResourceThreadId
227 PINTERNAL_BCB iBcb
= Bcb
;
238 IN BOOLEAN WriteThrough
,
239 IN PIO_STATUS_BLOCK IoStatus
242 PINTERNAL_BCB iBcb
= Bcb
;
244 if (--iBcb
->RefCount
== 0)
246 IoStatus
->Information
= 0;
249 ExAcquireFastMutex(&iBcb
->CacheSegment
->Lock
);
250 if (iBcb
->CacheSegment
->Dirty
)
252 IoStatus
->Status
= CcRosFlushCacheSegment(iBcb
->CacheSegment
);
256 IoStatus
->Status
= STATUS_SUCCESS
;
258 ExReleaseFastMutex(&iBcb
->CacheSegment
->Lock
);
262 IoStatus
->Status
= STATUS_SUCCESS
;
265 ExFreeToNPagedLookasideList(&iBcbLookasideList
, iBcb
);