Author: tfaber Date: Mon Apr 17 17:29:10 2017 New Revision: 74355
URL: http://svn.reactos.org/svn/reactos?rev=74355&view=rev Log: [NTOS:CC] - Implement CcPurgeCacheSection CORE-12893
Modified: trunk/reactos/ntoskrnl/cc/fs.c
Modified: trunk/reactos/ntoskrnl/cc/fs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cc/fs.c?rev=74355&... ============================================================================== --- trunk/reactos/ntoskrnl/cc/fs.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/cc/fs.c [iso-8859-1] Mon Apr 17 17:29:10 2017 @@ -135,10 +135,82 @@ 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; }