From 73e2aff9c5481400343ff4fa4e7e4b2dfe8186b9 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Mon, 17 Apr 2017 17:29:10 +0000 Subject: [PATCH] [NTOS:CC] - Implement CcPurgeCacheSection CORE-12893 svn path=/trunk/; revision=74355 --- reactos/ntoskrnl/cc/fs.c | 74 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/cc/fs.c b/reactos/ntoskrnl/cc/fs.c index 4feb125f708..1bf5095aa98 100644 --- a/reactos/ntoskrnl/cc/fs.c +++ b/reactos/ntoskrnl/cc/fs.c @@ -135,10 +135,82 @@ CcPurgeCacheSection ( IN ULONG Length, IN BOOLEAN UninitializeCacheMaps) { + PROS_SHARED_CACHE_MAP SharedCacheMap; + LONGLONG StartOffset; + LONGLONG EndOffset; + LIST_ENTRY FreeList; + KIRQL OldIrql; + PLIST_ENTRY ListEntry; + PROS_VACB Vacb; + LONGLONG ViewEnd; + CCTRACE(CC_API_DEBUG, "SectionObjectPointer=%p\n FileOffset=%p Length=%lu UninitializeCacheMaps=%d", SectionObjectPointer, FileOffset, Length, UninitializeCacheMaps); - //UNIMPLEMENTED; + if (UninitializeCacheMaps) + { + DPRINT1("FIXME: CcPurgeCacheSection not uninitializing private cache maps\n"); + } + + SharedCacheMap = SectionObjectPointer->SharedCacheMap; + + StartOffset = FileOffset != NULL ? FileOffset->QuadPart : 0; + if (Length == 0 || FileOffset == NULL) + { + EndOffset = MAXLONGLONG; + } + else + { + EndOffset = StartOffset + Length; + ASSERT(EndOffset > StartOffset); + } + + InitializeListHead(&FreeList); + + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &OldIrql); + ListEntry = SharedCacheMap->CacheMapVacbListHead.Flink; + while (ListEntry != &SharedCacheMap->CacheMapVacbListHead) + { + Vacb = CONTAINING_RECORD(ListEntry, ROS_VACB, CacheMapVacbListEntry); + ListEntry = ListEntry->Flink; + + /* Skip VACBs outside the range, or only partially in range */ + if (Vacb->FileOffset.QuadPart < StartOffset) + { + continue; + } + ViewEnd = min(Vacb->FileOffset.QuadPart + VACB_MAPPING_GRANULARITY, + SharedCacheMap->SectionSize.QuadPart); + if (ViewEnd >= EndOffset) + { + break; + } + + ASSERT((Vacb->ReferenceCount == 0) || + (Vacb->ReferenceCount == 1 && Vacb->Dirty)); + + /* This VACB is in range, so unlink it and mark for free */ + RemoveEntryList(&Vacb->VacbLruListEntry); + if (Vacb->Dirty) + { + RemoveEntryList(&Vacb->DirtyVacbListEntry); + DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE; + } + RemoveEntryList(&Vacb->CacheMapVacbListEntry); + InsertHeadList(&FreeList, &Vacb->CacheMapVacbListEntry); + } + KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, OldIrql); + KeReleaseGuardedMutex(&ViewLock); + + while (!IsListEmpty(&FreeList)) + { + Vacb = CONTAINING_RECORD(RemoveHeadList(&FreeList), + ROS_VACB, + CacheMapVacbListEntry); + CcRosInternalFreeVacb(Vacb); + } + return FALSE; }