[NTOSKRNL] Implement per-file dirty page threshold.

Namely, implement CcSetDirtyPageThreshold() and add support for it
in CcCanIWrite().

Also added my name in the headers of the few files I touched tonight.

CORE-14235
This commit is contained in:
Pierre Schweitzer 2018-01-23 23:23:32 +01:00
parent 389f683026
commit f93acd806a
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
4 changed files with 69 additions and 4 deletions

View file

@ -5,6 +5,7 @@
* PURPOSE: Cache manager
*
* PROGRAMMERS: David Welch (welch@cwcom.net)
* Pierre Schweitzer (pierre@reactos.org)
*/
/* INCLUDES *****************************************************************/
@ -140,7 +141,7 @@ CcSetBcbOwnerPointer (
}
/*
* @unimplemented
* @implemented
*/
VOID
NTAPI
@ -149,10 +150,23 @@ CcSetDirtyPageThreshold (
IN ULONG DirtyPageThreshold
)
{
PFSRTL_COMMON_FCB_HEADER Fcb;
PROS_SHARED_CACHE_MAP SharedCacheMap;
CCTRACE(CC_API_DEBUG, "FileObject=%p DirtyPageThreshold=%lu\n",
FileObject, DirtyPageThreshold);
UNIMPLEMENTED;
SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
if (SharedCacheMap != NULL)
{
SharedCacheMap->DirtyPageThreshold = DirtyPageThreshold;
}
Fcb = FileObject->FsContext;
if (!BooleanFlagOn(Fcb->Flags, FSRTL_FLAG_LIMIT_MODIFIED_PAGES))
{
SetFlag(Fcb->Flags, FSRTL_FLAG_LIMIT_MODIFIED_PAGES);
}
}
/*

View file

@ -4,7 +4,8 @@
* FILE: ntoskrnl/cc/copy.c
* PURPOSE: Implements cache managers copy interface
*
* PROGRAMMERS:
* PROGRAMMERS: Some people?
* Pierre Schweitzer (pierre@reactos.org)
*/
/* INCLUDES ******************************************************************/
@ -375,6 +376,12 @@ CcCanIWrite (
IN BOOLEAN Wait,
IN BOOLEAN Retrying)
{
KIRQL OldIrql;
ULONG DirtyPages;
PLIST_ENTRY ListEntry;
PFSRTL_COMMON_FCB_HEADER Fcb;
PROS_SHARED_CACHE_MAP SharedCacheMap;
CCTRACE(CC_API_DEBUG, "FileObject=%p BytesToWrite=%lu Wait=%d Retrying=%d\n",
FileObject, BytesToWrite, Wait, Retrying);
@ -392,7 +399,48 @@ CcCanIWrite (
return FALSE;
}
/* FIXME: Handle per-file threshold */
/* Is there a limit per file object? */
Fcb = FileObject->FsContext;
SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
if (!BooleanFlagOn(Fcb->Flags, FSRTL_FLAG_LIMIT_MODIFIED_PAGES) ||
SharedCacheMap->DirtyPageThreshold == 0)
{
/* Nope, so that's fine, allow write operation */
return TRUE;
}
/* There's a limit, start counting dirty pages */
DirtyPages = 0;
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &OldIrql);
for (ListEntry = SharedCacheMap->CacheMapVacbListHead.Flink;
ListEntry != &SharedCacheMap->CacheMapVacbListHead;
ListEntry = ListEntry->Flink)
{
PROS_VACB Vacb;
Vacb = CONTAINING_RECORD(ListEntry,
ROS_VACB,
CacheMapVacbListEntry);
if (Vacb->Dirty)
{
DirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
}
}
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, OldIrql);
/* Is dirty page count above local threshold? */
if (DirtyPages > SharedCacheMap->DirtyPageThreshold)
{
return FALSE;
}
/* We cannot write if dirty pages count will bring use above
* XXX: Might not be accurate
*/
if (DirtyPages + (BytesToWrite / PAGE_SIZE) > SharedCacheMap->DirtyPageThreshold)
{
return FALSE;
}
return TRUE;
}

View file

@ -5,6 +5,7 @@
* PURPOSE: Cache manager
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Pierre Schweitzer (pierre@reactos.org)
*/
/* NOTES **********************************************************************
@ -1333,6 +1334,7 @@ CcRosInitializeFileCache (
SharedCacheMap->SectionSize = FileSizes->AllocationSize;
SharedCacheMap->FileSize = FileSizes->FileSize;
SharedCacheMap->PinAccess = PinAccess;
SharedCacheMap->DirtyPageThreshold = 0;
KeInitializeSpinLock(&SharedCacheMap->CacheMapLock);
InitializeListHead(&SharedCacheMap->CacheMapVacbListHead);
FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap;

View file

@ -159,6 +159,7 @@ typedef struct _ROS_SHARED_CACHE_MAP
PVOID LazyWriteContext;
KSPIN_LOCK CacheMapLock;
ULONG OpenCount;
ULONG DirtyPageThreshold;
#if DBG
BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
#endif