https://git.reactos.org/?p=reactos.git;a=commitdiff;h=33cde2831225c26f4b7af…
commit 33cde2831225c26f4b7afed69dc1f56e4a6ab32b
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Wed Dec 30 10:53:31 2020 +0100
Commit: Jérôme Gardou <jerome.gardou(a)reactos.org>
CommitDate: Wed Feb 3 09:41:23 2021 +0100
[NTOS:CC] Simplify CcRosDeleteFileCache
---
ntoskrnl/cc/view.c | 147 +++++++++++++++++++++++++----------------------------
1 file changed, 68 insertions(+), 79 deletions(-)
diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c
index 40413a91601..b6b7ec57560 100644
--- a/ntoskrnl/cc/view.c
+++ b/ntoskrnl/cc/view.c
@@ -974,105 +974,94 @@ CcRosDeleteFileCache (
*/
{
PLIST_ENTRY current_entry;
- PROS_VACB current;
- LIST_ENTRY FreeList;
ASSERT(SharedCacheMap);
+ ASSERT(SharedCacheMap == FileObject->SectionObjectPointer->SharedCacheMap);
+ ASSERT(SharedCacheMap->OpenCount == 0);
- SharedCacheMap->OpenCount++;
- KeReleaseQueuedSpinLock(LockQueueMasterLock, *OldIrql);
+ /* Remove all VACBs from the global lists */
+ KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
+ current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
+ while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
+ {
+ PROS_VACB Vacb = CONTAINING_RECORD(current_entry, ROS_VACB,
CacheMapVacbListEntry);
- CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
+ RemoveEntryList(&Vacb->VacbLruListEntry);
+ InitializeListHead(&Vacb->VacbLruListEntry);
- *OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
- SharedCacheMap->OpenCount--;
- if (SharedCacheMap->OpenCount == 0)
+ if (Vacb->Dirty)
+ {
+ CcRosUnmarkDirtyVacb(Vacb, FALSE);
+ /* Mark it as dirty again so we know that we have to flush before freeing it
*/
+ Vacb->Dirty = TRUE;
+ }
+
+ current_entry = current_entry->Flink;
+ }
+
+ /* Make sure there is no trace anymore of this map */
+ FileObject->SectionObjectPointer->SharedCacheMap = NULL;
+ RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
+
+ KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
+ KeReleaseQueuedSpinLock(LockQueueMasterLock, *OldIrql);
+
+ /* Now that we're out of the locks, free everything for real */
+ while (!IsListEmpty(&SharedCacheMap->CacheMapVacbListHead))
{
- FileObject->SectionObjectPointer->SharedCacheMap = NULL;
+ PROS_VACB Vacb =
CONTAINING_RECORD(RemoveHeadList(&SharedCacheMap->CacheMapVacbListHead), ROS_VACB,
CacheMapVacbListEntry);
+ ULONG RefCount;
- /*
- * Release all VACBs
- */
- InitializeListHead(&FreeList);
- KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
- while (!IsListEmpty(&SharedCacheMap->CacheMapVacbListHead))
+ InitializeListHead(&Vacb->CacheMapVacbListEntry);
+
+ /* Flush to disk, if needed */
+ if (Vacb->Dirty)
{
- current_entry =
RemoveTailList(&SharedCacheMap->CacheMapVacbListHead);
- KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
+ SIZE_T FlushSize = min(VACB_MAPPING_GRANULARITY,
Vacb->SharedCacheMap->SectionSize.QuadPart - Vacb->FileOffset.QuadPart);
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
- current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
- RemoveEntryList(¤t->VacbLruListEntry);
- InitializeListHead(¤t->VacbLruListEntry);
- if (current->Dirty)
- {
- KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
- CcRosUnmarkDirtyVacb(current, FALSE);
- KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
- DPRINT1("Freeing dirty VACB\n");
- }
- if (current->MappedCount != 0)
+ Status = MmFlushVirtualMemory(NULL, &Vacb->BaseAddress,
&FlushSize, &Iosb);
+ if (!NT_SUCCESS(Status))
{
- current->MappedCount = 0;
- NT_VERIFY(CcRosVacbDecRefCount(current) > 0);
- DPRINT1("Freeing mapped VACB\n");
+ /* Complain. There's not much we can do */
+ DPRINT1("Failed to flush VACB to disk while deleting the cache
entry. Status: 0x%08x\n", Status);
}
- InsertHeadList(&FreeList, ¤t->CacheMapVacbListEntry);
-
- KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
+ Vacb->Dirty = FALSE;
}
-#if DBG
- SharedCacheMap->Trace = FALSE;
-#endif
- KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
- KeReleaseQueuedSpinLock(LockQueueMasterLock, *OldIrql);
- if(SharedCacheMap->Section)
- ObDereferenceObject(SharedCacheMap->Section);
- ObDereferenceObject(SharedCacheMap->FileObject);
-
- while (!IsListEmpty(&FreeList))
- {
- ULONG Refs;
-
- current_entry = RemoveTailList(&FreeList);
- current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
- InitializeListHead(¤t->CacheMapVacbListEntry);
- Refs = CcRosVacbDecRefCount(current);
+ RefCount = CcRosVacbDecRefCount(Vacb);
#if DBG // CORE-14578
- if (Refs != 0)
+ if (RefCount != 0)
+ {
+ DPRINT1("Leaking VACB %p attached to %p (%I64d)\n", Vacb,
FileObject, Vacb->FileOffset.QuadPart);
+ DPRINT1("There are: %d references left\n", RefCount);
+ DPRINT1("Map: %d\n", Vacb->MappedCount);
+ DPRINT1("Dirty: %d\n", Vacb->Dirty);
+ if (FileObject->FileName.Length != 0)
{
- DPRINT1("Leaking VACB %p attached to %p (%I64d)\n", current,
FileObject, current->FileOffset.QuadPart);
- DPRINT1("There are: %d references left\n", Refs);
- DPRINT1("Map: %d\n", current->MappedCount);
- DPRINT1("Dirty: %d\n", current->Dirty);
- if (FileObject->FileName.Length != 0)
- {
- DPRINT1("File was: %wZ\n", &FileObject->FileName);
- }
- else if (FileObject->FsContext != NULL &&
-
((PFSRTL_COMMON_FCB_HEADER)(FileObject->FsContext))->NodeTypeCode == 0x0502
&&
-
((PFSRTL_COMMON_FCB_HEADER)(FileObject->FsContext))->NodeByteSize == 0x1F8
&&
- ((PUNICODE_STRING)(((PUCHAR)FileObject->FsContext) +
0x100))->Length != 0)
- {
- DPRINT1("File was: %wZ (FastFAT)\n",
(PUNICODE_STRING)(((PUCHAR)FileObject->FsContext) + 0x100));
- }
- else
- {
- DPRINT1("No name for the file\n");
- }
+ DPRINT1("File was: %wZ\n", &FileObject->FileName);
}
+ else
+ {
+ DPRINT1("No name for the file\n");
+ }
+ }
#else
- ASSERT(Refs == 0);
+ (void)RefCount;
#endif
- }
+ }
- *OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
- RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
- KeReleaseQueuedSpinLock(LockQueueMasterLock, *OldIrql);
+ /* Release the references we own */
+ if(SharedCacheMap->Section)
+ ObDereferenceObject(SharedCacheMap->Section);
+ ObDereferenceObject(SharedCacheMap->FileObject);
+
+ ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap);
+
+ /* Acquire the lock again for our caller */
+ *OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
- ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap);
- *OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
- }
return STATUS_SUCCESS;
}