forget update de.rc
[reactos.git] / reactos / ntoskrnl / cc / fs.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/cc/fs.c
6 * PURPOSE: Implements cache managers functions useful for File Systems
7 *
8 * PROGRAMMERS: Alex Ionescu
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 #ifndef VACB_MAPPING_GRANULARITY
18 #define VACB_MAPPING_GRANULARITY (256 * 1024)
19 #endif
20
21 /* GLOBALS *****************************************************************/
22
23 extern FAST_MUTEX ViewLock;
24 extern ULONG DirtyPageCount;
25
26 NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg);
27
28 /* FUNCTIONS *****************************************************************/
29
30 /*
31 * @unimplemented
32 */
33 LARGE_INTEGER
34 STDCALL
35 CcGetDirtyPages (
36 IN PVOID LogHandle,
37 IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine,
38 IN PVOID Context1,
39 IN PVOID Context2
40 )
41 {
42 LARGE_INTEGER i;
43 UNIMPLEMENTED;
44 i.QuadPart = 0;
45 return i;
46 }
47
48 /*
49 * @implemented
50 */
51 PFILE_OBJECT
52 STDCALL
53 CcGetFileObjectFromBcb (
54 IN PVOID Bcb
55 )
56 {
57 PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb;
58 return iBcb->CacheSegment->Bcb->FileObject;
59 }
60
61 /*
62 * @unimplemented
63 */
64 LARGE_INTEGER
65 STDCALL
66 CcGetLsnForFileObject (
67 IN PFILE_OBJECT FileObject,
68 OUT PLARGE_INTEGER OldestLsn OPTIONAL
69 )
70 {
71 LARGE_INTEGER i;
72 UNIMPLEMENTED;
73 i.QuadPart = 0;
74 return i;
75 }
76
77 /*
78 * @unimplemented
79 */
80 VOID
81 STDCALL
82 CcInitializeCacheMap (
83 IN PFILE_OBJECT FileObject,
84 IN PCC_FILE_SIZES FileSizes,
85 IN BOOLEAN PinAccess,
86 IN PCACHE_MANAGER_CALLBACKS CallBacks,
87 IN PVOID LazyWriterContext
88 )
89 {
90 CcRosInitializeFileCache(FileObject, VACB_MAPPING_GRANULARITY);
91 }
92
93 /*
94 * @unimplemented
95 */
96 BOOLEAN
97 STDCALL
98 CcIsThereDirtyData (
99 IN PVPB Vpb
100 )
101 {
102 UNIMPLEMENTED;
103 return FALSE;
104 }
105
106 /*
107 * @unimplemented
108 */
109 BOOLEAN
110 STDCALL
111 CcPurgeCacheSection (
112 IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
113 IN PLARGE_INTEGER FileOffset OPTIONAL,
114 IN ULONG Length,
115 IN BOOLEAN UninitializeCacheMaps
116 )
117 {
118 UNIMPLEMENTED;
119 return FALSE;
120 }
121
122
123 /*
124 * @implemented
125 */
126 VOID STDCALL
127 CcSetFileSizes (IN PFILE_OBJECT FileObject,
128 IN PCC_FILE_SIZES FileSizes)
129 {
130 KIRQL oldirql;
131 PBCB Bcb;
132 PLIST_ENTRY current_entry;
133 PCACHE_SEGMENT 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 %d, FileSize %d, ValidDataLength %d\n",
140 (ULONG)FileSizes->AllocationSize.QuadPart,
141 (ULONG)FileSizes->FileSize.QuadPart,
142 (ULONG)FileSizes->ValidDataLength.QuadPart);
143
144 Bcb = 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 (Bcb == NULL)
151 return;
152
153 if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart)
154 {
155 InitializeListHead(&FreeListHead);
156 ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
157 KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
158
159 current_entry = Bcb->BcbSegmentListHead.Flink;
160 while (current_entry != &Bcb->BcbSegmentListHead)
161 {
162 current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
163 current_entry = current_entry->Flink;
164 if (current->FileOffset > FileSizes->AllocationSize.QuadPart)
165 {
166 if (current->ReferenceCount == 0 || (current->ReferenceCount == 1 && current->Dirty))
167 {
168 RemoveEntryList(&current->BcbSegmentListEntry);
169 RemoveEntryList(&current->CacheSegmentListEntry);
170 RemoveEntryList(&current->CacheSegmentLRUListEntry);
171 if (current->Dirty)
172 {
173 RemoveEntryList(&current->DirtySegmentListEntry);
174 DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE;
175 }
176 InsertHeadList(&FreeListHead, &current->BcbSegmentListEntry);
177 }
178 else
179 {
180 DPRINT1("Anyone has referenced a cache segment behind the new size.\n");
181 KEBUGCHECKCC;
182 }
183 }
184 }
185
186 Bcb->AllocationSize = FileSizes->AllocationSize;
187 Bcb->FileSize = FileSizes->FileSize;
188 KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
189 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
190
191 current_entry = FreeListHead.Flink;
192 while(current_entry != &FreeListHead)
193 {
194 current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
195 current_entry = current_entry->Flink;
196 Status = CcRosInternalFreeCacheSegment(current);
197 if (!NT_SUCCESS(Status))
198 {
199 DPRINT1("CcRosInternalFreeCacheSegment failed, status = %x\n", Status);
200 KEBUGCHECK(0);
201 }
202 }
203 }
204 else
205 {
206 KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
207 Bcb->AllocationSize = FileSizes->AllocationSize;
208 Bcb->FileSize = FileSizes->FileSize;
209 KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
210 }
211 }
212
213 /*
214 * @unimplemented
215 */
216 VOID
217 STDCALL
218 CcSetLogHandleForFile (
219 IN PFILE_OBJECT FileObject,
220 IN PVOID LogHandle,
221 IN PFLUSH_TO_LSN FlushToLsnRoutine
222 )
223 {
224 UNIMPLEMENTED;
225 }
226
227 /*
228 * @unimplemented
229 */
230 BOOLEAN
231 STDCALL
232 CcUninitializeCacheMap (
233 IN PFILE_OBJECT FileObject,
234 IN PLARGE_INTEGER TruncateSize OPTIONAL,
235 IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL
236 )
237 {
238 #if 0
239 UNIMPLEMENTED;
240 return FALSE;
241 #else
242 return CcRosReleaseFileCache(FileObject);
243 #endif
244 }