Implemented CcZeroData.

svn path=/trunk/; revision=3032
This commit is contained in:
Hartmut Birr 2002-06-10 21:11:56 +00:00
parent c4d4559cce
commit 8393c73b3b
5 changed files with 221 additions and 5 deletions

View file

@ -1,4 +1,4 @@
/* $Id: copy.c,v 1.5 2002/06/04 15:26:55 dwelch Exp $
/* $Id: copy.c,v 1.6 2002/06/10 21:11:56 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -26,8 +26,29 @@
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
static PHYSICAL_ADDRESS CcZeroPage = (PHYSICAL_ADDRESS)0LL;
/* FUNCTIONS *****************************************************************/
VOID
InitCacheZeroPage(VOID)
{
NTSTATUS Status;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &CcZeroPage);
if (!NT_SUCCESS(Status))
{
DbgPrint("Can't allocate CcZeroPage.\n");
KeBugCheck(0);
}
Status = MiZeroPage(CcZeroPage);
if (!NT_SUCCESS(Status))
{
DbgPrint("Can't zero out CcZeroPage.\n");
KeBugCheck(0);
}
}
NTSTATUS
ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
PVOID Buffer)
@ -410,4 +431,195 @@ CcCopyWrite (
return TRUE;
}
BOOLEAN STDCALL
CcZeroData (
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER StartOffset,
IN PLARGE_INTEGER EndOffset,
IN BOOLEAN Wait
)
{
NTSTATUS Status;
LARGE_INTEGER WriteOffset;
ULONG Length;
PMDL Mdl;
ULONG i;
IO_STATUS_BLOCK Iosb;
DPRINT("CcZeroData(FileObject %x, StartOffset %I64x, EndOffset %I64x, Wait %d\n",
FileObject, StartOffset->QuadPart, EndOffset->QuadPart, Wait);
Length = EndOffset->u.LowPart - StartOffset->u.LowPart;
// FIXME: NT uses the shared chache map field for cached/non cached detection
if (((PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext)->Bcb == NULL)
{
// File is not cached
CHECKPOINT;
WriteOffset.QuadPart = StartOffset->QuadPart;
while (Length > 0)
{
if (Length + WriteOffset.u.LowPart % PAGESIZE > 262144)
{
Mdl = MmCreateMdl(NULL, (PVOID)WriteOffset.u.LowPart, 262144 - WriteOffset.u.LowPart % PAGESIZE);
WriteOffset.QuadPart += (262144 - WriteOffset.u.LowPart % PAGESIZE);
Length -= (262144 - WriteOffset.u.LowPart % PAGESIZE);
}
else
{
Mdl = MmCreateMdl(NULL, (PVOID)WriteOffset.u.LowPart, Length - WriteOffset.u.LowPart % PAGESIZE);
WriteOffset.QuadPart += (Length - WriteOffset.u.LowPart % PAGESIZE);
Length = 0;
}
if (Mdl == NULL)
{
return FALSE;
}
Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
for (i = 0; i < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); i++)
{
((PULONG)(Mdl + 1))[i] = CcZeroPage.u.LowPart;
}
Status = IoPageWrite(FileObject, Mdl, StartOffset, &Iosb, TRUE);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
}
}
else
{
// File is cached
KIRQL oldirql;
PBCB Bcb;
PLIST_ENTRY current_entry;
PCACHE_SEGMENT CacheSeg, current, previous;
ULONG TempLength;
ULONG Start;
ULONG count;
ULONG size;
PHYSICAL_ADDRESS page;
CHECKPOINT;
Start = StartOffset->u.LowPart;
Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
if (Wait)
{
// testing, if the requested datas are available
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
{
CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
if (!CacheSeg->Valid)
{
if ((Start >= CacheSeg->FileOffset && Start < CacheSeg->FileOffset + Bcb->CacheSegmentSize)
|| (Start + Length > CacheSeg->FileOffset &&
Start + Length <= CacheSeg->FileOffset + Bcb->CacheSegmentSize))
{
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
// datas not available
return FALSE;
}
}
current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
}
while (Length > 0)
{
WriteOffset.QuadPart = ROUND_DOWN(Start, Bcb->CacheSegmentSize);
if (Start % Bcb->CacheSegmentSize + Length > 262144)
{
Mdl = MmCreateMdl(NULL, NULL, 262144);
if (Mdl == NULL)
{
return FALSE;
}
Status = CcRosGetCacheSegmentChain (Bcb, ROUND_DOWN(Start, Bcb->CacheSegmentSize),
262144, &CacheSeg);
if (!NT_SUCCESS(Status))
{
ExFreePool(Mdl);
return FALSE;
}
}
else
{
Mdl = MmCreateMdl(NULL, (PVOID)ROUND_DOWN(Start, Bcb->CacheSegmentSize),
ROUND_UP(Start % Bcb->CacheSegmentSize + Length, Bcb->CacheSegmentSize));
if (Mdl == NULL)
{
return FALSE;
}
Status = CcRosGetCacheSegmentChain (Bcb, ROUND_DOWN(Start, Bcb->CacheSegmentSize),
min(ROUND_UP(Start % Bcb->CacheSegmentSize
+ Length, Bcb->CacheSegmentSize),
Bcb->AllocationSize.u.LowPart
- ROUND_DOWN(Start, Bcb->CacheSegmentSize)),
&CacheSeg);
if (!NT_SUCCESS(Status))
{
ExFreePool(Mdl);
return FALSE;
}
}
Mdl->MdlFlags |= (MDL_PAGES_LOCKED|MDL_IO_PAGE_READ);
current = CacheSeg;
count = 0;
while (current != NULL)
{
if (Start % Bcb->CacheSegmentSize ||
Start % Bcb->CacheSegmentSize + Length < Bcb->CacheSegmentSize)
{
if (!current->Valid)
{
// Segment lesen
Status = ReadCacheSegment(current);
if (!NT_SUCCESS(Status))
{
DPRINT1("ReadCacheSegment failed, status %x\n", Status);
}
}
TempLength = min (Length, Bcb->CacheSegmentSize - Start % Bcb->CacheSegmentSize);
memset (current->BaseAddress + Start % Bcb->CacheSegmentSize, 0, TempLength);
}
else
{
TempLength = Bcb->CacheSegmentSize;
memset (current->BaseAddress, 0, Bcb->CacheSegmentSize);
}
Start += TempLength;
Length -= TempLength;
size = ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG));
for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE) && count < size; i++)
{
page = MmGetPhysicalAddressForProcess(NULL, current->BaseAddress + (i * PAGESIZE));
((PULONG)(Mdl + 1))[count++] = page.u.LowPart;
}
current = current->NextInChain;
}
// Write the Segment
Status = IoPageWrite(FileObject, Mdl, &WriteOffset, &Iosb, TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("IoPageWrite failed, status %x\n", Status);
}
current = CacheSeg;
while (current != NULL)
{
previous = current;
current = current->NextInChain;
CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
}
}
}
return TRUE;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: view.c,v 1.42 2002/06/04 15:26:55 dwelch Exp $
/* $Id: view.c,v 1.43 2002/06/10 21:11:56 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -576,6 +576,7 @@ CcInitView(VOID)
InitializeListHead(&CacheSegmentLRUListHead);
ExInitializeFastMutex(&ViewLock);
MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache);
InitCacheZeroPage();
}
/* EOF */

