file, line, vacb, Refs, vacb->Dirty, vacb->PageOut);
}
+ if (Refs == 0)
+ {
+ CcRosInternalFreeVacb(vacb);
+ }
+
return Refs;
}
ULONG CcRosVacbGetRefCount_(PROS_VACB vacb, PCSTR file, INT line)
}
#endif
-NTSTATUS
-CcRosInternalFreeVacb(PROS_VACB Vacb);
-
/* FUNCTIONS *****************************************************************/
PROS_VACB current;
BOOLEAN Locked;
NTSTATUS Status;
- LARGE_INTEGER ZeroTimeout;
DPRINT("CcRosFlushDirtyPages(Target %lu)\n", Target);
(*Count) = 0;
- ZeroTimeout.QuadPart = 0;
KeEnterCriticalRegion();
KeAcquireGuardedMutex(&ViewLock);
while ((current_entry != &DirtyVacbListHead) && (Target > 0))
{
+ ULONG Refs;
+
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
DirtyVacbListEntry);
continue;
}
- Status = CcRosAcquireVacbLock(current,
- Wait ? NULL : &ZeroTimeout);
- if (Status != STATUS_SUCCESS)
- {
- current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
- current->SharedCacheMap->LazyWriteContext);
- CcRosVacbDecRefCount(current);
- continue;
- }
-
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))
{
- CcRosReleaseVacbLock(current);
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
current->SharedCacheMap->LazyWriteContext);
CcRosVacbDecRefCount(current);
Status = CcRosFlushVacb(current);
- CcRosReleaseVacbLock(current);
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
current->SharedCacheMap->LazyWriteContext);
CcRosVacbIncRefCount(current);
/* Check if it's mapped and not dirty */
- if (current->MappedCount > 0 && !current->Dirty)
+ if (InterlockedCompareExchange((PLONG)¤t->MappedCount, 0, 0) > 0 && !current->Dirty)
{
/* We have to break these locks because Cc sucks */
KeReleaseSpinLock(¤t->SharedCacheMap->CacheMapLock, oldIrql);
while (!IsListEmpty(&FreeList))
{
+ ULONG Refs;
+
current_entry = RemoveHeadList(&FreeList);
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
CacheMapVacbListEntry);
InitializeListHead(¤t->CacheMapVacbListEntry);
- CcRosVacbDecRefCount(current);
- CcRosInternalFreeVacb(current);
+ Refs = CcRosVacbDecRefCount(current);
+ ASSERT(Refs == 0);
}
DPRINT("Evicted %lu cache pages\n", (*NrFreed));
if (Mapped)
{
- Vacb->MappedCount++;
- }
- Refs = CcRosVacbDecRefCount(Vacb);
- if (Mapped && (Vacb->MappedCount == 1))
- {
- CcRosVacbIncRefCount(Vacb);
+ if (InterlockedIncrement((PLONG)&Vacb->MappedCount) == 1)
+ {
+ CcRosVacbIncRefCount(Vacb);
+ }
}
+ Refs = CcRosVacbDecRefCount(Vacb);
ASSERT(Refs > 0);
- CcRosReleaseVacbLock(Vacb);
-
return STATUS_SUCCESS;
}
CcRosVacbIncRefCount(current);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
- CcRosAcquireVacbLock(current, NULL);
return current;
}
if (current->FileOffset.QuadPart > FileOffset)
}
ASSERT(Vacb->MappedCount != 0);
- Vacb->MappedCount--;
-
- if (Vacb->MappedCount == 0)
+ if (InterlockedDecrement((PLONG)&Vacb->MappedCount) == 0)
{
CcRosVacbDecRefCount(Vacb);
}
PLIST_ENTRY current_entry;
NTSTATUS Status;
KIRQL oldIrql;
+ ULONG Refs;
ASSERT(SharedCacheMap);
current->MappedCount = 0;
current->ReferenceCount = 0;
current->PinCount = 0;
- KeInitializeMutex(¤t->Mutex, 0);
InitializeListHead(¤t->CacheMapVacbListEntry);
InitializeListHead(¤t->DirtyVacbListEntry);
InitializeListHead(¤t->VacbLruListEntry);
return Status;
}
- CcRosAcquireVacbLock(current, NULL);
KeAcquireGuardedMutex(&ViewLock);
*Vacb = current;
current);
}
#endif
- CcRosVacbDecRefCount(*Vacb);
- CcRosReleaseVacbLock(*Vacb);
KeReleaseGuardedMutex(&ViewLock);
- CcRosInternalFreeVacb(*Vacb);
+
+ Refs = CcRosVacbDecRefCount(*Vacb);
+ ASSERT(Refs == 0);
+
*Vacb = current;
- CcRosAcquireVacbLock(current, NULL);
return STATUS_SUCCESS;
}
if (current->FileOffset.QuadPart < FileOffset)
ASSERT(IsListEmpty(&Vacb->CacheMapVacbListEntry));
ASSERT(IsListEmpty(&Vacb->DirtyVacbListEntry));
ASSERT(IsListEmpty(&Vacb->VacbLruListEntry));
- RtlFillMemory(Vacb, sizeof(Vacb), 0xfd);
+ RtlFillMemory(Vacb, sizeof(*Vacb), 0xfd);
ExFreeToNPagedLookasideList(&VacbLookasideList, Vacb);
return STATUS_SUCCESS;
}
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
- CcRosAcquireVacbLock(current, NULL);
RemoveEntryList(¤t->VacbLruListEntry);
InitializeListHead(¤t->VacbLruListEntry);
if (current->Dirty)
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
DPRINT1("Freeing dirty VACB\n");
}
+ if (current->MappedCount != 0)
+ {
+ current->MappedCount = 0;
+ NT_VERIFY(CcRosVacbDecRefCount(current) > 0);
+ DPRINT1("Freeing mapped VACB\n");
+ }
InsertHeadList(&FreeList, ¤t->CacheMapVacbListEntry);
- CcRosReleaseVacbLock(current);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
}
while (!IsListEmpty(&FreeList))
{
+ ULONG Refs;
+
current_entry = RemoveTailList(&FreeList);
current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
InitializeListHead(¤t->CacheMapVacbListEntry);
- CcRosVacbDecRefCount(current);
- CcRosInternalFreeVacb(current);
+ 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);
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);
{
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;