[NTOSKRNL:CC] Implemented CcCanIWrite and CcDeferWrite

This commit is contained in:
Dibyamartanda Samanta 2024-11-03 18:56:31 +01:00 committed by CodingWorkshop Signing Team
parent 377ff4fb9b
commit d81565e7ec
Signed by: CodingWorkshop Signing Team
GPG Key ID: 6DC88369C82795D2

View File

@ -130,12 +130,120 @@ CcCanIWrite(
_In_ PFILE_OBJECT FileObject,
_In_ ULONG BytesToWrite,
_In_ BOOLEAN Wait,
_In_ BOOLEAN IsRetrying)
_In_ UCHAR Retrying)
{
NT_DBGBREAK("UNIMPLEMENTED\n");
}
PFSRTL_COMMON_FCB_HEADER FsContext;
PSHARED_CACHE_MAP SharedCacheMap;
DEFERRED_WRITE DeferredWrite;
KEVENT Event;
ULONG WriteSize;
ULONG Pages;
KIRQL OldIrql;
BOOLEAN IsSmallThreshold = FALSE;
/* Quick checks for immediate return */
if (FileObject->Flags & FO_WRITE_THROUGH)
return TRUE;
if (IoIsFileOriginRemote(FileObject) && Retrying < 0xFD)
return TRUE;
/* Calculate size and pages */
WriteSize = min(BytesToWrite, 0x40000);
Pages = ROUND_UP(WriteSize, PAGE_SIZE) / PAGE_SIZE;
FsContext = FileObject->FsContext;
/* Check threshold conditions */
if (Retrying >= 0xFE || (FsContext->Flags & FSRTL_FLAG_LIMIT_MODIFIED_PAGES))
{
if (Retrying != 0xFF)
{
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
}
if (FileObject->SectionObjectPointer)
{
SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
if (SharedCacheMap &&
SharedCacheMap->DirtyPageThreshold &&
SharedCacheMap->DirtyPages)
{
if (SharedCacheMap->DirtyPageThreshold < (SharedCacheMap->DirtyPages + Pages))
{
IsSmallThreshold = TRUE;
}
}
}
if (Retrying != 0xFF)
{
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
}
}
/* Check if we can write immediately */
if ((Retrying || IsListEmpty(&CcDeferredWrites)) &&
(CcDirtyPageThreshold > (CcTotalDirtyPages + Pages)))
{
if ((MmAvailablePages > MmThrottleTop && !IsSmallThreshold) ||
(MmModifiedPageListHead.Total < 1000 &&
MmAvailablePages > MmThrottleBottom &&
!IsSmallThreshold))
{
return TRUE;
}
}
if (!Wait)
return FALSE;
/* Initialize deferred write */
if (IsListEmpty(&CcDeferredWrites))
{
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
CcScheduleLazyWriteScan(TRUE);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
}
KeInitializeEvent(&Event, NotificationEvent, FALSE);
DeferredWrite.NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
DeferredWrite.NodeByteSize = sizeof(DEFERRED_WRITE);
DeferredWrite.FileObject = FileObject;
DeferredWrite.BytesToWrite = BytesToWrite;
DeferredWrite.Event = &Event;
DeferredWrite.LimitModifiedPages = (FsContext->Flags & FSRTL_FLAG_LIMIT_MODIFIED_PAGES) != 0;
/* Insert into deferred writes list */
/* Insert into deferred writes list */
if (Retrying)
{
ExInterlockedInsertHeadList(&CcDeferredWrites,
&DeferredWrite.DeferredWriteLinks,
&CcDeferredWriteSpinLock);
}
else
{
ExInterlockedInsertTailList(&CcDeferredWrites,
&DeferredWrite.DeferredWriteLinks,
&CcDeferredWriteSpinLock);
}
/* Wait for the write to complete */
do
{
CcPostDeferredWrites();
} while (KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
&CcIdleDelay) != STATUS_SUCCESS);
return TRUE;
}
BOOLEAN
NTAPI
@ -165,18 +273,53 @@ CcCopyWrite(
VOID
NTAPI
CcDeferWrite(IN PFILE_OBJECT FileObject,
IN PCC_POST_DEFERRED_WRITE PostRoutine,
IN PVOID Context1,
IN PVOID Context2,
IN ULONG BytesToWrite,
IN BOOLEAN Retrying)
CcDeferWrite(
_In_ PFILE_OBJECT FileObject,
_In_ PCC_POST_DEFERRED_WRITE PostRoutine,
_In_ PVOID Context1,
_In_ PVOID Context2,
_In_ ULONG BytesToWrite,
_In_ BOOLEAN Retrying
)
{
NT_DBGBREAK("UNIMPLEMENTED\n");
}
KIRQL OldIrql;
PDEFERRED_WRITE DeferredWrite = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(DEFERRED_WRITE), 'wDcC');
if (DeferredWrite != nullptr)
{
RtlZeroMemory(DeferredWrite, sizeof(DEFERRED_WRITE));
DeferredWrite->NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
DeferredWrite->NodeByteSize = sizeof(DEFERRED_WRITE);
DeferredWrite->FileObject = FileObject;
DeferredWrite->BytesToWrite = BytesToWrite;
DeferredWrite->PostRoutine = PostRoutine;
DeferredWrite->Context1 = Context1;
DeferredWrite->Context2 = Context2;
if (Retrying)
ExInterlockedInsertHeadList(&CcDeferredWrites,
&DeferredWrite->DeferredWriteLinks,
&CcDeferredWriteSpinLock);
else
ExInterlockedInsertTailList(&CcDeferredWrites,
&DeferredWrite->DeferredWriteLinks,
&CcDeferredWriteSpinLock);
CcPostDeferredWrites();
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
CcScheduleLazyWriteScan(TRUE);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
}
else
{
PostRoutine(Context1, Context2);
}
}
VOID
NTAPI
CcFastCopyRead(