View file

@ -1,6 +1,6 @@
#ifndef __INCLUDE_INTERNAL_CC_H
#define __INCLUDE_INTERNAL_CC_H
/* $Id: cc.h,v 1.10 2002/01/26 21:21:02 dwelch Exp $ */
/* $Id: cc.h,v 1.11 2002/06/10 21:11:56 hbirr Exp $ */
#include <ddk/ntifs.h>
typedef struct _BCB
@ -76,4 +76,5 @@ CcRosGetCacheSegmentChain(PBCB Bcb,
ULONG FileOffset,
ULONG Length,
PCACHE_SEGMENT* CacheSeg);
VOID InitCacheZeroPage(VOID);
#endif

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.def,v 1.134 2002/06/05 16:53:36 ekohl Exp $
; $Id: ntoskrnl.def,v 1.135 2002/06/10 21:11:56 hbirr Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
@ -16,6 +16,7 @@ CcMdlReadComplete@8
CcSetDirtyPinnedData@8
CcSetFileSizes@8
CcUnpinData@4
CcZeroData@16
DbgBreakPoint@0
DbgBreakPointWithStatus@4
;DbgLoadImageSymbols@12

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.edf,v 1.120 2002/06/05 16:53:36 ekohl Exp $
; $Id: ntoskrnl.edf,v 1.121 2002/06/10 21:11:56 hbirr Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
@ -16,6 +16,7 @@ CcMapData=CcMapData@24
CcSetDirtyPinnedData=CcSetDirtyPinnedData@8
CcUnpinData=CcUnpinData@4
CcSetFileSizes=CcSetFileSizes@8
CcZeroData=CcZeroData@16
DbgBreakPoint=DbgBreakPoint@0
DbgBreakPointWithStatus=DbgBreakPointWithStatus@4
;DbgLoadImageSymbols=DbgLoadImageSymbols@12