[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 * PURPOSE: Cache manager
* *
* PROGRAMMERS: David Welch (welch@cwcom.net) * PROGRAMMERS: David Welch (welch@cwcom.net)
* Pierre Schweitzer (pierre@reactos.org)
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -140,7 +141,7 @@ CcSetBcbOwnerPointer (
} }
/* /*
* @unimplemented * @implemented
*/ */
VOID VOID
NTAPI NTAPI
@ -149,10 +150,23 @@ CcSetDirtyPageThreshold (
IN ULONG DirtyPageThreshold IN ULONG DirtyPageThreshold
) )
{ {
PFSRTL_COMMON_FCB_HEADER Fcb;
PROS_SHARED_CACHE_MAP SharedCacheMap;
CCTRACE(CC_API_DEBUG, "FileObject=%p DirtyPageThreshold=%lu\n", CCTRACE(CC_API_DEBUG, "FileObject=%p DirtyPageThreshold=%lu\n",
FileObject, DirtyPageThreshold); 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 * FILE: ntoskrnl/cc/copy.c
* PURPOSE: Implements cache managers copy interface * PURPOSE: Implements cache managers copy interface
* *
* PROGRAMMERS: * PROGRAMMERS: Some people?
* Pierre Schweitzer (pierre@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
@ -375,6 +376,12 @@ CcCanIWrite (
IN BOOLEAN Wait, IN BOOLEAN Wait,
IN BOOLEAN Retrying) 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", CCTRACE(CC_API_DEBUG, "FileObject=%p BytesToWrite=%lu Wait=%d Retrying=%d\n",
FileObject, BytesToWrite, Wait, Retrying); FileObject, BytesToWrite, Wait, Retrying);
@ -392,7 +399,48 @@ CcCanIWrite (
return FALSE; 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; return TRUE;
} }

View file

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

View file

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