[NTOS:CC]
[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 UNIMPLEMENTED;
42 i.QuadPart = 0;
43 return i;
44 }
45
46 /*
47 * @implemented
48 */
49 PFILE_OBJECT
50 NTAPI
51 CcGetFileObjectFromBcb (
52 IN PVOID Bcb)
53 {
54 PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb;
55 return iBcb->Vacb->SharedCacheMap->FileObject;
56 }
57
58 /*
59 * @unimplemented
60 */
61 LARGE_INTEGER
62 NTAPI
63 CcGetLsnForFileObject (
64 IN PFILE_OBJECT FileObject,
65 OUT PLARGE_INTEGER OldestLsn OPTIONAL)
66 {
67 LARGE_INTEGER i;
68 UNIMPLEMENTED;
69 i.QuadPart = 0;
70 return i;
71 }
72
73 /*
74 * @unimplemented
75 */
76 VOID
77 NTAPI
78 CcInitializeCacheMap (
79 IN PFILE_OBJECT FileObject,
80 IN PCC_FILE_SIZES FileSizes,
81 IN BOOLEAN PinAccess,
82 IN PCACHE_MANAGER_CALLBACKS CallBacks,
83 IN PVOID LazyWriterContext)
84 {
85 ASSERT(FileObject);
86 ASSERT(FileSizes);
87
88 /* Call old ROS cache init function */
89 CcRosInitializeFileCache(FileObject,
90 FileSizes,
91 CallBacks,
92 LazyWriterContext);
93 }
94
95 /*
96 * @unimplemented
97 */
98 BOOLEAN
99 NTAPI
100 CcIsThereDirtyData (
101 IN PVPB Vpb)
102 {
103 UNIMPLEMENTED;
104 return FALSE;
105 }
106
107 /*
108 * @unimplemented
109 */
110 BOOLEAN
111 NTAPI
112 CcPurgeCacheSection (
113 IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
114 IN PLARGE_INTEGER FileOffset OPTIONAL,
115 IN ULONG Length,
116 IN BOOLEAN UninitializeCacheMaps)
117 {
118 //UNIMPLEMENTED;
119 return FALSE;
120 }
121
122
123 /*
124 * @implemented
125 */
126 VOID NTAPI
127 CcSetFileSizes (
128 IN PFILE_OBJECT FileObject,
129 IN PCC_FILE_SIZES FileSizes)
130 {
131 KIRQL oldirql;
132 PROS_SHARED_CACHE_MAP SharedCacheMap;
133 PLIST_ENTRY current_entry;
134 PROS_VACB current;
135 LIST_ENTRY FreeListHead;
136 NTSTATUS Status;
137
138 DPRINT("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n",
139 FileObject, FileSizes);
140 DPRINT("AllocationSize %I64d, FileSize %I64d, ValidDataLength %I64d\n",
141 FileSizes->AllocationSize.QuadPart,
142 FileSizes->FileSize.QuadPart,
143 FileSizes->ValidDataLength.QuadPart);
144
145 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
146
147 /*
148 * It is valid to call this function on file objects that weren't
149 * initialized for caching. In this case it's simple no-op.
150 */
151 if (SharedCacheMap == NULL)
152 return;
153
154 if (FileSizes->AllocationSize.QuadPart < SharedCacheMap->SectionSize.QuadPart)
155 {
156 InitializeListHead(&FreeListHead);
157 KeAcquireGuardedMutex(&ViewLock);
158 KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql);
159
160 current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
161 while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
162 {
163 current = CONTAINING_RECORD(current_entry,
164 ROS_VACB,
165 CacheMapVacbListEntry);
166 current_entry = current_entry->Flink;
167 if (current->FileOffset.QuadPart >= FileSizes->AllocationSize.QuadPart)
168 {
169 if ((current->ReferenceCount == 0) || ((current->ReferenceCount == 1) && current->Dirty))
170 {
171 RemoveEntryList(&current->CacheMapVacbListEntry);
172 RemoveEntryList(&current->VacbLruListEntry);
173 if (current->Dirty)
174 {
175 RemoveEntryList(&current->DirtyVacbListEntry);
176 DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
177 }
178 InsertHeadList(&FreeListHead, &current->CacheMapVacbListEntry);
179 }
180 else
181 {
182 DPRINT1("Someone has referenced a VACB behind the new size.\n");
183 KeBugCheck(CACHE_MANAGER);
184 }
185 }
186 }
187
188 SharedCacheMap->SectionSize = FileSizes->AllocationSize;
189 SharedCacheMap->FileSize = FileSizes->FileSize;
190 KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldirql);
191 KeReleaseGuardedMutex(&ViewLock);
192
193 current_entry = FreeListHead.Flink;
194 while(current_entry != &FreeListHead)
195 {
196 current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
197 current_entry = current_entry->Flink;
198 Status = CcRosInternalFreeVacb(current);
199 if (!NT_SUCCESS(Status))
200 {
201 DPRINT1("CcRosInternalFreeVacb failed, status = %x\n", Status);
202 KeBugCheck(CACHE_MANAGER);
203 }
204 }
205 }
206 else
207 {
208 KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql);
209 SharedCacheMap->SectionSize = FileSizes->AllocationSize;
210 SharedCacheMap->FileSize = FileSizes->FileSize;
211 KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldirql);
212 }
213 }
214
215 /*
216 * @unimplemented
217 */
218 VOID
219 NTAPI
220 CcSetLogHandleForFile (
221 IN PFILE_OBJECT FileObject,
222 IN PVOID LogHandle,
223 IN PFLUSH_TO_LSN FlushToLsnRoutine)
224 {
225 UNIMPLEMENTED;
226 }
227
228 /*
229 * @unimplemented
230 */
231 BOOLEAN
232 NTAPI
233 CcUninitializeCacheMap (
234 IN PFILE_OBJECT FileObject,
235 IN PLARGE_INTEGER TruncateSize OPTIONAL,
236 IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL)
237 {
238 NTSTATUS Status;
239
240 Status = CcRosReleaseFileCache(FileObject);
241 if (UninitializeCompleteEvent)
242 KeSetEvent(&UninitializeCompleteEvent->Event, IO_NO_INCREMENT, FALSE);
243 return NT_SUCCESS(Status);
244 }
245
246 BOOLEAN
247 NTAPI
248 CcGetFileSizes (
249 IN PFILE_OBJECT FileObject,
250 IN PCC_FILE_SIZES FileSizes)
251 {
252 PROS_SHARED_CACHE_MAP SharedCacheMap;
253
254 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
255
256 if (!SharedCacheMap)
257 return FALSE;
258
259 FileSizes->AllocationSize = SharedCacheMap->SectionSize;
260 FileSizes->FileSize = FileSizes->ValidDataLength = SharedCacheMap->FileSize;
261 return TRUE;
262 }