[NTOSKRNL:CC] Implemented CcCanIWrite and CcDeferWrite
This commit is contained in:
parent
377ff4fb9b
commit
d81565e7ec
@ -130,12 +130,120 @@ CcCanIWrite(
|
|||||||
_In_ PFILE_OBJECT FileObject,
|
_In_ PFILE_OBJECT FileObject,
|
||||||
_In_ ULONG BytesToWrite,
|
_In_ ULONG BytesToWrite,
|
||||||
_In_ BOOLEAN Wait,
|
_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
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
@ -165,18 +273,53 @@ CcCopyWrite(
|
|||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
CcDeferWrite(
|
||||||
CcDeferWrite(IN PFILE_OBJECT FileObject,
|
_In_ PFILE_OBJECT FileObject,
|
||||||
IN PCC_POST_DEFERRED_WRITE PostRoutine,
|
_In_ PCC_POST_DEFERRED_WRITE PostRoutine,
|
||||||
IN PVOID Context1,
|
_In_ PVOID Context1,
|
||||||
IN PVOID Context2,
|
_In_ PVOID Context2,
|
||||||
IN ULONG BytesToWrite,
|
_In_ ULONG BytesToWrite,
|
||||||
IN BOOLEAN Retrying)
|
_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
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcFastCopyRead(
|
CcFastCopyRead(
|
||||||
|
Loading…
Reference in New Issue
Block a user