2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/cc/view.c
5 * PURPOSE: Cache manager
6 * PROGRAMMER: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
14 #include <ddk/ntifs.h>
15 #include <internal/mm.h>
18 #include <internal/debug.h>
20 /* FUNCTIONS *****************************************************************/
22 NTSTATUS
CcFlushCachePage(PCACHE_SEGMENT CacheSeg
)
24 * FUNCTION: Asks the FSD to flush the contents of the page back to disk
27 KeWaitForSingleObject(&CacheSeg
->Lock
,
32 /* Build an IRP_MJ_WRITE and send it to the filesystem */
33 KeSetEvent(&CacheSeg
->Lock
, IO_NO_INCREMENT
, 0);
34 return(STATUS_NOT_IMPLEMENTED
);
37 NTSTATUS
CcReleaseCachePage(PBCB Bcb
,
38 PCACHE_SEGMENT CacheSeg
,
41 DPRINT("CcReleaseCachePage(Bcb %x, CacheSeg %x, Valid %d)\n",
42 Bcb
, CacheSeg
, Valid
);
44 CacheSeg
->ReferenceCount
--;
45 CacheSeg
->Valid
= Valid
;
46 KeSetEvent(&CacheSeg
->Lock
, IO_NO_INCREMENT
, FALSE
);
48 DPRINT("CcReleaseCachePage() finished\n");
50 return(STATUS_SUCCESS
);
53 NTSTATUS
CcRequestCachePage(PBCB Bcb
,
57 PCACHE_SEGMENT
* CacheSeg
)
60 PLIST_ENTRY current_entry
;
61 PCACHE_SEGMENT current
;
63 DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
64 "UptoDate %x, CacheSeg %x)\n", Bcb
, FileOffset
, BaseAddress
,
67 KeAcquireSpinLock(&Bcb
->BcbLock
, &oldirql
);
69 current_entry
= Bcb
->CacheSegmentListHead
.Flink
;
70 while (current_entry
!= &Bcb
->CacheSegmentListHead
)
72 current
= CONTAINING_RECORD(current_entry
, CACHE_SEGMENT
, ListEntry
);
73 if (current
->FileOffset
== PAGE_ROUND_DOWN(FileOffset
))
75 DPRINT("Found existing segment at %x\n", current
);
76 current
->ReferenceCount
++;
77 KeReleaseSpinLock(&Bcb
->BcbLock
, oldirql
);
78 DPRINT("Waiting for segment\n");
79 KeWaitForSingleObject(¤t
->Lock
,
84 *UptoDate
= current
->Valid
;
85 *BaseAddress
= current
->BaseAddress
;
87 DPRINT("Returning %x (UptoDate %d)\n", current
, current
->Valid
);
88 return(STATUS_SUCCESS
);
90 current_entry
= current_entry
->Flink
;
93 DPRINT("Creating new segment\n");
95 KeReleaseSpinLock(&Bcb
->BcbLock
, oldirql
);
97 current
= ExAllocatePool(NonPagedPool
, sizeof(CACHE_SEGMENT
));
98 current
->BaseAddress
= NULL
;
99 MmCreateMemoryArea(KernelMode
,
101 MEMORY_AREA_CACHE_SEGMENT
,
102 ¤t
->BaseAddress
,
105 (PMEMORY_AREA
*)¤t
->MemoryArea
);
107 current
->Valid
= FALSE
;
108 current
->FileOffset
= PAGE_ROUND_DOWN(FileOffset
);
111 KeInitializeEvent(¤t
->Lock
, SynchronizationEvent
, FALSE
);
112 current
->ReferenceCount
= 1;
114 InsertTailList(&Bcb
->CacheSegmentListHead
, ¤t
->ListEntry
);
116 *UptoDate
= current
->Valid
;
117 *BaseAddress
= current
->BaseAddress
;
121 current
->BaseAddress
,
123 (ULONG
)MmAllocPage());
126 DPRINT("Returning %x (BaseAddress %x)\n", current
, *BaseAddress
);
128 return(STATUS_SUCCESS
);
131 NTSTATUS
CcFreeCacheSegment(PFILE_OBJECT FileObject
,
133 PCACHE_SEGMENT CacheSeg
)
135 MmFreeMemoryArea(NULL
,
136 CacheSeg
->BaseAddress
,
139 ExFreePool(CacheSeg
);
140 return(STATUS_SUCCESS
);
143 NTSTATUS
CcReleaseFileCache(PFILE_OBJECT FileObject
,
146 PLIST_ENTRY current_entry
;
147 PCACHE_SEGMENT current
;
149 DPRINT("CcReleaseFileCache(FileObject %x, Bcb %x)\n",
152 current_entry
= Bcb
->CacheSegmentListHead
.Flink
;
153 while (current_entry
!= (&Bcb
->CacheSegmentListHead
))
155 current
= CONTAINING_RECORD(current_entry
, CACHE_SEGMENT
, ListEntry
);
156 current_entry
= current_entry
->Flink
;
157 CcFreeCacheSegment(FileObject
,
164 DPRINT("CcReleaseFileCache() finished\n");
166 return(STATUS_SUCCESS
);
169 NTSTATUS
CcInitializeFileCache(PFILE_OBJECT FileObject
,
172 DPRINT("CcInitializeFileCache(FileObject %x)\n",FileObject
);
174 (*Bcb
) = ExAllocatePool(NonPagedPool
, sizeof(BCB
));
177 return(STATUS_UNSUCCESSFUL
);
180 (*Bcb
)->FileObject
= FileObject
;
181 InitializeListHead(&(*Bcb
)->CacheSegmentListHead
);
182 KeInitializeSpinLock(&(*Bcb
)->BcbLock
);
184 DPRINT("Finished CcInitializeFileCache() = %x\n", *Bcb
);
186 return(STATUS_SUCCESS
);