1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS kernel
3 * FILE: ntoskrnl/cc/fs.c
4 * PURPOSE: Implements cache managers functions useful for File Systems
5 * PROGRAMMER: Alex Ionescu
10 /* INCLUDES ******************************************************************/
12 #include <ddk/ntddk.h>
13 #include <ddk/ntifs.h>
14 #include <internal/mm.h>
15 #include <internal/cc.h>
16 #include <internal/pool.h>
17 #include <internal/io.h>
18 #include <ntos/minmax.h>
21 #include <internal/debug.h>
23 /* GLOBALS *****************************************************************/
25 extern FAST_MUTEX ViewLock
;
26 extern ULONG DirtyPageCount
;
28 NTSTATUS
CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg
);
30 /* FUNCTIONS *****************************************************************/
39 IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine
,
56 CcGetFileObjectFromBcb (
69 CcGetLsnForFileObject (
70 IN PFILE_OBJECT FileObject
,
71 OUT PLARGE_INTEGER OldestLsn OPTIONAL
86 CcInitializeCacheMap (
87 IN PFILE_OBJECT FileObject
,
88 IN PCC_FILE_SIZES FileSizes
,
90 IN PCACHE_MANAGER_CALLBACKS CallBacks
,
91 IN PVOID LazyWriterContext
115 CcPurgeCacheSection (
116 IN PSECTION_OBJECT_POINTERS SectionObjectPointer
,
117 IN PLARGE_INTEGER FileOffset OPTIONAL
,
119 IN BOOLEAN UninitializeCacheMaps
131 CcSetFileSizes (IN PFILE_OBJECT FileObject
,
132 IN PCC_FILE_SIZES FileSizes
)
136 PLIST_ENTRY current_entry
;
137 PCACHE_SEGMENT current
;
138 LIST_ENTRY FreeListHead
;
141 DPRINT("CcSetFileSizes(FileObject %x, FileSizes %x)\n",
142 FileObject
, FileSizes
);
143 DPRINT("AllocationSize %d, FileSize %d, ValidDataLength %d\n",
144 (ULONG
)FileSizes
->AllocationSize
.QuadPart
,
145 (ULONG
)FileSizes
->FileSize
.QuadPart
,
146 (ULONG
)FileSizes
->ValidDataLength
.QuadPart
);
148 Bcb
= FileObject
->SectionObjectPointer
->SharedCacheMap
;
151 if (FileSizes
->AllocationSize
.QuadPart
< Bcb
->AllocationSize
.QuadPart
)
153 InitializeListHead(&FreeListHead
);
154 ExAcquireFastMutex(&ViewLock
);
155 KeAcquireSpinLock(&Bcb
->BcbLock
, &oldirql
);
157 current_entry
= Bcb
->BcbSegmentListHead
.Flink
;
158 while (current_entry
!= &Bcb
->BcbSegmentListHead
)
160 current
= CONTAINING_RECORD(current_entry
, CACHE_SEGMENT
, BcbSegmentListEntry
);
161 current_entry
= current_entry
->Flink
;
162 if (current
->FileOffset
> FileSizes
->AllocationSize
.QuadPart
)
164 if (current
->ReferenceCount
== 0 || (current
->ReferenceCount
== 1 && current
->Dirty
))
166 RemoveEntryList(¤t
->BcbSegmentListEntry
);
167 RemoveEntryList(¤t
->CacheSegmentListEntry
);
168 RemoveEntryList(¤t
->CacheSegmentLRUListEntry
);
171 RemoveEntryList(¤t
->DirtySegmentListEntry
);
172 DirtyPageCount
-= Bcb
->CacheSegmentSize
/ PAGE_SIZE
;
174 InsertHeadList(&FreeListHead
, ¤t
->BcbSegmentListEntry
);
178 DPRINT1("Anyone has referenced a cache segment behind the new size.\n");
184 Bcb
->AllocationSize
= FileSizes
->AllocationSize
;
185 Bcb
->FileSize
= FileSizes
->FileSize
;
186 KeReleaseSpinLock(&Bcb
->BcbLock
, oldirql
);
187 ExReleaseFastMutex(&ViewLock
);
189 current_entry
= FreeListHead
.Flink
;
190 while(current_entry
!= &FreeListHead
)
192 current
= CONTAINING_RECORD(current_entry
, CACHE_SEGMENT
, BcbSegmentListEntry
);
193 current_entry
= current_entry
->Flink
;
194 Status
= CcRosInternalFreeCacheSegment(current
);
195 if (!NT_SUCCESS(Status
))
197 DPRINT1("CcRosInternalFreeCacheSegment failed, status = %x\n");
204 KeAcquireSpinLock(&Bcb
->BcbLock
, &oldirql
);
205 Bcb
->AllocationSize
= FileSizes
->AllocationSize
;
206 Bcb
->FileSize
= FileSizes
->FileSize
;
207 KeReleaseSpinLock(&Bcb
->BcbLock
, oldirql
);
216 CcSetLogHandleForFile (
217 IN PFILE_OBJECT FileObject
,
219 IN PFLUSH_TO_LSN FlushToLsnRoutine
230 CcUninitializeCacheMap (
231 IN PFILE_OBJECT FileObject
,
232 IN PLARGE_INTEGER TruncateSize OPTIONAL
,
233 IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL