https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d0bf98663b198696a936d…
commit d0bf98663b198696a936dc6f8c4921db282f4bee
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Wed Jan 27 15:29:57 2021 +0100
Commit: Jérôme Gardou <jerome.gardou(a)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: