Skip to content

Commit

Permalink
[NTOS:CC] Rewrite CcPurgeCacheSection
Browse files Browse the repository at this point in the history
  • Loading branch information
TAN-Gaming committed Nov 12, 2024
1 parent d1c5461 commit 1e742de
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 8 deletions.
43 changes: 35 additions & 8 deletions ntoskrnl/cc/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,31 @@ CcIsThereDirtyData (
return Dirty;
}

static
VOID
CcpUpdatePurgedFileCache(
_In_ PROS_SHARED_CACHE_MAP SharedCacheMap,
_In_ ULONG PurgedDirtyPages)
{
KIRQL OldIrql;

OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);

/* Update number of dirty pages and check dirty status */
CcTotalDirtyPages -= PurgedDirtyPages;
SharedCacheMap->DirtyPages -= PurgedDirtyPages;
if (SharedCacheMap->DirtyPages == 0)
{
/* The file cache is no longer dirty, remove from dirty list */
RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
InsertTailList(&CcCleanSharedCacheMapList, &SharedCacheMap->SharedCacheMapLinks);
}

KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
}

/*
* @unimplemented
*/
Expand Down Expand Up @@ -237,21 +262,16 @@ CcPurgeCacheSection (
* Allow one ref: VACB is supposed to be always 1-referenced
*/
Refs = CcRosVacbGetRefCount(Vacb);
if ((Refs > 1 && !Vacb->Dirty) ||
(Refs > 2 && Vacb->Dirty))
if (Refs > 1)
{
Success = FALSE;
break;
}

/* This VACB is in range, so unlink it and mark for free */
ASSERT(Refs == 1 || Vacb->Dirty);
ASSERT(Refs == 1);
RemoveEntryList(&Vacb->VacbLruListEntry);
InitializeListHead(&Vacb->VacbLruListEntry);
if (Vacb->Dirty)
{
CcRosUnmarkDirtyVacb(Vacb, FALSE);
}
RemoveEntryList(&Vacb->CacheMapVacbListEntry);
InsertHeadList(&FreeList, &Vacb->CacheMapVacbListEntry);
}
Expand All @@ -273,7 +293,14 @@ CcPurgeCacheSection (
/* Now make sure that Mm doesn't hold some pages here. */
purgeMm:
if (Success)
Success = MmPurgeSegment(SectionObjectPointer, FileOffset, Length);
{
ULONG PurgedDirtyPages;

Success = MmPurgeSegment(SectionObjectPointer, FileOffset, Length, &PurgedDirtyPages);

if (SharedCacheMap && PurgedDirtyPages != 0)
CcpUpdatePurgedFileCache(SharedCacheMap, PurgedDirtyPages);
}

return Success;
}
Expand Down
1 change: 1 addition & 0 deletions ntoskrnl/include/internal/cc.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
//
extern ULONG CcRosTraceLevel;
extern LIST_ENTRY DirtyVacbListHead;
extern LIST_ENTRY CcCleanSharedCacheMapList;
extern LIST_ENTRY CcDirtySharedCacheMapList;
extern ULONG CcDirtyPageThreshold;
extern ULONG CcTotalDirtyPages;
Expand Down

0 comments on commit 1e742de

Please sign in to comment.