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