2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/cc/fs.c
5 * PURPOSE: Implements cache managers functions useful for File Systems
7 * PROGRAMMERS: Alex Ionescu
10 /* INCLUDES ******************************************************************/
16 #ifndef VACB_MAPPING_GRANULARITY
17 #define VACB_MAPPING_GRANULARITY (256 * 1024)
20 /* GLOBALS *****************************************************************/
22 extern KGUARDED_MUTEX ViewLock
;
23 extern ULONG DirtyPageCount
;
25 NTSTATUS
CcRosInternalFreeVacb(PROS_VACB Vacb
);
27 /* FUNCTIONS *****************************************************************/
36 IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine
,
42 CCTRACE(CC_API_DEBUG
, "LogHandle=%p DirtyPageRoutine=%p Context1=%p Context2=%p\n",
43 LogHandle
, DirtyPageRoutine
, Context1
, Context2
);
55 CcGetFileObjectFromBcb (
58 PINTERNAL_BCB iBcb
= (PINTERNAL_BCB
)Bcb
;
60 CCTRACE(CC_API_DEBUG
, "Bcb=%p\n", Bcb
);
62 return iBcb
->Vacb
->SharedCacheMap
->FileObject
;
70 CcGetLsnForFileObject (
71 IN PFILE_OBJECT FileObject
,
72 OUT PLARGE_INTEGER OldestLsn OPTIONAL
)
76 CCTRACE(CC_API_DEBUG
, "FileObject=%p\n", FileObject
);
88 CcInitializeCacheMap (
89 IN PFILE_OBJECT FileObject
,
90 IN PCC_FILE_SIZES FileSizes
,
92 IN PCACHE_MANAGER_CALLBACKS CallBacks
,
93 IN PVOID LazyWriterContext
)
100 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileSizes=%p PinAccess=%d CallBacks=%p LazyWriterContext=%p\n",
101 FileObject
, FileSizes
, PinAccess
, CallBacks
, LazyWriterContext
);
103 /* Call old ROS cache init function */
104 Status
= CcRosInitializeFileCache(FileObject
,
109 if (!NT_SUCCESS(Status
))
110 ExRaiseStatus(Status
);
121 CCTRACE(CC_API_DEBUG
, "Vpb=%p\n", Vpb
);
132 CcPurgeCacheSection (
133 IN PSECTION_OBJECT_POINTERS SectionObjectPointer
,
134 IN PLARGE_INTEGER FileOffset OPTIONAL
,
136 IN BOOLEAN UninitializeCacheMaps
)
138 PROS_SHARED_CACHE_MAP SharedCacheMap
;
139 LONGLONG StartOffset
;
143 PLIST_ENTRY ListEntry
;
147 CCTRACE(CC_API_DEBUG
, "SectionObjectPointer=%p\n FileOffset=%p Length=%lu UninitializeCacheMaps=%d",
148 SectionObjectPointer
, FileOffset
, Length
, UninitializeCacheMaps
);
150 if (UninitializeCacheMaps
)
152 DPRINT1("FIXME: CcPurgeCacheSection not uninitializing private cache maps\n");
155 SharedCacheMap
= SectionObjectPointer
->SharedCacheMap
;
157 StartOffset
= FileOffset
!= NULL
? FileOffset
->QuadPart
: 0;
158 if (Length
== 0 || FileOffset
== NULL
)
160 EndOffset
= MAXLONGLONG
;
164 EndOffset
= StartOffset
+ Length
;
165 ASSERT(EndOffset
> StartOffset
);
168 InitializeListHead(&FreeList
);
170 KeAcquireGuardedMutex(&ViewLock
);
171 KeAcquireSpinLock(&SharedCacheMap
->CacheMapLock
, &OldIrql
);
172 ListEntry
= SharedCacheMap
->CacheMapVacbListHead
.Flink
;
173 while (ListEntry
!= &SharedCacheMap
->CacheMapVacbListHead
)
175 Vacb
= CONTAINING_RECORD(ListEntry
, ROS_VACB
, CacheMapVacbListEntry
);
176 ListEntry
= ListEntry
->Flink
;
178 /* Skip VACBs outside the range, or only partially in range */
179 if (Vacb
->FileOffset
.QuadPart
< StartOffset
)
183 ViewEnd
= min(Vacb
->FileOffset
.QuadPart
+ VACB_MAPPING_GRANULARITY
,
184 SharedCacheMap
->SectionSize
.QuadPart
);
185 if (ViewEnd
>= EndOffset
)
190 ASSERT((Vacb
->ReferenceCount
== 0) ||
191 (Vacb
->ReferenceCount
== 1 && Vacb
->Dirty
));
193 /* This VACB is in range, so unlink it and mark for free */
194 RemoveEntryList(&Vacb
->VacbLruListEntry
);
197 RemoveEntryList(&Vacb
->DirtyVacbListEntry
);
198 DirtyPageCount
-= VACB_MAPPING_GRANULARITY
/ PAGE_SIZE
;
200 RemoveEntryList(&Vacb
->CacheMapVacbListEntry
);
201 InsertHeadList(&FreeList
, &Vacb
->CacheMapVacbListEntry
);
203 KeReleaseSpinLock(&SharedCacheMap
->CacheMapLock
, OldIrql
);
204 KeReleaseGuardedMutex(&ViewLock
);
206 while (!IsListEmpty(&FreeList
))
208 Vacb
= CONTAINING_RECORD(RemoveHeadList(&FreeList
),
210 CacheMapVacbListEntry
);
211 CcRosInternalFreeVacb(Vacb
);
223 IN PFILE_OBJECT FileObject
,
224 IN PCC_FILE_SIZES FileSizes
)
227 PROS_SHARED_CACHE_MAP SharedCacheMap
;
229 CCTRACE(CC_API_DEBUG
, "FileObject=%p FileSizes=%p\n",
230 FileObject
, FileSizes
);
232 DPRINT("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n",
233 FileObject
, FileSizes
);
234 DPRINT("AllocationSize %I64d, FileSize %I64d, ValidDataLength %I64d\n",
235 FileSizes
->AllocationSize
.QuadPart
,
236 FileSizes
->FileSize
.QuadPart
,
237 FileSizes
->ValidDataLength
.QuadPart
);
239 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
242 * It is valid to call this function on file objects that weren't
243 * initialized for caching. In this case it's simple no-op.
245 if (SharedCacheMap
== NULL
)
248 if (FileSizes
->AllocationSize
.QuadPart
< SharedCacheMap
->SectionSize
.QuadPart
)
250 CcPurgeCacheSection(FileObject
->SectionObjectPointer
,
251 &FileSizes
->AllocationSize
,
256 KeAcquireSpinLock(&SharedCacheMap
->CacheMapLock
, &oldirql
);
257 SharedCacheMap
->SectionSize
= FileSizes
->AllocationSize
;
258 SharedCacheMap
->FileSize
= FileSizes
->FileSize
;
259 KeReleaseSpinLock(&SharedCacheMap
->CacheMapLock
, oldirql
);
267 CcSetLogHandleForFile (
268 IN PFILE_OBJECT FileObject
,
270 IN PFLUSH_TO_LSN FlushToLsnRoutine
)
272 CCTRACE(CC_API_DEBUG
, "FileObject=%p LogHandle=%p FlushToLsnRoutine=%p\n",
273 FileObject
, LogHandle
, FlushToLsnRoutine
);
283 CcUninitializeCacheMap (
284 IN PFILE_OBJECT FileObject
,
285 IN PLARGE_INTEGER TruncateSize OPTIONAL
,
286 IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL
)
289 PROS_SHARED_CACHE_MAP SharedCacheMap
;
292 CCTRACE(CC_API_DEBUG
, "FileObject=%p TruncateSize=%p UninitializeCompleteEvent=%p\n",
293 FileObject
, TruncateSize
, UninitializeCompleteEvent
);
295 if (TruncateSize
!= NULL
&&
296 FileObject
->SectionObjectPointer
!= NULL
&&
297 FileObject
->SectionObjectPointer
->SharedCacheMap
!= NULL
)
299 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
300 KeAcquireSpinLock(&SharedCacheMap
->CacheMapLock
, &OldIrql
);
301 if (SharedCacheMap
->FileSize
.QuadPart
> TruncateSize
->QuadPart
)
303 SharedCacheMap
->FileSize
= *TruncateSize
;
305 KeReleaseSpinLock(&SharedCacheMap
->CacheMapLock
, OldIrql
);
306 CcPurgeCacheSection(FileObject
->SectionObjectPointer
,
312 Status
= CcRosReleaseFileCache(FileObject
);
313 if (UninitializeCompleteEvent
)
315 KeSetEvent(&UninitializeCompleteEvent
->Event
, IO_NO_INCREMENT
, FALSE
);
317 return NT_SUCCESS(Status
);
323 IN PFILE_OBJECT FileObject
,
324 IN PCC_FILE_SIZES FileSizes
)
326 PROS_SHARED_CACHE_MAP SharedCacheMap
;
328 SharedCacheMap
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
333 FileSizes
->AllocationSize
= SharedCacheMap
->SectionSize
;
334 FileSizes
->FileSize
= FileSizes
->ValidDataLength
= SharedCacheMap
->FileSize
;