2000-02-26 22:41:35 +00:00
|
|
|
/* $Id: view.c,v 1.7 2000/02/26 22:41:34 ea Exp $
|
|
|
|
*
|
1998-12-21 15:48:21 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: ntoskrnl/cc/view.c
|
|
|
|
* PURPOSE: Cache manager
|
|
|
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* Created 22/05/98
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
|
|
|
#include <ddk/ntddk.h>
|
|
|
|
#include <ddk/ntifs.h>
|
1999-04-05 15:04:46 +00:00
|
|
|
#include <internal/mm.h>
|
1998-12-21 15:48:21 +00:00
|
|
|
|
1999-05-29 00:15:17 +00:00
|
|
|
#define NDEBUG
|
1998-12-21 15:48:21 +00:00
|
|
|
#include <internal/debug.h>
|
|
|
|
|
1999-05-29 00:15:17 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
1999-01-16 21:03:00 +00:00
|
|
|
|
2000-02-26 22:41:35 +00:00
|
|
|
NTSTATUS STDCALL CcFlushCachePage(PCACHE_SEGMENT CacheSeg)
|
1999-05-29 00:15:17 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Asks the FSD to flush the contents of the page back to disk
|
|
|
|
*/
|
1998-12-21 15:48:21 +00:00
|
|
|
{
|
1999-05-29 00:15:17 +00:00
|
|
|
KeWaitForSingleObject(&CacheSeg->Lock,
|
|
|
|
Executive,
|
|
|
|
KernelMode,
|
|
|
|
FALSE,
|
|
|
|
NULL);
|
|
|
|
/* Build an IRP_MJ_WRITE and send it to the filesystem */
|
|
|
|
KeSetEvent(&CacheSeg->Lock, IO_NO_INCREMENT, 0);
|
|
|
|
return(STATUS_NOT_IMPLEMENTED);
|
|
|
|
}
|
1998-12-21 15:48:21 +00:00
|
|
|
|
2000-02-26 22:41:35 +00:00
|
|
|
NTSTATUS STDCALL CcReleaseCachePage(PBCB Bcb,
|
1999-05-29 00:15:17 +00:00
|
|
|
PCACHE_SEGMENT CacheSeg,
|
|
|
|
BOOLEAN Valid)
|
|
|
|
{
|
|
|
|
DPRINT("CcReleaseCachePage(Bcb %x, CacheSeg %x, Valid %d)\n",
|
|
|
|
Bcb, CacheSeg, Valid);
|
|
|
|
|
|
|
|
CacheSeg->ReferenceCount--;
|
|
|
|
CacheSeg->Valid = Valid;
|
|
|
|
KeSetEvent(&CacheSeg->Lock, IO_NO_INCREMENT, FALSE);
|
|
|
|
|
|
|
|
DPRINT("CcReleaseCachePage() finished\n");
|
|
|
|
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
1998-12-21 15:48:21 +00:00
|
|
|
|
2000-02-26 22:41:35 +00:00
|
|
|
NTSTATUS STDCALL CcRequestCachePage(PBCB Bcb,
|
1999-02-01 20:58:37 +00:00
|
|
|
ULONG FileOffset,
|
|
|
|
PVOID* BaseAddress,
|
1999-05-29 00:15:17 +00:00
|
|
|
PBOOLEAN UptoDate,
|
|
|
|
PCACHE_SEGMENT* CacheSeg)
|
1998-12-21 15:48:21 +00:00
|
|
|
{
|
1999-02-01 20:58:37 +00:00
|
|
|
KIRQL oldirql;
|
1999-01-16 21:03:00 +00:00
|
|
|
PLIST_ENTRY current_entry;
|
|
|
|
PCACHE_SEGMENT current;
|
1999-04-05 15:04:46 +00:00
|
|
|
|
1999-05-29 00:15:17 +00:00
|
|
|
DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
|
|
|
|
"UptoDate %x, CacheSeg %x)\n", Bcb, FileOffset, BaseAddress,
|
|
|
|
UptoDate, CacheSeg);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-02-01 20:58:37 +00:00
|
|
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-02-01 20:58:37 +00:00
|
|
|
current_entry = Bcb->CacheSegmentListHead.Flink;
|
|
|
|
while (current_entry != &Bcb->CacheSegmentListHead)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-04-05 15:04:46 +00:00
|
|
|
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
|
|
|
|
if (current->FileOffset == PAGE_ROUND_DOWN(FileOffset))
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-05-29 00:15:17 +00:00
|
|
|
DPRINT("Found existing segment at %x\n", current);
|
1999-04-05 15:04:46 +00:00
|
|
|
current->ReferenceCount++;
|
1999-02-01 20:58:37 +00:00
|
|
|
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
1999-05-29 00:15:17 +00:00
|
|
|
DPRINT("Waiting for segment\n");
|
1999-04-05 15:04:46 +00:00
|
|
|
KeWaitForSingleObject(¤t->Lock,
|
|
|
|
Executive,
|
|
|
|
KernelMode,
|
|
|
|
FALSE,
|
|
|
|
NULL);
|
|
|
|
*UptoDate = current->Valid;
|
1999-05-29 00:15:17 +00:00
|
|
|
*BaseAddress = current->BaseAddress;
|
|
|
|
*CacheSeg = current;
|
|
|
|
DPRINT("Returning %x (UptoDate %d)\n", current, current->Valid);
|
1999-02-01 20:58:37 +00:00
|
|
|
return(STATUS_SUCCESS);
|
1999-01-28 15:54:26 +00:00
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
current_entry = current_entry->Flink;
|
|
|
|
}
|
1999-04-05 15:04:46 +00:00
|
|
|
|
1999-05-29 00:15:17 +00:00
|
|
|
DPRINT("Creating new segment\n");
|
|
|
|
|
|
|
|
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
|
|
|
|
1999-04-05 15:04:46 +00:00
|
|
|
current = ExAllocatePool(NonPagedPool, sizeof(CACHE_SEGMENT));
|
|
|
|
current->BaseAddress = NULL;
|
|
|
|
MmCreateMemoryArea(KernelMode,
|
1999-05-29 00:15:17 +00:00
|
|
|
NULL,
|
1999-04-05 15:04:46 +00:00
|
|
|
MEMORY_AREA_CACHE_SEGMENT,
|
|
|
|
¤t->BaseAddress,
|
|
|
|
CACHE_SEGMENT_SIZE,
|
|
|
|
PAGE_READWRITE,
|
1999-05-29 00:15:17 +00:00
|
|
|
(PMEMORY_AREA*)¤t->MemoryArea);
|
|
|
|
CHECKPOINT;
|
1999-04-05 15:04:46 +00:00
|
|
|
current->Valid = FALSE;
|
|
|
|
current->FileOffset = PAGE_ROUND_DOWN(FileOffset);
|
1999-05-29 00:15:17 +00:00
|
|
|
current->Bcb = Bcb;
|
|
|
|
CHECKPOINT;
|
|
|
|
KeInitializeEvent(¤t->Lock, SynchronizationEvent, FALSE);
|
1999-04-05 15:04:46 +00:00
|
|
|
current->ReferenceCount = 1;
|
1999-05-29 00:15:17 +00:00
|
|
|
CHECKPOINT;
|
1999-04-05 15:04:46 +00:00
|
|
|
InsertTailList(&Bcb->CacheSegmentListHead, ¤t->ListEntry);
|
1999-05-29 00:15:17 +00:00
|
|
|
CHECKPOINT;
|
1999-04-05 15:04:46 +00:00
|
|
|
*UptoDate = current->Valid;
|
|
|
|
*BaseAddress = current->BaseAddress;
|
1999-05-29 00:15:17 +00:00
|
|
|
*CacheSeg = current;
|
|
|
|
CHECKPOINT;
|
|
|
|
MmSetPage(NULL,
|
|
|
|
current->BaseAddress,
|
|
|
|
PAGE_READWRITE,
|
|
|
|
(ULONG)MmAllocPage());
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-05-29 00:15:17 +00:00
|
|
|
|
|
|
|
DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress);
|
|
|
|
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2000-02-26 22:41:35 +00:00
|
|
|
NTSTATUS STDCALL CcFreeCacheSegment(PFILE_OBJECT FileObject,
|
1999-05-29 00:15:17 +00:00
|
|
|
PBCB Bcb,
|
|
|
|
PCACHE_SEGMENT CacheSeg)
|
|
|
|
{
|
|
|
|
MmFreeMemoryArea(NULL,
|
|
|
|
CacheSeg->BaseAddress,
|
|
|
|
CACHE_SEGMENT_SIZE,
|
|
|
|
TRUE);
|
|
|
|
ExFreePool(CacheSeg);
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2000-02-26 22:41:35 +00:00
|
|
|
NTSTATUS STDCALL CcReleaseFileCache(PFILE_OBJECT FileObject,
|
1999-05-29 00:15:17 +00:00
|
|
|
PBCB Bcb)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY current_entry;
|
|
|
|
PCACHE_SEGMENT current;
|
|
|
|
|
|
|
|
DPRINT("CcReleaseFileCache(FileObject %x, Bcb %x)\n",
|
|
|
|
FileObject, Bcb);
|
|
|
|
|
|
|
|
current_entry = Bcb->CacheSegmentListHead.Flink;
|
|
|
|
while (current_entry != (&Bcb->CacheSegmentListHead))
|
|
|
|
{
|
|
|
|
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
|
|
|
|
current_entry = current_entry->Flink;
|
|
|
|
CcFreeCacheSegment(FileObject,
|
|
|
|
Bcb,
|
|
|
|
current);
|
|
|
|
}
|
|
|
|
|
|
|
|
ExFreePool(Bcb);
|
|
|
|
|
|
|
|
DPRINT("CcReleaseFileCache() finished\n");
|
1999-04-05 15:04:46 +00:00
|
|
|
|
|
|
|
return(STATUS_SUCCESS);
|
1998-12-21 15:48:21 +00:00
|
|
|
}
|
|
|
|
|
2000-02-26 22:41:35 +00:00
|
|
|
NTSTATUS STDCALL CcInitializeFileCache(PFILE_OBJECT FileObject,
|
1999-02-01 20:58:37 +00:00
|
|
|
PBCB* Bcb)
|
1998-12-21 15:48:21 +00:00
|
|
|
{
|
1999-04-05 15:04:46 +00:00
|
|
|
DPRINT("CcInitializeFileCache(FileObject %x)\n",FileObject);
|
|
|
|
|
1999-02-01 20:58:37 +00:00
|
|
|
(*Bcb) = ExAllocatePool(NonPagedPool, sizeof(BCB));
|
|
|
|
if ((*Bcb) == NULL)
|
1999-01-28 15:54:26 +00:00
|
|
|
{
|
1999-04-05 15:04:46 +00:00
|
|
|
return(STATUS_UNSUCCESSFUL);
|
1999-01-28 15:54:26 +00:00
|
|
|
}
|
|
|
|
|
1999-02-01 20:58:37 +00:00
|
|
|
(*Bcb)->FileObject = FileObject;
|
|
|
|
InitializeListHead(&(*Bcb)->CacheSegmentListHead);
|
|
|
|
KeInitializeSpinLock(&(*Bcb)->BcbLock);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-04-05 15:04:46 +00:00
|
|
|
DPRINT("Finished CcInitializeFileCache() = %x\n", *Bcb);
|
|
|
|
|
1999-02-01 20:58:37 +00:00
|
|
|
return(STATUS_SUCCESS);
|
1998-12-21 15:48:21 +00:00
|
|
|
}
|
1999-02-01 20:58:37 +00:00
|
|
|
|
|
|
|
|
2000-02-26 22:41:35 +00:00
|
|
|
/* EOF */
|