1 /* $Id: view.c,v 1.8 2000/03/05 19:17:40 ea Exp $
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)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <ddk/ntifs.h>
16 #include <internal/mm.h>
17 #include <internal/cc.h>
20 #include <internal/debug.h>
22 /* FUNCTIONS *****************************************************************/
24 NTSTATUS STDCALL
CcFlushCachePage(PCACHE_SEGMENT CacheSeg
)
26 * FUNCTION: Asks the FSD to flush the contents of the page back to disk
29 KeWaitForSingleObject(&CacheSeg
->Lock
,
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
);
39 NTSTATUS STDCALL
CcReleaseCachePage(PBCB Bcb
,
40 PCACHE_SEGMENT CacheSeg
,
43 DPRINT("CcReleaseCachePage(Bcb %x, CacheSeg %x, Valid %d)\n",
44 Bcb
, CacheSeg
, Valid
);
46 CacheSeg
->ReferenceCount
--;
47 CacheSeg
->Valid
= Valid
;
48 KeSetEvent(&CacheSeg
->Lock
, IO_NO_INCREMENT
, FALSE
);
50 DPRINT("CcReleaseCachePage() finished\n");
52 return(STATUS_SUCCESS
);
55 NTSTATUS STDCALL
CcRequestCachePage(PBCB Bcb
,
59 PCACHE_SEGMENT
* CacheSeg
)
62 PLIST_ENTRY current_entry
;
63 PCACHE_SEGMENT current
;
65 DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
66 "UptoDate %x, CacheSeg %x)\n", Bcb
, FileOffset
, BaseAddress
,
69 KeAcquireSpinLock(&Bcb
->BcbLock
, &oldirql
);
71 current_entry
= Bcb
->CacheSegmentListHead
.Flink
;
72 while (current_entry
!= &Bcb
->CacheSegmentListHead
)
74 current
= CONTAINING_RECORD(current_entry
, CACHE_SEGMENT
, ListEntry
);
75 if (current
->FileOffset
== PAGE_ROUND_DOWN(FileOffset
))
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(¤t
->Lock
,
86 *UptoDate
= current
->Valid
;
87 *BaseAddress
= current
->BaseAddress
;
89 DPRINT("Returning %x (UptoDate %d)\n", current
, current
->Valid
);
90 return(STATUS_SUCCESS
);
92 current_entry
= current_entry
->Flink
;
95 DPRINT("Creating new segment\n");
97 KeReleaseSpinLock(&Bcb
->BcbLock
, oldirql
);
99 current
= ExAllocatePool(NonPagedPool
, sizeof(CACHE_SEGMENT
));
100 current
->BaseAddress
= NULL
;
101 MmCreateMemoryArea(KernelMode
,
103 MEMORY_AREA_CACHE_SEGMENT
,
104 ¤t
->BaseAddress
,
107 (PMEMORY_AREA
*)¤t
->MemoryArea
);
109 current
->Valid
= FALSE
;
110 current
->FileOffset
= PAGE_ROUND_DOWN(FileOffset
);
113 KeInitializeEvent(¤t
->Lock
, SynchronizationEvent
, FALSE
);
114 current
->ReferenceCount
= 1;
116 InsertTailList(&Bcb
->CacheSegmentListHead
, ¤t
->ListEntry
);
118 *UptoDate
= current
->Valid
;
119 *BaseAddress
= current
->BaseAddress
;
123 current
->BaseAddress
,
125 (ULONG
)MmAllocPage());
128 DPRINT("Returning %x (BaseAddress %x)\n", current
, *BaseAddress
);
130 return(STATUS_SUCCESS
);
133 NTSTATUS STDCALL
CcFreeCacheSegment(PFILE_OBJECT FileObject
,
135 PCACHE_SEGMENT CacheSeg
)
137 MmFreeMemoryArea(NULL
,
138 CacheSeg
->BaseAddress
,
141 ExFreePool(CacheSeg
);
142 return(STATUS_SUCCESS
);
145 NTSTATUS STDCALL
CcReleaseFileCache(PFILE_OBJECT FileObject
,
148 PLIST_ENTRY current_entry
;
149 PCACHE_SEGMENT current
;
151 DPRINT("CcReleaseFileCache(FileObject %x, Bcb %x)\n",
154 current_entry
= Bcb
->CacheSegmentListHead
.Flink
;
155 while (current_entry
!= (&Bcb
->CacheSegmentListHead
))
157 current
= CONTAINING_RECORD(current_entry
, CACHE_SEGMENT
, ListEntry
);
158 current_entry
= current_entry
->Flink
;
159 CcFreeCacheSegment(FileObject
,
166 DPRINT("CcReleaseFileCache() finished\n");
168 return(STATUS_SUCCESS
);
171 NTSTATUS STDCALL
CcInitializeFileCache(PFILE_OBJECT FileObject
,
174 DPRINT("CcInitializeFileCache(FileObject %x)\n",FileObject
);
176 (*Bcb
) = ExAllocatePool(NonPagedPool
, sizeof(BCB
));
179 return(STATUS_UNSUCCESSFUL
);
182 (*Bcb
)->FileObject
= FileObject
;
183 InitializeListHead(&(*Bcb
)->CacheSegmentListHead
);
184 KeInitializeSpinLock(&(*Bcb
)->BcbLock
);
186 DPRINT("Finished CcInitializeFileCache() = %x\n", *Bcb
);
188 return(STATUS_SUCCESS
);
192 /**********************************************************************
194 * CcMdlReadCompleteDev@8
206 * Used by CcMdlReadComplete@8 and FsRtl
210 CcMdlReadCompleteDev (
212 IN PDEVICE_OBJECT DeviceObject
219 /**********************************************************************
221 * CcMdlReadComplete@8
231 * From Bo Branten's ntifs.h v13.
236 IN PFILE_OBJECT FileObject
,
240 PDEVICE_OBJECT DeviceObject
= NULL
;
242 DeviceObject
= IoGetRelatedDeviceObject (FileObject
);
243 /* FIXME: try fast I/O first */
244 CcMdlReadCompleteDev (