return TRUE;
}
+static
+VOID
+CcpDereferenceBcb(
+ IN PROS_SHARED_CACHE_MAP SharedCacheMap,
+ IN PINTERNAL_BCB Bcb)
+{
+ ULONG RefCount;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
+ RefCount = --Bcb->RefCount;
+ if (RefCount == 0)
+ {
+ RemoveEntryList(&Bcb->BcbEntry);
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
+
+ ASSERT(Bcb->PinCount == 0);
+ CcRosReleaseVacb(SharedCacheMap,
+ Bcb->Vacb,
+ TRUE,
+ Bcb->Dirty,
+ FALSE);
+
+ ExDeleteResourceLite(&Bcb->Lock);
+ ExFreeToNPagedLookasideList(&iBcbLookasideList, Bcb);
+ }
+ else
+ {
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
+ }
+}
+
static
PVOID
CcpGetAppropriateBcb(
/* Yes, and we've lost */
if (DupBcb != NULL)
{
+ /* We will return that BCB */
+ ++DupBcb->RefCount;
Result = TRUE;
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
if (ToPin)
{
- DupBcb->PinCount++;
-
if (BooleanFlagOn(PinFlags, PIN_EXCLUSIVE))
{
Result = ExAcquireResourceExclusiveLite(&iBcb->Lock, BooleanFlagOn(PinFlags, PIN_WAIT));
Result = ExAcquireSharedStarveExclusive(&iBcb->Lock, BooleanFlagOn(PinFlags, PIN_WAIT));
}
- if (!Result)
+ if (Result)
+ {
+ DupBcb->PinCount++;
+ }
+ else
{
- DupBcb->PinCount--;
+ CcpDereferenceBcb(SharedCacheMap, DupBcb);
DupBcb = NULL;
}
}
- if (Result)
+ if (DupBcb != NULL)
{
- /* We'll return that BCB */
- ++DupBcb->RefCount;
+ /* Delete the loser */
+ CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
+ ExDeleteResourceLite(&iBcb->Lock);
+ ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
}
- /* Delete the loser */
- CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
- ExDeleteResourceLite(&iBcb->Lock);
- ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
-
/* Return the winner - no need to update buffer address, it's
* relative to the VACB, which is unchanged.
*/
}
InsertTailList(&SharedCacheMap->BcbList, &iBcb->BcbEntry);
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
}
- KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
return iBcb;
}
KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
NewBcb = CcpFindBcb(SharedCacheMap, FileOffset, Length, TRUE);
- KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
if (NewBcb != NULL)
{
- NewBcb->PinCount++;
+ ++NewBcb->RefCount;
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
if (BooleanFlagOn(Flags, PIN_EXCLUSIVE))
{
if (!Result)
{
- NewBcb->PinCount--;
+ CcpDereferenceBcb(SharedCacheMap, NewBcb);
+ NewBcb = NULL;
}
else
{
- NewBcb->RefCount++;
+ NewBcb->PinCount++;
*Bcb = NewBcb;
*Buffer = (PUCHAR)NewBcb->Vacb->BaseAddress + FileOffset->QuadPart % VACB_MAPPING_GRANULARITY;
}
}
else
{
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
+
if (BooleanFlagOn(Flags, PIN_IF_BCB))
{
return FALSE;
KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
iBcb = CcpFindBcb(SharedCacheMap, FileOffset, Length, FALSE);
- KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
if (iBcb == NULL)
{
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
+
Ret = CcpMapData(SharedCacheMap, FileOffset, Length, Flags, &Vacb, pBuffer);
if (Ret)
{
else
{
++iBcb->RefCount;
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
+
*pBcb = iBcb;
*pBuffer = (PUCHAR)iBcb->Vacb->BaseAddress + FileOffset->QuadPart % VACB_MAPPING_GRANULARITY;
Ret = TRUE;
IN ERESOURCE_THREAD ResourceThreadId)
{
PINTERNAL_BCB iBcb = Bcb;
+ PROS_SHARED_CACHE_MAP SharedCacheMap;
CCTRACE(CC_API_DEBUG, "Bcb=%p ResourceThreadId=%lu\n", Bcb, ResourceThreadId);
iBcb->PinCount--;
}
- if (--iBcb->RefCount == 0)
- {
- KIRQL OldIrql;
- PROS_SHARED_CACHE_MAP SharedCacheMap;
-
- ASSERT(iBcb->PinCount == 0);
- SharedCacheMap = iBcb->Vacb->SharedCacheMap;
- CcRosReleaseVacb(SharedCacheMap,
- iBcb->Vacb,
- TRUE,
- iBcb->Dirty,
- FALSE);
-
- KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
- if (!IsListEmpty(&iBcb->BcbEntry))
- {
- RemoveEntryList(&iBcb->BcbEntry);
- }
- KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
-
- ExDeleteResourceLite(&iBcb->Lock);
- ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
- }
+ SharedCacheMap = iBcb->Vacb->SharedCacheMap;
+ CcpDereferenceBcb(SharedCacheMap, iBcb);
}
/*
CCTRACE(CC_API_DEBUG, "Bcb=%p WriteThrough=%d\n", Bcb, WriteThrough);
+ SharedCacheMap = iBcb->Vacb->SharedCacheMap;
IoStatus->Status = STATUS_SUCCESS;
+
+ KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
if (--iBcb->RefCount == 0)
{
+ RemoveEntryList(&iBcb->BcbEntry);
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
+
IoStatus->Information = 0;
if (WriteThrough)
{
ASSERT(iBcb->PinCount == 0);
}
- SharedCacheMap = iBcb->Vacb->SharedCacheMap;
CcRosReleaseVacb(iBcb->Vacb->SharedCacheMap,
iBcb->Vacb,
TRUE,
iBcb->Dirty,
FALSE);
- KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
- if (!IsListEmpty(&iBcb->BcbEntry))
- {
- RemoveEntryList(&iBcb->BcbEntry);
- }
- KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
-
ExDeleteResourceLite(&iBcb->Lock);
ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
}
+ else
+ {
+ KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
+ }
}