5fb3ca458e261365e79467715ac61d25350cce86
[reactos.git] / reactos / ntoskrnl / cc / fs.c
1 /*
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
6 *
7 * PROGRAMMERS: Alex Ionescu
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 #ifndef VACB_MAPPING_GRANULARITY
17 #define VACB_MAPPING_GRANULARITY (256 * 1024)
18 #endif
19
20 /* GLOBALS *****************************************************************/
21
22 extern KGUARDED_MUTEX ViewLock;
23 extern ULONG DirtyPageCount;
24
25 NTSTATUS CcRosInternalFreeVacb(PROS_VACB Vacb);
26
27 /* FUNCTIONS *****************************************************************/
28
29 /*
30 * @unimplemented
31 */
32 LARGE_INTEGER
33 NTAPI
34 CcGetDirtyPages (
35 IN PVOID LogHandle,
36 IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine,
37 IN PVOID Context1,
38 IN PVOID Context2)
39 {
40 LARGE_INTEGER i;
41
42 CCTRACE(CC_API_DEBUG, "LogHandle=%p DirtyPageRoutine=%p Context1=%p Context2=%p\n",
43 LogHandle, DirtyPageRoutine, Context1, Context2);
44
45 UNIMPLEMENTED;
46 i.QuadPart = 0;
47 return i;
48 }
49
50 /*
51 * @implemented
52 */
53 PFILE_OBJECT
54 NTAPI
55 CcGetFileObjectFromBcb (
56 IN PVOID Bcb)
57 {
58 PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb;
59
60 CCTRACE(CC_API_DEBUG, "Bcb=%p\n", Bcb);
61
62 return iBcb->Vacb->SharedCacheMap->FileObject;
63 }
64
65 /*
66 * @unimplemented
67 */
68 LARGE_INTEGER
69 NTAPI
70 CcGetLsnForFileObject (
71 IN PFILE_OBJECT FileObject,
72 OUT PLARGE_INTEGER OldestLsn OPTIONAL)
73 {
74 LARGE_INTEGER i;
75
76 CCTRACE(CC_API_DEBUG, "FileObject=%p\n", FileObject);
77
78 UNIMPLEMENTED;
79 i.QuadPart = 0;
80 return i;
81 }
82
83 /*
84 * @unimplemented
85 */
86 VOID
87 NTAPI
88 CcInitializeCacheMap (
89 IN PFILE_OBJECT FileObject,
90 IN PCC_FILE_SIZES FileSizes,
91 IN BOOLEAN PinAccess,
92 IN PCACHE_MANAGER_CALLBACKS CallBacks,
93 IN PVOID LazyWriterContext)
94 {
95 NTSTATUS Status;
96
97 ASSERT(FileObject);
98 ASSERT(FileSizes);
99
100 CCTRACE(CC_API_DEBUG, "FileObject=%p FileSizes=%p PinAccess=%d CallBacks=%p LazyWriterContext=%p\n",
101 FileObject, FileSizes, PinAccess, CallBacks, LazyWriterContext);
102
103 /* Call old ROS cache init function */
104 Status = CcRosInitializeFileCache(FileObject,
105 FileSizes,
106 CallBacks,
107 LazyWriterContext);
108 if (!NT_SUCCESS(Status))
109 ExRaiseStatus(Status);
110 }
111
112 /*
113 * @unimplemented
114 */
115 BOOLEAN
116 NTAPI
117 CcIsThereDirtyData (
118 IN PVPB Vpb)
119 {
120 CCTRACE(CC_API_DEBUG, "Vpb=%p\n", Vpb);
121
122 UNIMPLEMENTED;
123 return FALSE;
124 }
125
126 /*
127 * @unimplemented
128 */
129 BOOLEAN
130 NTAPI
131 CcPurgeCacheSection (
132 IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
133 IN PLARGE_INTEGER FileOffset OPTIONAL,
134 IN ULONG Length,
135 IN BOOLEAN UninitializeCacheMaps)
136 {
137 CCTRACE(CC_API_DEBUG, "SectionObjectPointer=%p\n FileOffset=%p Length=%lu UninitializeCacheMaps=%d",
138 SectionObjectPointer, FileOffset, Length, UninitializeCacheMaps);
139
140 //UNIMPLEMENTED;
141 return FALSE;
142 }
143
144
145 /*
146 * @implemented
147 */
148 VOID NTAPI
149 CcSetFileSizes (
150 IN PFILE_OBJECT FileObject,
151 IN PCC_FILE_SIZES FileSizes)
152 {
153 KIRQL oldirql;
154 PROS_SHARED_CACHE_MAP SharedCacheMap;
155 PLIST_ENTRY current_entry;
156 PROS_VACB current;
157 LIST_ENTRY FreeListHead;
158 NTSTATUS Status;
159
160 CCTRACE(CC_API_DEBUG, "FileObject=%p FileSizes=%p\n",
161 FileObject, FileSizes);
162
163 DPRINT("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n",
164 FileObject, FileSizes);
165 DPRINT("AllocationSize %I64d, FileSize %I64d, ValidDataLength %I64d\n",
166 FileSizes->AllocationSize.QuadPart,
167 FileSizes->FileSize.QuadPart,
168 FileSizes->ValidDataLength.QuadPart);
169
170 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
171
172 /*
173 * It is valid to call this function on file objects that weren't
174 * initialized for caching. In this case it's simple no-op.
175 */
176 if (SharedCacheMap == NULL)
177 return;
178
179 if (FileSizes->AllocationSize.QuadPart < SharedCacheMap->SectionSize.QuadPart)
180 {
181 InitializeListHead(&FreeListHead);
182 KeAcquireGuardedMutex(&ViewLock);
183 KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql);
184
185 current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
186 while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
187 {
188 current = CONTAINING_RECORD(current_entry,
189 ROS_VACB,
190 CacheMapVacbListEntry);
191 current_entry = current_entry->Flink;
192 if (current->FileOffset.QuadPart >= FileSizes->AllocationSize.QuadPart)
193 {
194 if ((current->ReferenceCount == 0) || ((current->ReferenceCount == 1) && current->Dirty))
195 {
196 RemoveEntryList(&current->CacheMapVacbListEntry);
197 RemoveEntryList(&current->VacbLruListEntry);
198 if (current->Dirty)
199 {
200 RemoveEntryList(&current->DirtyVacbListEntry);
201 DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
202 }
203 InsertHeadList(&FreeListHead, &current->CacheMapVacbListEntry);
204 }
205 else
206 {
207 DPRINT1("Someone has referenced a VACB behind the new size.\n");
208 KeBugCheck(CACHE_MANAGER);
209 }
210 }
211 }
212
213 SharedCacheMap->SectionSize = FileSizes->AllocationSize;
214 SharedCacheMap->FileSize = FileSizes->FileSize;
215 KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldirql);
216 KeReleaseGuardedMutex(&ViewLock);
217
218 current_entry = FreeListHead.Flink;
219 while(current_entry != &FreeListHead)
220 {
221 current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
222 current_entry = current_entry->Flink;
223 Status = CcRosInternalFreeVacb(current);
224 if (!NT_SUCCESS(Status))
225 {
226 DPRINT1("CcRosInternalFreeVacb failed, status = %x\n", Status);
227 KeBugCheck(CACHE_MANAGER);
228 }
229 }
230 }
231 else
232 {
233 KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql);
234 SharedCacheMap->SectionSize = FileSizes->AllocationSize;
235 SharedCacheMap->FileSize = FileSizes->FileSize;
236 KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldirql);
237 }
238 }
239
240 /*
241 * @unimplemented
242 */
243 VOID
244 NTAPI
245 CcSetLogHandleForFile (
246 IN PFILE_OBJECT FileObject,
247 IN PVOID LogHandle,
248 IN PFLUSH_TO_LSN FlushToLsnRoutine)
249 {
250 CCTRACE(CC_API_DEBUG, "FileObject=%p LogHandle=%p FlushToLsnRoutine=%p\n",
251 FileObject, LogHandle, FlushToLsnRoutine);
252
253 UNIMPLEMENTED;
254 }
255
256 /*
257 * @unimplemented
258 */
259 BOOLEAN
260 NTAPI
261 CcUninitializeCacheMap (
262 IN PFILE_OBJECT FileObject,
263 IN PLARGE_INTEGER TruncateSize OPTIONAL,
264 IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL)
265 {
266 NTSTATUS Status;
267
268 CCTRACE(CC_API_DEBUG, "FileObject=%p TruncateSize=%p UninitializeCompleteEvent=%p\n",
269 FileObject, TruncateSize, UninitializeCompleteEvent);
270
271 Status = CcRosReleaseFileCache(FileObject);
272 if (UninitializeCompleteEvent)
273 KeSetEvent(&UninitializeCompleteEvent->Event, IO_NO_INCREMENT, FALSE);
274 return NT_SUCCESS(Status);
275 }
276
277 BOOLEAN
278 NTAPI
279 CcGetFileSizes (
280 IN PFILE_OBJECT FileObject,
281 IN PCC_FILE_SIZES FileSizes)
282 {
283 PROS_SHARED_CACHE_MAP SharedCacheMap;
284
285 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
286
287 if (!SharedCacheMap)
288 return FALSE;
289
290 FileSizes->AllocationSize = SharedCacheMap->SectionSize;
291 FileSizes->FileSize = FileSizes->ValidDataLength = SharedCacheMap->FileSize;
292 return TRUE;
293 }