Skip to content

Commit

Permalink
[NTOS:CC] Rewrite CcFlushCache (attempt 2)
Browse files Browse the repository at this point in the history
  • Loading branch information
TAN-Gaming committed Nov 16, 2024
1 parent 97c02f5 commit 915306a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 31 deletions.
84 changes: 54 additions & 30 deletions ntoskrnl/cc/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -1036,33 +1036,62 @@ CcRosInternalFreeVacb (
return STATUS_SUCCESS;
}

BOOLEAN
CcpAcquireFileCacheForFlush(
_In_ PROS_SHARED_CACHE_MAP SharedCacheMap,
_In_ BOOLEAN Wait)
{
if (Wait)
{
ExAcquireFastMutex(&SharedCacheMap->FlushCacheLock);
return TRUE;
}

return ExTryToAcquireFastMutex(&SharedCacheMap->FlushCacheLock);
}

VOID
CcpReleaseFileCacheFromFlush(
_In_ PROS_SHARED_CACHE_MAP SharedCacheMap)
{
ExReleaseFastMutex(&SharedCacheMap->FlushCacheLock);
}

static
VOID
CcpUpdateFlushedFileCache(
CcpFileCacheFlushComplete(
_In_ PROS_SHARED_CACHE_MAP SharedCacheMap,
_In_ ULONG FlushedPages,
_In_ BOOLEAN UpdateCacheMap,
_In_ LONGLONG NewVdl)
{
KIRQL OldIrql;

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

/* Update number of dirty pages and check dirty status */
/* Update total dirty pages */
CcTotalDirtyPages -= FlushedPages;
SharedCacheMap->DirtyPages -= FlushedPages;
if (SharedCacheMap->DirtyPages == 0)

if (UpdateCacheMap)
{
/* The file cache is no longer dirty, remove from dirty list */
RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
InsertTailList(&CcCleanSharedCacheMapList, &SharedCacheMap->SharedCacheMapLinks);
}
KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);

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

/* Update VDL */
if (SharedCacheMap->ValidDataLength.QuadPart < NewVdl)
SharedCacheMap->ValidDataLength.QuadPart = NewVdl;
/* Update VDL */
if (SharedCacheMap->ValidDataLength.QuadPart < NewVdl)
SharedCacheMap->ValidDataLength.QuadPart = NewVdl;

KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
}

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

Expand Down Expand Up @@ -1145,7 +1174,10 @@ CcpFlushFileCache(
MmLength = VACB_MAPPING_GRANULARITY - (FlushStart % VACB_MAPPING_GRANULARITY);
}

Status = MmFlushSegment(SharedCacheMap->FileObject->SectionObjectPointer, &MmOffset, MmLength, &MmFlushedPages);
Status = MmFlushSegment(SharedCacheMap->FileObject->SectionObjectPointer,
&MmOffset,
MmLength,
&MmFlushedPages);
FlushedPages += MmFlushedPages;
if (!NT_SUCCESS(Status))
break;
Expand All @@ -1157,21 +1189,7 @@ CcpFlushFileCache(
if (HaveFileLock)
FsRtlReleaseFileForCcFlush(SharedCacheMap->FileObject);

if (UpdateCacheMap)
{
CcpUpdateFlushedFileCache(SharedCacheMap, FlushedPages, FlushStart);
}
else if (FlushedPages != 0)
{
KIRQL OldIrql;

OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);

/* Update total dirty pages */
CcTotalDirtyPages -= FlushedPages;

KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
}
CcpFileCacheFlushComplete(SharedCacheMap, FlushedPages, UpdateCacheMap, FlushStart);

Quit:
if (IoStatus)
Expand Down Expand Up @@ -1228,8 +1246,13 @@ CcFlushCache(
SharedCacheMap = SectionObjectPointers->SharedCacheMap;
if (SharedCacheMap)
{
/* Call internal function */
CcpAcquireFileCacheForFlush(SharedCacheMap, TRUE);

CcpFlushFileCache(SharedCacheMap, FileOffset, Length, TRUE, IoStatus);

CcpReleaseFileCacheFromFlush(SharedCacheMap);

/* IoStatus was handled by the internal function. We can simply return here */
return;
}
else
Expand Down Expand Up @@ -1347,6 +1370,7 @@ CcRosInitializeFileCache (
KeInitializeSpinLock(&SharedCacheMap->CacheMapLock);
InitializeListHead(&SharedCacheMap->CacheMapVacbListHead);
InitializeListHead(&SharedCacheMap->BcbList);
ExInitializeFastMutex(&SharedCacheMap->FlushCacheLock);

SharedCacheMap->Flags = SHARED_CACHE_MAP_IN_CREATION;

Expand Down
11 changes: 10 additions & 1 deletion ntoskrnl/include/internal/cc.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ typedef struct _ROS_SHARED_CACHE_MAP
LIST_ENTRY CacheMapVacbListHead;
BOOLEAN PinAccess;
KSPIN_LOCK CacheMapLock;
FAST_MUTEX FlushCacheLock;
#if DBG
BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
#endif
Expand All @@ -202,7 +203,6 @@ typedef struct _ROS_SHARED_CACHE_MAP
#define READAHEAD_DISABLED 0x1
#define WRITEBEHIND_DISABLED 0x2
#define SHARED_CACHE_MAP_IN_CREATION 0x4
#define SHARED_CACHE_MAP_IN_LAZYWRITE 0x8
#define MAX_FLUSH_LENGTH ((MAXULONG >> PAGE_SHIFT) * PAGE_SIZE)

typedef struct _ROS_VACB
Expand Down Expand Up @@ -351,6 +351,15 @@ CcpMarkDirtyFileCache(
_In_ PVOID BaseAddress,
_In_ ULONG Length);

BOOLEAN
CcpAcquireFileCacheForFlush(
_In_ PROS_SHARED_CACHE_MAP SharedCacheMap,
_In_ BOOLEAN Wait);

VOID
CcpReleaseFileCacheFromFlush(
_In_ PROS_SHARED_CACHE_MAP SharedCacheMap);

VOID
CcpFlushFileCache(
_In_ PROS_SHARED_CACHE_MAP SharedCacheMap,
Expand Down

0 comments on commit 915306a

Please sign in to comment.