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