[NTOSKRNL] Fix lazy writer for in-use VACB.
[reactos.git] / ntoskrnl / cc / view.c
index 081d881..e1d0643 100644 (file)
@@ -205,6 +205,8 @@ CcRosFlushDirtyPages (
 
     while ((current_entry != &DirtyVacbListHead) && (Target > 0))
     {
+        ULONG Refs;
+
         current = CONTAINING_RECORD(current_entry,
                                     ROS_VACB,
                                     DirtyVacbListEntry);
@@ -231,7 +233,9 @@ CcRosFlushDirtyPages (
         ASSERT(current->Dirty);
 
         /* One reference is added above */
-        if (CcRosVacbGetRefCount(current) > 2)
+        Refs = CcRosVacbGetRefCount(current);
+        if ((Refs > 3 && current->PinCount == 0) ||
+            (Refs > 4 && current->PinCount > 1))
         {
             current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
                 current->SharedCacheMap->LazyWriteContext);
@@ -1132,7 +1136,32 @@ CcRosDeleteFileCache (
             current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
             InitializeListHead(&current->CacheMapVacbListEntry);
             Refs = CcRosVacbDecRefCount(current);
+#if DBG // CORE-14578
+            if (Refs != 0)
+            {
+                DPRINT1("Leaking VACB %p attached to %p (%I64d)\n", current, FileObject, current->FileOffset.QuadPart);
+                DPRINT1("There are: %d references left\n", Refs);
+                DPRINT1("Pin: %d, Map: %d\n", current->PinCount, 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");
+                }
+            }
+#else
             ASSERT(Refs == 0);
+#endif
         }
 
         OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
@@ -1445,6 +1474,7 @@ ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[])
         ULONG Valid = 0, Dirty = 0;
         PROS_SHARED_CACHE_MAP SharedCacheMap;
         PUNICODE_STRING FileName;
+        PWSTR Extra = L"";
 
         SharedCacheMap = CONTAINING_RECORD(ListEntry, ROS_SHARED_CACHE_MAP, SharedCacheMapLinks);
 
@@ -1471,13 +1501,22 @@ ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[])
         {
             FileName = &SharedCacheMap->FileObject->FileName;
         }
+        else if (SharedCacheMap->FileObject != NULL &&
+                 SharedCacheMap->FileObject->FsContext != NULL &&
+                 ((PFSRTL_COMMON_FCB_HEADER)(SharedCacheMap->FileObject->FsContext))->NodeTypeCode == 0x0502 &&
+                 ((PFSRTL_COMMON_FCB_HEADER)(SharedCacheMap->FileObject->FsContext))->NodeByteSize == 0x1F8 &&
+                 ((PUNICODE_STRING)(((PUCHAR)SharedCacheMap->FileObject->FsContext) + 0x100))->Length != 0)
+        {
+            FileName = (PUNICODE_STRING)(((PUCHAR)SharedCacheMap->FileObject->FsContext) + 0x100);
+            Extra = L" (FastFAT)";
+        }
         else
         {
             FileName = &NoName;
         }
 
         /* And print */
-        KdbpPrint("%p\t%d\t%d\t%wZ\n", SharedCacheMap, Valid, Dirty, FileName);
+        KdbpPrint("%p\t%d\t%d\t%wZ%S\n", SharedCacheMap, Valid, Dirty, FileName, Extra);
     }
 
     return TRUE;