4feb125f708127670b7ef5613a99b932088dca7e
[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 PinAccess,
107 CallBacks,
108 LazyWriterContext);
109 if (!NT_SUCCESS(Status))
110 ExRaiseStatus(Status);
111 }
112
113 /*
114 * @unimplemented
115 */
116 BOOLEAN
117 NTAPI
118 CcIsThereDirtyData (
119 IN PVPB Vpb)
120 {
121 CCTRACE(CC_API_DEBUG, "Vpb=%p\n", Vpb);
122
123 UNIMPLEMENTED;
124 return FALSE;
125 }
126
127 /*
128 * @unimplemented
129 */
130 BOOLEAN
131 NTAPI
132 CcPurgeCacheSection (
133 IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
134 IN PLARGE_INTEGER FileOffset OPTIONAL,
135 IN ULONG Length,
136 IN BOOLEAN UninitializeCacheMaps)
137 {
138 CCTRACE(CC_API_DEBUG, "SectionObjectPointer=%p\n FileOffset=%p Length=%lu UninitializeCacheMaps=%d",
139 SectionObjectPointer, FileOffset, Length, UninitializeCacheMaps);
140
141 //UNIMPLEMENTED;
142 return FALSE;
143 }
144
145
146 /*
147 * @implemented
148 */
149 VOID NTAPI
150 CcSetFileSizes (
151 IN PFILE_OBJECT FileObject,
152 IN PCC_FILE_SIZES FileSizes)
153 {
154 KIRQL oldirql;
155 PROS_SHARED_CACHE_MAP SharedCacheMap;
156 PLIST_ENTRY current_entry;
157 PROS_VACB current;
158 LIST_ENTRY FreeListHead;
159 NTSTATUS Status;
160
161 CCTRACE(CC_API_DEBUG, "FileObject=%p FileSizes=%p\n",
162 FileObject, FileSizes);
163
164 DPRINT("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n",
165 FileObject, FileSizes);
166 DPRINT("AllocationSize %I64d, FileSize %I64d, ValidDataLength %I64d\n",
167 FileSizes->AllocationSize.QuadPart,
168 FileSizes->FileSize.QuadPart,
169 FileSizes->ValidDataLength.QuadPart);
170
171 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
172
173 /*
174 * It is valid to call this function on file objects that weren't
175 * initialized for caching. In this case it's simple no-op.
176 */
177 if (SharedCacheMap == NULL)
178 return;
179
180 if (FileSizes->AllocationSize.QuadPart < SharedCacheMap->SectionSize.QuadPart)
181 {
182 InitializeListHead(&FreeListHead);
183 KeAcquireGuardedMutex(&ViewLock);
184 KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql);
185
186 current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
187 while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
188 {
189 current = CONTAINING_RECORD(current_entry,
190 ROS_VACB,
191 CacheMapVacbListEntry);
192 current_entry = current_entry->Flink;
193 if (current->FileOffset.QuadPart >= FileSizes->AllocationSize.QuadPart)
194 {
195 if ((current->ReferenceCount == 0) || ((current->ReferenceCount == 1) && current->Dirty))
196 {
197 RemoveEntryList(&current->CacheMapVacbListEntry);
198 RemoveEntryList(&current->VacbLruListEntry);
199 if (current->Dirty)
200 {
201 RemoveEntryList(&current->DirtyVacbListEntry);
202 DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
203 }
204 InsertHeadList(&FreeListHead, &current->CacheMapVacbListEntry);
205 }
206 else
207 {
208 DPRINT1("Someone has referenced a VACB behind the new size.\n");
209 KeBugCheck(CACHE_MANAGER);
210 }
211 }
212 }
213
214 SharedCacheMap->SectionSize = FileSizes->AllocationSize;
215 SharedCacheMap->FileSize = FileSizes->FileSize;
216 KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldirql);
217 KeReleaseGuardedMutex(&ViewLock);
218
219 current_entry = FreeListHead.Flink;
220 while(current_entry != &FreeListHead)
221 {
222 current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
223 current_entry = current_entry->Flink;
224 Status = CcRosInternalFreeVacb(current);
225 if (!NT_SUCCESS(Status))
226 {
227 DPRINT1("CcRosInternalFreeVacb failed, status = %x\n", Status);
228 KeBugCheck(CACHE_MANAGER);
229 }
230 }
231 }
232 else
233 {
234 KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql);
235 SharedCacheMap->SectionSize = FileSizes->AllocationSize;
236 SharedCacheMap->FileSize = FileSizes->FileSize;
237 KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldirql);
238 }
239 }
240
241 /*
242 * @unimplemented
243 */
244 VOID
245 NTAPI
246 CcSetLogHandleForFile (
247 IN PFILE_OBJECT FileObject,
248 IN PVOID LogHandle,
249 IN PFLUSH_TO_LSN FlushToLsnRoutine)
250 {
251 CCTRACE(CC_API_DEBUG, "FileObject=%p LogHandle=%p FlushToLsnRoutine=%p\n",
252 FileObject, LogHandle, FlushToLsnRoutine);
253
254 UNIMPLEMENTED;
255 }
256
257 /*
258 * @unimplemented
259 */
260 BOOLEAN
261 NTAPI
262 CcUninitializeCacheMap (
263 IN PFILE_OBJECT FileObject,
264 IN PLARGE_INTEGER TruncateSize OPTIONAL,
265 IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL)
266 {
267 NTSTATUS Status;
268
269 CCTRACE(CC_API_DEBUG, "FileObject=%p TruncateSize=%p UninitializeCompleteEvent=%p\n",
270 FileObject, TruncateSize, UninitializeCompleteEvent);
271
272 Status = CcRosReleaseFileCache(FileObject);
273 if (UninitializeCompleteEvent)
274 KeSetEvent(&UninitializeCompleteEvent->Event, IO_NO_INCREMENT, FALSE);
275 return NT_SUCCESS(Status);
276 }
277
278 BOOLEAN
279 NTAPI
280 CcGetFileSizes (
281 IN PFILE_OBJECT FileObject,
282 IN PCC_FILE_SIZES FileSizes)
283 {
284 PROS_SHARED_CACHE_MAP SharedCacheMap;
285
286 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
287
288 if (!SharedCacheMap)
289 return FALSE;
290
291 FileSizes->AllocationSize = SharedCacheMap->SectionSize;
292 FileSizes->FileSize = FileSizes->ValidDataLength = SharedCacheMap->FileSize;
293 return TRUE;
294 }