https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d0bf98663b198696a936dc6f8c4921db282f4bee
commit d0bf98663b198696a936dc6f8c4921db282f4bee Author: Jérôme Gardou <jerome.gar...@reactos.org> AuthorDate: Wed Jan 27 15:29:57 2021 +0100 Commit: Jérôme Gardou <jerome.gar...@reactos.org> CommitDate: Wed Feb 3 09:41:23 2021 +0100 [NTOS:CC] Be sure to flush the whole file in CcFlushCache --- ntoskrnl/cc/view.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index 06ec86788a9..591168eeba0 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -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: