diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index de4a75ea8f7..ee0ec497d40 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -172,11 +172,27 @@ CcRosFlushVacb ( SIZE_T FlushSize = min(VACB_MAPPING_GRANULARITY, Vacb->SharedCacheMap->SectionSize.QuadPart - Vacb->FileOffset.QuadPart); NTSTATUS Status; + BOOLEAN HaveLock = FALSE; CcRosUnmarkDirtyVacb(Vacb, TRUE); + /* Lock for flush, if we are not already the top-level */ + if (IoGetTopLevelIrp() != (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP) + { + Status = FsRtlAcquireFileForCcFlushEx(Vacb->SharedCacheMap->FileObject); + if (!NT_SUCCESS(Status)) + goto quit; + HaveLock = TRUE; + } + Status = MmFlushVirtualMemory(NULL, &Vacb->BaseAddress, &FlushSize, &Iosb); + if (HaveLock) + { + FsRtlReleaseFileForCcFlush(Vacb->SharedCacheMap->FileObject); + } + +quit: if (!NT_SUCCESS(Status)) CcRosMarkDirtyVacb(Vacb); diff --git a/ntoskrnl/include/internal/fsrtl.h b/ntoskrnl/include/internal/fsrtl.h index 79cc3b6cfbc..228bb7a1cf8 100644 --- a/ntoskrnl/include/internal/fsrtl.h +++ b/ntoskrnl/include/internal/fsrtl.h @@ -148,3 +148,11 @@ NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection(_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection); + +VOID +NTAPI +FsRtlReleaseFileForCcFlush(IN PFILE_OBJECT FileObject); + +NTSTATUS +NTAPI +FsRtlAcquireFileForCcFlushEx(IN PFILE_OBJECT FileObject);