NTOSKRNL.FSRtl MDL stubs added.
[reactos.git] / reactos / ntoskrnl / cc / view.c
1 /* $Id: view.c,v 1.8 2000/03/05 19:17:40 ea Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/cc/view.c
6 * PURPOSE: Cache manager
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <ddk/ntifs.h>
16 #include <internal/mm.h>
17 #include <internal/cc.h>
18
19 #define NDEBUG
20 #include <internal/debug.h>
21
22 /* FUNCTIONS *****************************************************************/
23
24 NTSTATUS STDCALL CcFlushCachePage(PCACHE_SEGMENT CacheSeg)
25 /*
26 * FUNCTION: Asks the FSD to flush the contents of the page back to disk
27 */
28 {
29 KeWaitForSingleObject(&CacheSeg->Lock,
30 Executive,
31 KernelMode,
32 FALSE,
33 NULL);
34 /* Build an IRP_MJ_WRITE and send it to the filesystem */
35 KeSetEvent(&CacheSeg->Lock, IO_NO_INCREMENT, 0);
36 return(STATUS_NOT_IMPLEMENTED);
37 }
38
39 NTSTATUS STDCALL CcReleaseCachePage(PBCB Bcb,
40 PCACHE_SEGMENT CacheSeg,
41 BOOLEAN Valid)
42 {
43 DPRINT("CcReleaseCachePage(Bcb %x, CacheSeg %x, Valid %d)\n",
44 Bcb, CacheSeg, Valid);
45
46 CacheSeg->ReferenceCount--;
47 CacheSeg->Valid = Valid;
48 KeSetEvent(&CacheSeg->Lock, IO_NO_INCREMENT, FALSE);
49
50 DPRINT("CcReleaseCachePage() finished\n");
51
52 return(STATUS_SUCCESS);
53 }
54
55 NTSTATUS STDCALL CcRequestCachePage(PBCB Bcb,
56 ULONG FileOffset,
57 PVOID* BaseAddress,
58 PBOOLEAN UptoDate,
59 PCACHE_SEGMENT* CacheSeg)
60 {
61 KIRQL oldirql;
62 PLIST_ENTRY current_entry;
63 PCACHE_SEGMENT current;
64
65 DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
66 "UptoDate %x, CacheSeg %x)\n", Bcb, FileOffset, BaseAddress,
67 UptoDate, CacheSeg);
68
69 KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
70
71 current_entry = Bcb->CacheSegmentListHead.Flink;
72 while (current_entry != &Bcb->CacheSegmentListHead)
73 {
74 current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
75 if (current->FileOffset == PAGE_ROUND_DOWN(FileOffset))
76 {
77 DPRINT("Found existing segment at %x\n", current);
78 current->ReferenceCount++;
79 KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
80 DPRINT("Waiting for segment\n");
81 KeWaitForSingleObject(&current->Lock,
82 Executive,
83 KernelMode,
84 FALSE,
85 NULL);
86 *UptoDate = current->Valid;
87 *BaseAddress = current->BaseAddress;
88 *CacheSeg = current;
89 DPRINT("Returning %x (UptoDate %d)\n", current, current->Valid);
90 return(STATUS_SUCCESS);
91 }
92 current_entry = current_entry->Flink;
93 }
94
95 DPRINT("Creating new segment\n");
96
97 KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
98
99 current = ExAllocatePool(NonPagedPool, sizeof(CACHE_SEGMENT));
100 current->BaseAddress = NULL;
101 MmCreateMemoryArea(KernelMode,
102 NULL,
103 MEMORY_AREA_CACHE_SEGMENT,
104 &current->BaseAddress,
105 CACHE_SEGMENT_SIZE,
106 PAGE_READWRITE,
107 (PMEMORY_AREA*)&current->MemoryArea);
108 CHECKPOINT;
109 current->Valid = FALSE;
110 current->FileOffset = PAGE_ROUND_DOWN(FileOffset);
111 current->Bcb = Bcb;
112 CHECKPOINT;
113 KeInitializeEvent(&current->Lock, SynchronizationEvent, FALSE);
114 current->ReferenceCount = 1;
115 CHECKPOINT;
116 InsertTailList(&Bcb->CacheSegmentListHead, &current->ListEntry);
117 CHECKPOINT;
118 *UptoDate = current->Valid;
119 *BaseAddress = current->BaseAddress;
120 *CacheSeg = current;
121 CHECKPOINT;
122 MmSetPage(NULL,
123 current->BaseAddress,
124 PAGE_READWRITE,
125 (ULONG)MmAllocPage());
126
127
128 DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress);
129
130 return(STATUS_SUCCESS);
131 }
132
133 NTSTATUS STDCALL CcFreeCacheSegment(PFILE_OBJECT FileObject,
134 PBCB Bcb,
135 PCACHE_SEGMENT CacheSeg)
136 {
137 MmFreeMemoryArea(NULL,
138 CacheSeg->BaseAddress,
139 CACHE_SEGMENT_SIZE,
140 TRUE);
141 ExFreePool(CacheSeg);
142 return(STATUS_SUCCESS);
143 }
144
145 NTSTATUS STDCALL CcReleaseFileCache(PFILE_OBJECT FileObject,
146 PBCB Bcb)
147 {
148 PLIST_ENTRY current_entry;
149 PCACHE_SEGMENT current;
150
151 DPRINT("CcReleaseFileCache(FileObject %x, Bcb %x)\n",
152 FileObject, Bcb);
153
154 current_entry = Bcb->CacheSegmentListHead.Flink;
155 while (current_entry != (&Bcb->CacheSegmentListHead))
156 {
157 current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
158 current_entry = current_entry->Flink;
159 CcFreeCacheSegment(FileObject,
160 Bcb,
161 current);
162 }
163
164 ExFreePool(Bcb);
165
166 DPRINT("CcReleaseFileCache() finished\n");
167
168 return(STATUS_SUCCESS);
169 }
170
171 NTSTATUS STDCALL CcInitializeFileCache(PFILE_OBJECT FileObject,
172 PBCB* Bcb)
173 {
174 DPRINT("CcInitializeFileCache(FileObject %x)\n",FileObject);
175
176 (*Bcb) = ExAllocatePool(NonPagedPool, sizeof(BCB));
177 if ((*Bcb) == NULL)
178 {
179 return(STATUS_UNSUCCESSFUL);
180 }
181
182 (*Bcb)->FileObject = FileObject;
183 InitializeListHead(&(*Bcb)->CacheSegmentListHead);
184 KeInitializeSpinLock(&(*Bcb)->BcbLock);
185
186 DPRINT("Finished CcInitializeFileCache() = %x\n", *Bcb);
187
188 return(STATUS_SUCCESS);
189 }
190
191
192 /**********************************************************************
193 * NAME INTERNAL
194 * CcMdlReadCompleteDev@8
195 *
196 * DESCRIPTION
197 *
198 * ARGUMENTS
199 * MdlChain
200 * DeviceObject
201 *
202 * RETURN VALUE
203 * None.
204 *
205 * NOTE
206 * Used by CcMdlReadComplete@8 and FsRtl
207 */
208 VOID
209 STDCALL
210 CcMdlReadCompleteDev (
211 IN PMDL MdlChain,
212 IN PDEVICE_OBJECT DeviceObject
213 )
214 {
215 UNIMPLEMENTED;
216 }
217
218
219 /**********************************************************************
220 * NAME EXPORTED
221 * CcMdlReadComplete@8
222 *
223 * DESCRIPTION
224 *
225 * ARGUMENTS
226 *
227 * RETURN VALUE
228 * None.
229 *
230 * NOTE
231 * From Bo Branten's ntifs.h v13.
232 */
233 VOID
234 STDCALL
235 CcMdlReadComplete (
236 IN PFILE_OBJECT FileObject,
237 IN PMDL MdlChain
238 )
239 {
240 PDEVICE_OBJECT DeviceObject = NULL;
241
242 DeviceObject = IoGetRelatedDeviceObject (FileObject);
243 /* FIXME: try fast I/O first */
244 CcMdlReadCompleteDev (
245 MdlChain,
246 DeviceObject
247 );
248 }
249
250
251 /* EOF */