LIST_ENTRY CcCleanSharedCacheMapList;
#if DBG
-static void CcRosVacbIncRefCount_(PROS_VACB vacb, const char* file, int line)
+VOID CcRosVacbIncRefCount_(PROS_VACB vacb, PCSTR file, INT line)
{
++vacb->ReferenceCount;
if (vacb->SharedCacheMap->Trace)
file, line, vacb, vacb->ReferenceCount, vacb->Dirty, vacb->PageOut);
}
}
-static void CcRosVacbDecRefCount_(PROS_VACB vacb, const char* file, int line)
+VOID CcRosVacbDecRefCount_(PROS_VACB vacb, PCSTR file, INT line)
{
ASSERT(vacb->ReferenceCount != 0);
--vacb->ReferenceCount;
file, line, vacb, vacb->ReferenceCount, vacb->Dirty, vacb->PageOut);
}
}
-#define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
-#define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
-#else
-#define CcRosVacbIncRefCount(vacb) (++((vacb)->ReferenceCount))
-#define CcRosVacbDecRefCount(vacb) (--((vacb)->ReferenceCount))
#endif
NTSTATUS
CcRosVacbDecRefCount(current);
/* Check if we can free this entry now */
- if (current->ReferenceCount == 0)
+ if (current->ReferenceCount < 2)
{
ASSERT(!current->Dirty);
ASSERT(!current->MappedCount);
+ ASSERT(current->ReferenceCount == 1);
RemoveEntryList(¤t->CacheMapVacbListEntry);
RemoveEntryList(¤t->VacbLruListEntry);
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
CacheMapVacbListEntry);
+ CcRosVacbDecRefCount(current);
CcRosInternalFreeVacb(current);
}
CcRosVacbIncRefCount(Vacb);
}
+ ASSERT(Vacb->ReferenceCount > 0);
+
CcRosReleaseVacbLock(Vacb);
return STATUS_SUCCESS;
KeBugCheck(CACHE_MANAGER);
}
- if (!Vacb->Dirty)
- {
- CcRosMarkDirtyVacb(Vacb);
- }
-
- CcRosReleaseVacbLock(Vacb);
+ CcRosReleaseVacb(SharedCacheMap, Vacb, Vacb->Valid, TRUE, FALSE);
return STATUS_SUCCESS;
}
+/*
+ * Note: this is not the contrary function of
+ * CcRosMapVacbInKernelSpace()
+ */
NTSTATUS
NTAPI
CcRosUnmapVacb (
return STATUS_UNSUCCESSFUL;
}
- if (NowDirty && !Vacb->Dirty)
- {
- CcRosMarkDirtyVacb(Vacb);
- }
-
ASSERT(Vacb->MappedCount != 0);
Vacb->MappedCount--;
- CcRosVacbDecRefCount(Vacb);
if (Vacb->MappedCount == 0)
{
CcRosVacbDecRefCount(Vacb);
}
- CcRosReleaseVacbLock(Vacb);
+ CcRosReleaseVacb(SharedCacheMap, Vacb, Vacb->Valid, NowDirty, FALSE);
return STATUS_SUCCESS;
}
static
NTSTATUS
-CcRosMapVacb(
+CcRosMapVacbInKernelSpace(
PROS_VACB Vacb)
{
ULONG i;
current->MappedCount = 0;
current->DirtyVacbListEntry.Flink = NULL;
current->DirtyVacbListEntry.Blink = NULL;
- current->ReferenceCount = 1;
+ current->ReferenceCount = 0;
current->PinCount = 0;
KeInitializeMutex(¤t->Mutex, 0);
CcRosAcquireVacbLock(current, NULL);
}
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
InsertTailList(&VacbLruListHead, ¤t->VacbLruListEntry);
+ CcRosVacbIncRefCount(current);
KeReleaseGuardedMutex(&ViewLock);
MI_SET_USAGE(MI_USAGE_CACHE);
}
#endif
- Status = CcRosMapVacb(current);
+ Status = CcRosMapVacbInKernelSpace(current);
if (!NT_SUCCESS(Status))
{
RemoveEntryList(¤t->CacheMapVacbListEntry);
ExFreeToNPagedLookasideList(&VacbLookasideList, current);
}
+ /* Reference it to allow release */
+ CcRosVacbIncRefCount(current);
+
return Status;
}
DPRINT("*BaseAddress %p\n", *BaseAddress);
*Vacb = current;
*BaseOffset = current->FileOffset.QuadPart;
+
+ ASSERT(current->ReferenceCount > 1);
+
return STATUS_SUCCESS;
}
NULL);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ if (Vacb->PinCount != 0 || Vacb->ReferenceCount != 0)
+ {
+ DPRINT1("Invalid free: %ld, %ld\n", Vacb->ReferenceCount, Vacb->PinCount);
+ if (Vacb->SharedCacheMap->FileObject && Vacb->SharedCacheMap->FileObject->FileName.Length)
+ {
+ DPRINT1("For file: %wZ\n", &Vacb->SharedCacheMap->FileObject->FileName);
+ }
+ }
+
+ ASSERT(Vacb->PinCount == 0);
+ ASSERT(Vacb->ReferenceCount == 0);
ExFreeToNPagedLookasideList(&VacbLookasideList, Vacb);
return STATUS_SUCCESS;
}
LONGLONG RemainingLength;
PROS_VACB current;
NTSTATUS Status;
- KIRQL oldIrql;
CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p FileOffset=%p Length=%lu\n",
SectionObjectPointers, FileOffset, Length);
}
}
- CcRosReleaseVacbLock(current);
-
- KeAcquireGuardedMutex(&ViewLock);
- KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
- CcRosVacbDecRefCount(current);
- KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
- KeReleaseGuardedMutex(&ViewLock);
+ CcRosReleaseVacb(SharedCacheMap, current, current->Valid, current->Dirty, FALSE);
}
Offset.QuadPart += VACB_MAPPING_GRANULARITY;
{
current_entry = RemoveTailList(&FreeList);
current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
+ CcRosVacbDecRefCount(current);
CcRosInternalFreeVacb(current);
}
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, OldIrql);
/* And free it. */
- ExFreePoolWithTag(PrivateMap, TAG_PRIVATE_CACHE_MAP);
+ if (PrivateMap != &SharedCacheMap->PrivateCacheMap)
+ {
+ ExFreePoolWithTag(PrivateMap, TAG_PRIVATE_CACHE_MAP);
+ }
+ else
+ {
+ PrivateMap->NodeTypeCode = 0;
+ }
if (SharedCacheMap->OpenCount > 0)
{
PPRIVATE_CACHE_MAP PrivateMap;
/* Allocate the private cache map for this handle */
- PrivateMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(PRIVATE_CACHE_MAP), TAG_PRIVATE_CACHE_MAP);
+ if (SharedCacheMap->PrivateCacheMap.NodeTypeCode != 0)
+ {
+ PrivateMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(PRIVATE_CACHE_MAP), TAG_PRIVATE_CACHE_MAP);
+ }
+ else
+ {
+ PrivateMap = &SharedCacheMap->PrivateCacheMap;
+ }
+
if (PrivateMap == NULL)
{
/* If we also allocated the shared cache map for this file, kill it */
(CcDirtyPageThreshold * PAGE_SIZE) / 1024);
KdbpPrint("MmAvailablePages:\t%lu (%lu Kb)\n", MmAvailablePages,
(MmAvailablePages * PAGE_SIZE) / 1024);
+ KdbpPrint("MmThrottleTop:\t\t%lu (%lu Kb)\n", MmThrottleTop,
+ (MmThrottleTop * PAGE_SIZE) / 1024);
+ KdbpPrint("MmThrottleBottom:\t%lu (%lu Kb)\n", MmThrottleBottom,
+ (MmThrottleBottom * PAGE_SIZE) / 1024);
+ KdbpPrint("MmModifiedPageListHead.Total:\t%lu (%lu Kb)\n", MmModifiedPageListHead.Total,
+ (MmModifiedPageListHead.Total * PAGE_SIZE) / 1024);
if (CcTotalDirtyPages >= CcDirtyPageThreshold)
{