[NTOSKRNL:CC] Implemented CcSetDirtyInMask
This commit is contained in:
parent
d81565e7ec
commit
f6620f9372
@ -100,28 +100,160 @@ CcFindBitmapRangeToDirty(
|
||||
VOID
|
||||
NTAPI
|
||||
CcSetDirtyInMask(
|
||||
_In_ PSHARED_CACHE_MAP SharedMap,
|
||||
_In_ PSHARED_CACHE_MAP SharedCacheMap,
|
||||
_In_ PLARGE_INTEGER FileOffset,
|
||||
_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
|
||||
NTAPI
|
||||
CcMapAndCopy(
|
||||
_In_ PSHARED_CACHE_MAP SharedMap,
|
||||
_In_ PSHARED_CACHE_MAP SharedCacheMap,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ PLARGE_INTEGER FileOffset,
|
||||
_In_ ULONG Length,
|
||||
_In_ ULONG CopyFlags,
|
||||
_In_ ULONG Flags,
|
||||
_In_ PFILE_OBJECT FileObject,
|
||||
_In_ PLARGE_INTEGER ValidDataLength,
|
||||
_In_ BOOLEAN Wait)
|
||||
{
|
||||
NT_DBGBREAK("UNIMPLEMENTED\n");
|
||||
{
|
||||
NT_DBGBREAK("UNIMPLEMENTED\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* EXTERNAL API FUNCTIONS */
|
||||
|
||||
BOOLEAN
|
||||
@ -132,22 +264,22 @@ CcCanIWrite(
|
||||
_In_ BOOLEAN Wait,
|
||||
_In_ UCHAR Retrying)
|
||||
{
|
||||
PFSRTL_COMMON_FCB_HEADER FsContext;
|
||||
PSHARED_CACHE_MAP SharedCacheMap;
|
||||
DEFERRED_WRITE DeferredWrite;
|
||||
KEVENT Event;
|
||||
ULONG WriteSize;
|
||||
ULONG Pages;
|
||||
KIRQL OldIrql;
|
||||
BOOLEAN IsSmallThreshold = FALSE;
|
||||
PFSRTL_COMMON_FCB_HEADER FsContext = nullptr;
|
||||
PSHARED_CACHE_MAP SharedCacheMap = nullptr;
|
||||
DEFERRED_WRITE DeferredWrite = {0};
|
||||
KEVENT Event = {0};
|
||||
ULONG WriteSize = {0};
|
||||
ULONG Pages = {0};
|
||||
KIRQL OldIrql = {0};
|
||||
BOOLEAN IsSmallThreshold = false;
|
||||
|
||||
|
||||
/* Quick checks for immediate return */
|
||||
if (FileObject->Flags & FO_WRITE_THROUGH)
|
||||
return TRUE;
|
||||
return true;
|
||||
|
||||
if (IoIsFileOriginRemote(FileObject) && Retrying < 0xFD)
|
||||
return TRUE;
|
||||
return true;
|
||||
|
||||
/* Calculate size and pages */
|
||||
WriteSize = min(BytesToWrite, 0x40000);
|
||||
@ -172,7 +304,7 @@ CcCanIWrite(
|
||||
{
|
||||
if (SharedCacheMap->DirtyPageThreshold < (SharedCacheMap->DirtyPages + Pages))
|
||||
{
|
||||
IsSmallThreshold = TRUE;
|
||||
IsSmallThreshold = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -192,7 +324,7 @@ CcCanIWrite(
|
||||
MmAvailablePages > MmThrottleBottom &&
|
||||
!IsSmallThreshold))
|
||||
{
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,7 +339,7 @@ CcCanIWrite(
|
||||
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
|
||||
}
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
KeInitializeEvent(&Event, NotificationEvent, false);
|
||||
|
||||
DeferredWrite.NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
|
||||
DeferredWrite.NodeByteSize = sizeof(DEFERRED_WRITE);
|
||||
@ -238,7 +370,7 @@ CcCanIWrite(
|
||||
} while (KeWaitForSingleObject(&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
false,
|
||||
&CcIdleDelay) != STATUS_SUCCESS);
|
||||
|
||||
return TRUE;
|
||||
|
Loading…
Reference in New Issue
Block a user