[NTOS:CC] Be sure to flush the whole file in CcFlushCache

This commit is contained in:
Jérôme Gardou 2021-01-27 15:29:57 +01:00
parent 90c6a65efe
commit d0bf98663b

View file

@ -906,12 +906,19 @@ CcFlushCache (
CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p FileOffset=0x%I64X Length=%lu\n",
SectionObjectPointers, FileOffset ? FileOffset->QuadPart : 0LL, Length);
if (!SectionObjectPointers || !SectionObjectPointers->SharedCacheMap)
if (!SectionObjectPointers)
{
Status = STATUS_INVALID_PARAMETER;
goto quit;
}
if (!SectionObjectPointers->SharedCacheMap)
{
/* Forward this to Mm */
MmFlushSegment(SectionObjectPointers, FileOffset, Length, IoStatus);
return;
}
SharedCacheMap = SectionObjectPointers->SharedCacheMap;
ASSERT(SharedCacheMap);
if (FileOffset)
@ -934,8 +941,14 @@ CcFlushCache (
IoStatus->Information = 0;
}
/*
* We flush the VACBs that we find here.
* If there is no (dirty) VACB, it doesn't mean that there is no data to flush, so we call Mm to be sure.
* This is suboptimal, but this is due to the lack of granularity of how we track dirty cache data
*/
while (FlushStart < FlushEnd)
{
BOOLEAN DirtyVacb = FALSE;
PROS_VACB vacb = CcRosLookupVacb(SharedCacheMap, FlushStart);
if (vacb != NULL)
@ -947,6 +960,7 @@ CcFlushCache (
{
goto quit;
}
DirtyVacb = TRUE;
}
CcRosReleaseVacb(SharedCacheMap, vacb, FALSE, FALSE);
@ -955,11 +969,39 @@ CcFlushCache (
IoStatus->Information += VACB_MAPPING_GRANULARITY;
}
if (!DirtyVacb)
{
IO_STATUS_BLOCK MmIosb;
LARGE_INTEGER MmOffset;
MmOffset.QuadPart = FlushStart;
if (FlushEnd - (FlushEnd % VACB_MAPPING_GRANULARITY) <= FlushStart)
{
/* The whole range fits within a VACB chunk. */
Status = MmFlushSegment(SectionObjectPointers, &MmOffset, FlushEnd - FlushStart, &MmIosb);
}
else
{
ULONG MmLength = VACB_MAPPING_GRANULARITY - (FlushStart % VACB_MAPPING_GRANULARITY);
Status = MmFlushSegment(SectionObjectPointers, &MmOffset, MmLength, &MmIosb);
}
if (!NT_SUCCESS(Status))
goto quit;
if (IoStatus)
IoStatus->Information += MmIosb.Information;
}
if (!NT_SUCCESS(RtlLongLongAdd(FlushStart, VACB_MAPPING_GRANULARITY, &FlushStart)))
{
/* We're at the end of file ! */
break;
}
/* Round down to next VACB start now */
FlushStart -= FlushStart % VACB_MAPPING_GRANULARITY;
}
quit: