[NTOSKRNL:CC] Implemented CcSetDirtyInMask
This commit is contained in:
parent
d81565e7ec
commit
f6620f9372
@ -100,21 +100,149 @@ CcFindBitmapRangeToDirty(
|
|||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcSetDirtyInMask(
|
CcSetDirtyInMask(
|
||||||
_In_ PSHARED_CACHE_MAP SharedMap,
|
_In_ PSHARED_CACHE_MAP SharedCacheMap,
|
||||||
_In_ PLARGE_INTEGER FileOffset,
|
_In_ PLARGE_INTEGER FileOffset,
|
||||||
_In_ ULONG Length)
|
_In_ ULONG Length)
|
||||||
{
|
{
|
||||||
NT_DBGBREAK("UNIMPLEMENTED\n");
|
KLOCK_QUEUE_HANDLE LockHandle = {0};
|
||||||
|
LARGE_INTEGER EndOffset = {0};
|
||||||
|
ULONGLONG StartPage ={0};
|
||||||
|
ULONGLONG EndPage = {0};
|
||||||
|
ULONG CurrentPage = {0};
|
||||||
|
PMBCB Mbcb = nullptr;
|
||||||
|
PBITMAP_RANGE BitmapRange = nullptr;
|
||||||
|
PULONG Bitmap = nullptr;
|
||||||
|
PULONG VacbLevel = nullptr;
|
||||||
|
ULONG BitMask = {0};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate start and end pages
|
||||||
|
StartPage = FileOffset->QuadPart >> PAGE_SHIFT;
|
||||||
|
EndOffset.QuadPart = FileOffset->QuadPart + Length;
|
||||||
|
EndPage = (EndOffset.QuadPart - 1) >> PAGE_SHIFT;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if (SharedCacheMap->SectionSize.QuadPart > VACB_MAPPING_GRANULARITY)
|
||||||
|
{
|
||||||
|
if (!CcPrefillVacbLevelZone(1, &LockHandle, 0, 0, 0))
|
||||||
|
return;
|
||||||
|
VacbLevel = CcAllocateVacbLevel(0);
|
||||||
|
KeLowerIrql(LockHandle.OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeAcquireInStackQueuedSpinLock(&SharedCacheMap->BcbSpinLock, &LockHandle);
|
||||||
|
|
||||||
|
Mbcb = SharedCacheMap->Mbcb;
|
||||||
|
if (Mbcb == nullptr)
|
||||||
|
{
|
||||||
|
Mbcb = CcAllocateInitializeBcb();
|
||||||
|
if (Mbcb == nullptr)
|
||||||
|
goto ReleaseAndExit;
|
||||||
|
|
||||||
|
Mbcb->NodeTypeCode = CACHE_NTC_BCB;
|
||||||
|
InitializeListHead(&Mbcb->BitmapRanges);
|
||||||
|
InsertHeadList(&Mbcb->BitmapRanges, &Mbcb->BitmapRange1.Links);
|
||||||
|
Mbcb->BitmapRange1.FirstDirtyPage = (ULONG)-1;
|
||||||
|
Mbcb->BitmapRange1.Bitmap = (PULONG)&Mbcb->BitmapRange2;
|
||||||
|
SharedCacheMap->Mbcb = Mbcb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EndPage < 512 || Mbcb->NodeTypeCode == 0x02F9)
|
||||||
|
{
|
||||||
|
BitmapRange = CcFindBitmapRangeToDirty(Mbcb, StartPage, &Bitmap);
|
||||||
|
if (BitmapRange == nullptr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (StartPage < BitmapRange->BasePage + BitmapRange->FirstDirtyPage)
|
||||||
|
BitmapRange->FirstDirtyPage = StartPage - BitmapRange->BasePage;
|
||||||
|
if (EndPage > BitmapRange->BasePage + BitmapRange->LastDirtyPage)
|
||||||
|
BitmapRange->LastDirtyPage = EndPage - BitmapRange->BasePage;
|
||||||
|
|
||||||
|
if (SharedCacheMap->DirtyPages == 0)
|
||||||
|
{
|
||||||
|
CcScheduleLazyWriteScan(FALSE);
|
||||||
|
RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
|
||||||
|
InsertTailList(&CcDirtySharedCacheMapList, &SharedCacheMap->SharedCacheMapLinks);
|
||||||
|
Mbcb->ResumeWritePage = StartPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap = &BitmapRange->Bitmap[(StartPage - BitmapRange->BasePage) >> 5];
|
||||||
|
BitMask = 1 << (StartPage & 0x1F);
|
||||||
|
|
||||||
|
for (CurrentPage = StartPage; CurrentPage <= EndPage; CurrentPage++)
|
||||||
|
{
|
||||||
|
if ((*Bitmap & BitMask) == 0)
|
||||||
|
{
|
||||||
|
CcTotalDirtyPages++;
|
||||||
|
Mbcb->DirtyPages++;
|
||||||
|
BitmapRange->DirtyPages++;
|
||||||
|
SharedCacheMap->DirtyPages++;
|
||||||
|
*Bitmap |= BitMask;
|
||||||
|
}
|
||||||
|
BitMask <<= 1;
|
||||||
|
if (BitMask == 0)
|
||||||
|
{
|
||||||
|
Bitmap++;
|
||||||
|
BitMask = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle large files (>2MB)
|
||||||
|
if (Mbcb->BitmapRange1.DirtyPages)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(VacbLevel, Mbcb->BitmapRange1.Bitmap, (2 * sizeof(BITMAP_RANGE)));
|
||||||
|
RtlZeroMemory(Mbcb->BitmapRange1.Bitmap, (2 * sizeof(BITMAP_RANGE)));
|
||||||
|
}
|
||||||
|
Mbcb->BitmapRange1.Bitmap = VacbLevel;
|
||||||
|
|
||||||
|
// Initialize BitmapRange2
|
||||||
|
InsertTailList(&Mbcb->BitmapRanges, &Mbcb->BitmapRange2.Links);
|
||||||
|
Mbcb->BitmapRange2.BasePage = (ULONGLONG)-1;
|
||||||
|
Mbcb->BitmapRange2.FirstDirtyPage = (ULONG)-1;
|
||||||
|
|
||||||
|
// Initialize BitmapRange3
|
||||||
|
InsertTailList(&Mbcb->BitmapRanges, &Mbcb->BitmapRange3.Links);
|
||||||
|
Mbcb->BitmapRange3.BasePage = (ULONGLONG)-1;
|
||||||
|
Mbcb->BitmapRange3.FirstDirtyPage = (ULONG)-1;
|
||||||
|
|
||||||
|
VacbLevel = nullptr;
|
||||||
|
Mbcb->NodeTypeCode = 0x02F9;
|
||||||
|
|
||||||
|
KeReleaseInStackQueuedSpinLock(&LockHandle);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update ValidDataGoal if necessary
|
||||||
|
if (EndOffset.QuadPart > SharedCacheMap->ValidDataGoal.QuadPart)
|
||||||
|
{
|
||||||
|
SharedCacheMap->ValidDataGoal = EndOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseAndExit:
|
||||||
|
if (VacbLevel != nullptr)
|
||||||
|
{
|
||||||
|
*VacbLevel = (ULONG)CcVacbLevelFreeList;
|
||||||
|
CcVacbLevelEntries++;
|
||||||
|
CcVacbLevelFreeList = VacbLevel;
|
||||||
|
}
|
||||||
|
KeReleaseInStackQueuedSpinLock(&LockHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcMapAndCopy(
|
CcMapAndCopy(
|
||||||
_In_ PSHARED_CACHE_MAP SharedMap,
|
_In_ PSHARED_CACHE_MAP SharedCacheMap,
|
||||||
_In_ PVOID Buffer,
|
_In_ PVOID Buffer,
|
||||||
_In_ PLARGE_INTEGER FileOffset,
|
_In_ PLARGE_INTEGER FileOffset,
|
||||||
_In_ ULONG Length,
|
_In_ ULONG Length,
|
||||||
_In_ ULONG CopyFlags,
|
_In_ ULONG Flags,
|
||||||
_In_ PFILE_OBJECT FileObject,
|
_In_ PFILE_OBJECT FileObject,
|
||||||
_In_ PLARGE_INTEGER ValidDataLength,
|
_In_ PLARGE_INTEGER ValidDataLength,
|
||||||
_In_ BOOLEAN Wait)
|
_In_ BOOLEAN Wait)
|
||||||
@ -122,6 +250,10 @@ CcMapAndCopy(
|
|||||||
NT_DBGBREAK("UNIMPLEMENTED\n");
|
NT_DBGBREAK("UNIMPLEMENTED\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* EXTERNAL API FUNCTIONS */
|
/* EXTERNAL API FUNCTIONS */
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
@ -132,22 +264,22 @@ CcCanIWrite(
|
|||||||
_In_ BOOLEAN Wait,
|
_In_ BOOLEAN Wait,
|
||||||
_In_ UCHAR Retrying)
|
_In_ UCHAR Retrying)
|
||||||
{
|
{
|
||||||
PFSRTL_COMMON_FCB_HEADER FsContext;
|
PFSRTL_COMMON_FCB_HEADER FsContext = nullptr;
|
||||||
PSHARED_CACHE_MAP SharedCacheMap;
|
PSHARED_CACHE_MAP SharedCacheMap = nullptr;
|
||||||
DEFERRED_WRITE DeferredWrite;
|
DEFERRED_WRITE DeferredWrite = {0};
|
||||||
KEVENT Event;
|
KEVENT Event = {0};
|
||||||
ULONG WriteSize;
|
ULONG WriteSize = {0};
|
||||||
ULONG Pages;
|
ULONG Pages = {0};
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql = {0};
|
||||||
BOOLEAN IsSmallThreshold = FALSE;
|
BOOLEAN IsSmallThreshold = false;
|
||||||
|
|
||||||
|
|
||||||
/* Quick checks for immediate return */
|
/* Quick checks for immediate return */
|
||||||
if (FileObject->Flags & FO_WRITE_THROUGH)
|
if (FileObject->Flags & FO_WRITE_THROUGH)
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
if (IoIsFileOriginRemote(FileObject) && Retrying < 0xFD)
|
if (IoIsFileOriginRemote(FileObject) && Retrying < 0xFD)
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
/* Calculate size and pages */
|
/* Calculate size and pages */
|
||||||
WriteSize = min(BytesToWrite, 0x40000);
|
WriteSize = min(BytesToWrite, 0x40000);
|
||||||
@ -172,7 +304,7 @@ CcCanIWrite(
|
|||||||
{
|
{
|
||||||
if (SharedCacheMap->DirtyPageThreshold < (SharedCacheMap->DirtyPages + Pages))
|
if (SharedCacheMap->DirtyPageThreshold < (SharedCacheMap->DirtyPages + Pages))
|
||||||
{
|
{
|
||||||
IsSmallThreshold = TRUE;
|
IsSmallThreshold = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,7 +324,7 @@ CcCanIWrite(
|
|||||||
MmAvailablePages > MmThrottleBottom &&
|
MmAvailablePages > MmThrottleBottom &&
|
||||||
!IsSmallThreshold))
|
!IsSmallThreshold))
|
||||||
{
|
{
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +339,7 @@ CcCanIWrite(
|
|||||||
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
|
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, false);
|
||||||
|
|
||||||
DeferredWrite.NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
|
DeferredWrite.NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
|
||||||
DeferredWrite.NodeByteSize = sizeof(DEFERRED_WRITE);
|
DeferredWrite.NodeByteSize = sizeof(DEFERRED_WRITE);
|
||||||
@ -238,7 +370,7 @@ CcCanIWrite(
|
|||||||
} while (KeWaitForSingleObject(&Event,
|
} while (KeWaitForSingleObject(&Event,
|
||||||
Executive,
|
Executive,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
FALSE,
|
false,
|
||||||
&CcIdleDelay) != STATUS_SUCCESS);
|
&CcIdleDelay) != STATUS_SUCCESS);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
Loading…
Reference in New Issue
Block a user