[NTOSKRNL] Drop the ViewLock mutex in favour of the master spin lock

This will allow Cc calls during DPC, which is required by MS FastFAT

CORE-11819
This commit is contained in:
Pierre Schweitzer 2018-12-19 22:49:48 +01:00
parent b67dbdbea5
commit 4f8b041bf0
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
2 changed files with 101 additions and 94 deletions

View file

@ -15,8 +15,6 @@
/* GLOBALS *****************************************************************/ /* GLOBALS *****************************************************************/
extern KGUARDED_MUTEX ViewLock;
NTSTATUS CcRosInternalFreeVacb(PROS_VACB Vacb); NTSTATUS CcRosInternalFreeVacb(PROS_VACB Vacb);
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -115,12 +113,13 @@ CcIsThereDirtyData (
{ {
PROS_VACB Vacb; PROS_VACB Vacb;
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
KIRQL oldIrql;
/* Assume no dirty data */ /* Assume no dirty data */
BOOLEAN Dirty = FALSE; BOOLEAN Dirty = FALSE;
CCTRACE(CC_API_DEBUG, "Vpb=%p\n", Vpb); CCTRACE(CC_API_DEBUG, "Vpb=%p\n", Vpb);
KeAcquireGuardedMutex(&ViewLock); oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
/* Browse dirty VACBs */ /* Browse dirty VACBs */
for (Entry = DirtyVacbListHead.Flink; Entry != &DirtyVacbListHead; Entry = Entry->Flink) for (Entry = DirtyVacbListHead.Flink; Entry != &DirtyVacbListHead; Entry = Entry->Flink)
@ -148,7 +147,7 @@ CcIsThereDirtyData (
} }
} }
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
return Dirty; return Dirty;
} }
@ -202,8 +201,8 @@ CcPurgeCacheSection (
/* Assume success */ /* Assume success */
Success = TRUE; Success = TRUE;
KeAcquireGuardedMutex(&ViewLock); OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &OldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
ListEntry = SharedCacheMap->CacheMapVacbListHead.Flink; ListEntry = SharedCacheMap->CacheMapVacbListHead.Flink;
while (ListEntry != &SharedCacheMap->CacheMapVacbListHead) while (ListEntry != &SharedCacheMap->CacheMapVacbListHead)
{ {
@ -246,8 +245,8 @@ CcPurgeCacheSection (
RemoveEntryList(&Vacb->CacheMapVacbListEntry); RemoveEntryList(&Vacb->CacheMapVacbListEntry);
InsertHeadList(&FreeList, &Vacb->CacheMapVacbListEntry); InsertHeadList(&FreeList, &Vacb->CacheMapVacbListEntry);
} }
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, OldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
while (!IsListEmpty(&FreeList)) while (!IsListEmpty(&FreeList))
{ {

View file

@ -45,8 +45,6 @@
LIST_ENTRY DirtyVacbListHead; LIST_ENTRY DirtyVacbListHead;
static LIST_ENTRY VacbLruListHead; static LIST_ENTRY VacbLruListHead;
KGUARDED_MUTEX ViewLock;
NPAGED_LOOKASIDE_LIST iBcbLookasideList; NPAGED_LOOKASIDE_LIST iBcbLookasideList;
static NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList; static NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList;
static NPAGED_LOOKASIDE_LIST VacbLookasideList; static NPAGED_LOOKASIDE_LIST VacbLookasideList;
@ -135,8 +133,8 @@ CcRosTraceCacheMap (
{ {
DPRINT1("Enabling Tracing for CacheMap 0x%p:\n", SharedCacheMap); DPRINT1("Enabling Tracing for CacheMap 0x%p:\n", SharedCacheMap);
KeAcquireGuardedMutex(&ViewLock); oldirql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
current_entry = SharedCacheMap->CacheMapVacbListHead.Flink; current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
while (current_entry != &SharedCacheMap->CacheMapVacbListHead) while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
@ -147,8 +145,9 @@ CcRosTraceCacheMap (
DPRINT1(" VACB 0x%p enabled, RefCount %lu, Dirty %u, PageOut %lu\n", DPRINT1(" VACB 0x%p enabled, RefCount %lu, Dirty %u, PageOut %lu\n",
current, current->ReferenceCount, current->Dirty, current->PageOut ); current, current->ReferenceCount, current->Dirty, current->PageOut );
} }
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldirql);
KeReleaseGuardedMutex(&ViewLock); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
KeReleaseQueuedSpinLock(LockQueueMasterLock, oldirql);
} }
else else
{ {
@ -191,13 +190,14 @@ CcRosFlushDirtyPages (
PROS_VACB current; PROS_VACB current;
BOOLEAN Locked; BOOLEAN Locked;
NTSTATUS Status; NTSTATUS Status;
KIRQL OldIrql;
DPRINT("CcRosFlushDirtyPages(Target %lu)\n", Target); DPRINT("CcRosFlushDirtyPages(Target %lu)\n", Target);
(*Count) = 0; (*Count) = 0;
KeEnterCriticalRegion(); KeEnterCriticalRegion();
KeAcquireGuardedMutex(&ViewLock); OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
current_entry = DirtyVacbListHead.Flink; current_entry = DirtyVacbListHead.Flink;
if (current_entry == &DirtyVacbListHead) if (current_entry == &DirtyVacbListHead)
@ -232,14 +232,14 @@ CcRosFlushDirtyPages (
ASSERT(current->Dirty); ASSERT(current->Dirty);
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
Status = CcRosFlushVacb(current); Status = CcRosFlushVacb(current);
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite( current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
current->SharedCacheMap->LazyWriteContext); current->SharedCacheMap->LazyWriteContext);
KeAcquireGuardedMutex(&ViewLock); OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
CcRosVacbDecRefCount(current); CcRosVacbDecRefCount(current);
if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE) && if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE) &&
@ -270,7 +270,7 @@ CcRosFlushDirtyPages (
current_entry = DirtyVacbListHead.Flink; current_entry = DirtyVacbListHead.Flink;
} }
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
DPRINT("CcRosFlushDirtyPages() finished\n"); DPRINT("CcRosFlushDirtyPages() finished\n");
@ -307,7 +307,7 @@ CcRosTrimCache (
*NrFreed = 0; *NrFreed = 0;
retry: retry:
KeAcquireGuardedMutex(&ViewLock); oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
current_entry = VacbLruListHead.Flink; current_entry = VacbLruListHead.Flink;
while (current_entry != &VacbLruListHead) while (current_entry != &VacbLruListHead)
@ -319,7 +319,7 @@ retry:
VacbLruListEntry); VacbLruListEntry);
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
KeAcquireSpinLock(&current->SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&current->SharedCacheMap->CacheMapLock);
/* Reference the VACB */ /* Reference the VACB */
CcRosVacbIncRefCount(current); CcRosVacbIncRefCount(current);
@ -328,8 +328,8 @@ retry:
if (InterlockedCompareExchange((PLONG)&current->MappedCount, 0, 0) > 0 && !current->Dirty) if (InterlockedCompareExchange((PLONG)&current->MappedCount, 0, 0) > 0 && !current->Dirty)
{ {
/* We have to break these locks because Cc sucks */ /* We have to break these locks because Cc sucks */
KeReleaseSpinLock(&current->SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&current->SharedCacheMap->CacheMapLock);
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
/* Page out the VACB */ /* Page out the VACB */
for (i = 0; i < VACB_MAPPING_GRANULARITY / PAGE_SIZE; i++) for (i = 0; i < VACB_MAPPING_GRANULARITY / PAGE_SIZE; i++)
@ -340,8 +340,8 @@ retry:
} }
/* Reacquire the locks */ /* Reacquire the locks */
KeAcquireGuardedMutex(&ViewLock); oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
KeAcquireSpinLock(&current->SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&current->SharedCacheMap->CacheMapLock);
} }
/* Dereference the VACB */ /* Dereference the VACB */
@ -365,10 +365,10 @@ retry:
(*NrFreed) += PagesFreed; (*NrFreed) += PagesFreed;
} }
KeReleaseSpinLock(&current->SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&current->SharedCacheMap->CacheMapLock);
} }
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
/* Try flushing pages if we haven't met our target */ /* Try flushing pages if we haven't met our target */
if ((Target > 0) && !FlushedPages) if ((Target > 0) && !FlushedPages)
@ -459,8 +459,8 @@ CcRosLookupVacb (
DPRINT("CcRosLookupVacb(SharedCacheMap 0x%p, FileOffset %I64u)\n", DPRINT("CcRosLookupVacb(SharedCacheMap 0x%p, FileOffset %I64u)\n",
SharedCacheMap, FileOffset); SharedCacheMap, FileOffset);
KeAcquireGuardedMutex(&ViewLock); oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
current_entry = SharedCacheMap->CacheMapVacbListHead.Flink; current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
while (current_entry != &SharedCacheMap->CacheMapVacbListHead) while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
@ -473,8 +473,8 @@ CcRosLookupVacb (
FileOffset)) FileOffset))
{ {
CcRosVacbIncRefCount(current); CcRosVacbIncRefCount(current);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
return current; return current;
} }
if (current->FileOffset.QuadPart > FileOffset) if (current->FileOffset.QuadPart > FileOffset)
@ -482,8 +482,8 @@ CcRosLookupVacb (
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
} }
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
return NULL; return NULL;
} }
@ -498,8 +498,8 @@ CcRosMarkDirtyVacb (
SharedCacheMap = Vacb->SharedCacheMap; SharedCacheMap = Vacb->SharedCacheMap;
KeAcquireGuardedMutex(&ViewLock); oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
ASSERT(!Vacb->Dirty); ASSERT(!Vacb->Dirty);
@ -514,11 +514,9 @@ CcRosMarkDirtyVacb (
Vacb->Dirty = TRUE; Vacb->Dirty = TRUE;
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
KeReleaseGuardedMutex(&ViewLock);
/* Schedule a lazy writer run to now that we have dirty VACB */ /* Schedule a lazy writer run to now that we have dirty VACB */
oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
if (!LazyWriter.ScanActive) if (!LazyWriter.ScanActive)
{ {
CcScheduleLazyWriteScan(FALSE); CcScheduleLazyWriteScan(FALSE);
@ -539,8 +537,8 @@ CcRosUnmarkDirtyVacb (
if (LockViews) if (LockViews)
{ {
KeAcquireGuardedMutex(&ViewLock); oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
} }
ASSERT(Vacb->Dirty); ASSERT(Vacb->Dirty);
@ -555,8 +553,8 @@ CcRosUnmarkDirtyVacb (
if (LockViews) if (LockViews)
{ {
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
} }
} }
@ -702,7 +700,7 @@ CcRosFreeUnusedVacb (
Freed = FALSE; Freed = FALSE;
InitializeListHead(&FreeList); InitializeListHead(&FreeList);
KeAcquireGuardedMutex(&ViewLock); oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
/* Browse all the available VACB */ /* Browse all the available VACB */
current_entry = VacbLruListHead.Flink; current_entry = VacbLruListHead.Flink;
@ -715,7 +713,7 @@ CcRosFreeUnusedVacb (
VacbLruListEntry); VacbLruListEntry);
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
KeAcquireSpinLock(&current->SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&current->SharedCacheMap->CacheMapLock);
/* Only deal with unused VACB, we will free them */ /* Only deal with unused VACB, we will free them */
Refs = CcRosVacbGetRefCount(current); Refs = CcRosVacbGetRefCount(current);
@ -732,11 +730,11 @@ CcRosFreeUnusedVacb (
InsertHeadList(&FreeList, &current->CacheMapVacbListEntry); InsertHeadList(&FreeList, &current->CacheMapVacbListEntry);
} }
KeReleaseSpinLock(&current->SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&current->SharedCacheMap->CacheMapLock);
} }
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
/* And now, free any of the found VACB, that'll free memory! */ /* And now, free any of the found VACB, that'll free memory! */
while (!IsListEmpty(&FreeList)) while (!IsListEmpty(&FreeList))
@ -837,7 +835,7 @@ Retry:
return Status; return Status;
} }
KeAcquireGuardedMutex(&ViewLock); oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
*Vacb = current; *Vacb = current;
/* There is window between the call to CcRosLookupVacb /* There is window between the call to CcRosLookupVacb
@ -845,7 +843,7 @@ Retry:
* file offset exist. If there is a VACB, we release * file offset exist. If there is a VACB, we release
* our newly created VACB and return the existing one. * our newly created VACB and return the existing one.
*/ */
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
current_entry = SharedCacheMap->CacheMapVacbListHead.Flink; current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
previous = NULL; previous = NULL;
while (current_entry != &SharedCacheMap->CacheMapVacbListHead) while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
@ -858,7 +856,7 @@ Retry:
FileOffset)) FileOffset))
{ {
CcRosVacbIncRefCount(current); CcRosVacbIncRefCount(current);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
#if DBG #if DBG
if (SharedCacheMap->Trace) if (SharedCacheMap->Trace)
{ {
@ -868,7 +866,7 @@ Retry:
current); current);
} }
#endif #endif
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
Refs = CcRosVacbDecRefCount(*Vacb); Refs = CcRosVacbDecRefCount(*Vacb);
ASSERT(Refs == 0); ASSERT(Refs == 0);
@ -896,9 +894,9 @@ Retry:
{ {
InsertHeadList(&SharedCacheMap->CacheMapVacbListHead, &current->CacheMapVacbListEntry); InsertHeadList(&SharedCacheMap->CacheMapVacbListHead, &current->CacheMapVacbListEntry);
} }
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
InsertTailList(&VacbLruListHead, &current->VacbLruListEntry); InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
MI_SET_USAGE(MI_USAGE_CACHE); MI_SET_USAGE(MI_USAGE_CACHE);
#if MI_TRACE_PFNS #if MI_TRACE_PFNS
@ -938,6 +936,7 @@ CcRosGetVacb (
PROS_VACB current; PROS_VACB current;
NTSTATUS Status; NTSTATUS Status;
ULONG Refs; ULONG Refs;
KIRQL OldIrql;
ASSERT(SharedCacheMap); ASSERT(SharedCacheMap);
@ -961,13 +960,13 @@ CcRosGetVacb (
Refs = CcRosVacbGetRefCount(current); Refs = CcRosVacbGetRefCount(current);
KeAcquireGuardedMutex(&ViewLock); OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
/* Move to the tail of the LRU list */ /* Move to the tail of the LRU list */
RemoveEntryList(&current->VacbLruListEntry); RemoveEntryList(&current->VacbLruListEntry);
InsertTailList(&VacbLruListHead, &current->VacbLruListEntry); InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
/* /*
* Return information about the VACB to the caller. * Return information about the VACB to the caller.
@ -1150,7 +1149,8 @@ NTSTATUS
NTAPI NTAPI
CcRosDeleteFileCache ( CcRosDeleteFileCache (
PFILE_OBJECT FileObject, PFILE_OBJECT FileObject,
PROS_SHARED_CACHE_MAP SharedCacheMap) PROS_SHARED_CACHE_MAP SharedCacheMap,
PKIRQL OldIrql)
/* /*
* FUNCTION: Releases the shared cache map associated with a file object * FUNCTION: Releases the shared cache map associated with a file object
*/ */
@ -1158,41 +1158,38 @@ CcRosDeleteFileCache (
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PROS_VACB current; PROS_VACB current;
LIST_ENTRY FreeList; LIST_ENTRY FreeList;
KIRQL oldIrql;
ASSERT(SharedCacheMap); ASSERT(SharedCacheMap);
SharedCacheMap->OpenCount++; SharedCacheMap->OpenCount++;
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, *OldIrql);
CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL); CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
KeAcquireGuardedMutex(&ViewLock); *OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
SharedCacheMap->OpenCount--; SharedCacheMap->OpenCount--;
if (SharedCacheMap->OpenCount == 0) if (SharedCacheMap->OpenCount == 0)
{ {
KIRQL OldIrql;
FileObject->SectionObjectPointer->SharedCacheMap = NULL; FileObject->SectionObjectPointer->SharedCacheMap = NULL;
/* /*
* Release all VACBs * Release all VACBs
*/ */
InitializeListHead(&FreeList); InitializeListHead(&FreeList);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
while (!IsListEmpty(&SharedCacheMap->CacheMapVacbListHead)) while (!IsListEmpty(&SharedCacheMap->CacheMapVacbListHead))
{ {
current_entry = RemoveTailList(&SharedCacheMap->CacheMapVacbListHead); current_entry = RemoveTailList(&SharedCacheMap->CacheMapVacbListHead);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry); current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
RemoveEntryList(&current->VacbLruListEntry); RemoveEntryList(&current->VacbLruListEntry);
InitializeListHead(&current->VacbLruListEntry); InitializeListHead(&current->VacbLruListEntry);
if (current->Dirty) if (current->Dirty)
{ {
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
CcRosUnmarkDirtyVacb(current, FALSE); CcRosUnmarkDirtyVacb(current, FALSE);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
DPRINT1("Freeing dirty VACB\n"); DPRINT1("Freeing dirty VACB\n");
} }
if (current->MappedCount != 0) if (current->MappedCount != 0)
@ -1203,14 +1200,14 @@ CcRosDeleteFileCache (
} }
InsertHeadList(&FreeList, &current->CacheMapVacbListEntry); InsertHeadList(&FreeList, &current->CacheMapVacbListEntry);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
} }
#if DBG #if DBG
SharedCacheMap->Trace = FALSE; SharedCacheMap->Trace = FALSE;
#endif #endif
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, *OldIrql);
ObDereferenceObject(SharedCacheMap->FileObject); ObDereferenceObject(SharedCacheMap->FileObject);
while (!IsListEmpty(&FreeList)) while (!IsListEmpty(&FreeList))
@ -1249,12 +1246,12 @@ CcRosDeleteFileCache (
#endif #endif
} }
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock); *OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks); RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql); KeReleaseQueuedSpinLock(LockQueueMasterLock, *OldIrql);
ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap); ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap);
KeAcquireGuardedMutex(&ViewLock); *OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1265,12 +1262,14 @@ CcRosReferenceCache (
PFILE_OBJECT FileObject) PFILE_OBJECT FileObject)
{ {
PROS_SHARED_CACHE_MAP SharedCacheMap; PROS_SHARED_CACHE_MAP SharedCacheMap;
KeAcquireGuardedMutex(&ViewLock); KIRQL OldIrql;
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
ASSERT(SharedCacheMap); ASSERT(SharedCacheMap);
ASSERT(SharedCacheMap->OpenCount != 0); ASSERT(SharedCacheMap->OpenCount != 0);
SharedCacheMap->OpenCount++; SharedCacheMap->OpenCount++;
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
} }
VOID VOID
@ -1279,14 +1278,16 @@ CcRosRemoveIfClosed (
PSECTION_OBJECT_POINTERS SectionObjectPointer) PSECTION_OBJECT_POINTERS SectionObjectPointer)
{ {
PROS_SHARED_CACHE_MAP SharedCacheMap; PROS_SHARED_CACHE_MAP SharedCacheMap;
KIRQL OldIrql;
DPRINT("CcRosRemoveIfClosed()\n"); DPRINT("CcRosRemoveIfClosed()\n");
KeAcquireGuardedMutex(&ViewLock); OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
SharedCacheMap = SectionObjectPointer->SharedCacheMap; SharedCacheMap = SectionObjectPointer->SharedCacheMap;
if (SharedCacheMap && SharedCacheMap->OpenCount == 0) if (SharedCacheMap && SharedCacheMap->OpenCount == 0)
{ {
CcRosDeleteFileCache(SharedCacheMap->FileObject, SharedCacheMap); CcRosDeleteFileCache(SharedCacheMap->FileObject, SharedCacheMap, &OldIrql);
} }
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
} }
@ -1296,7 +1297,9 @@ CcRosDereferenceCache (
PFILE_OBJECT FileObject) PFILE_OBJECT FileObject)
{ {
PROS_SHARED_CACHE_MAP SharedCacheMap; PROS_SHARED_CACHE_MAP SharedCacheMap;
KeAcquireGuardedMutex(&ViewLock); KIRQL OldIrql;
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
ASSERT(SharedCacheMap); ASSERT(SharedCacheMap);
if (SharedCacheMap->OpenCount > 0) if (SharedCacheMap->OpenCount > 0)
@ -1304,11 +1307,17 @@ CcRosDereferenceCache (
SharedCacheMap->OpenCount--; SharedCacheMap->OpenCount--;
if (SharedCacheMap->OpenCount == 0) if (SharedCacheMap->OpenCount == 0)
{ {
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
MmFreeSectionSegments(SharedCacheMap->FileObject); MmFreeSectionSegments(SharedCacheMap->FileObject);
CcRosDeleteFileCache(FileObject, SharedCacheMap);
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
CcRosDeleteFileCache(FileObject, SharedCacheMap, &OldIrql);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
return;
} }
} }
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
} }
NTSTATUS NTSTATUS
@ -1324,7 +1333,7 @@ CcRosReleaseFileCache (
PPRIVATE_CACHE_MAP PrivateMap; PPRIVATE_CACHE_MAP PrivateMap;
PROS_SHARED_CACHE_MAP SharedCacheMap; PROS_SHARED_CACHE_MAP SharedCacheMap;
KeAcquireGuardedMutex(&ViewLock); OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
if (FileObject->SectionObjectPointer->SharedCacheMap != NULL) if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
{ {
@ -1335,17 +1344,15 @@ CcRosReleaseFileCache (
* lock the master lock, to be sure not to race * lock the master lock, to be sure not to race
* with a potential read ahead ongoing! * with a potential read ahead ongoing!
*/ */
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
PrivateMap = FileObject->PrivateCacheMap; PrivateMap = FileObject->PrivateCacheMap;
FileObject->PrivateCacheMap = NULL; FileObject->PrivateCacheMap = NULL;
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
if (PrivateMap != NULL) if (PrivateMap != NULL)
{ {
/* Remove it from the file */ /* Remove it from the file */
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &OldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
RemoveEntryList(&PrivateMap->PrivateLinks); RemoveEntryList(&PrivateMap->PrivateLinks);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, OldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
/* And free it. */ /* And free it. */
if (PrivateMap != &SharedCacheMap->PrivateCacheMap) if (PrivateMap != &SharedCacheMap->PrivateCacheMap)
@ -1362,13 +1369,19 @@ CcRosReleaseFileCache (
SharedCacheMap->OpenCount--; SharedCacheMap->OpenCount--;
if (SharedCacheMap->OpenCount == 0) if (SharedCacheMap->OpenCount == 0)
{ {
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
MmFreeSectionSegments(SharedCacheMap->FileObject); MmFreeSectionSegments(SharedCacheMap->FileObject);
CcRosDeleteFileCache(FileObject, SharedCacheMap);
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
CcRosDeleteFileCache(FileObject, SharedCacheMap, &OldIrql);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
return STATUS_SUCCESS;
} }
} }
} }
} }
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1417,7 +1430,7 @@ CcRosInitializeFileCache (
InitializeListHead(&SharedCacheMap->BcbList); InitializeListHead(&SharedCacheMap->BcbList);
} }
KeAcquireGuardedMutex(&ViewLock); OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
if (Allocated) if (Allocated)
{ {
if (FileObject->SectionObjectPointer->SharedCacheMap == NULL) if (FileObject->SectionObjectPointer->SharedCacheMap == NULL)
@ -1428,9 +1441,7 @@ CcRosInitializeFileCache (
KernelMode); KernelMode);
FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap; FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap;
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
InsertTailList(&CcCleanSharedCacheMapList, &SharedCacheMap->SharedCacheMapLinks); InsertTailList(&CcCleanSharedCacheMapList, &SharedCacheMap->SharedCacheMapLinks);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
} }
else else
{ {
@ -1457,16 +1468,14 @@ CcRosInitializeFileCache (
/* If we also allocated the shared cache map for this file, kill it */ /* If we also allocated the shared cache map for this file, kill it */
if (Allocated) if (Allocated)
{ {
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks); RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
FileObject->SectionObjectPointer->SharedCacheMap = NULL; FileObject->SectionObjectPointer->SharedCacheMap = NULL;
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap); ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap);
} }
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
@ -1478,14 +1487,14 @@ CcRosInitializeFileCache (
KeInitializeSpinLock(&PrivateMap->ReadAheadSpinLock); KeInitializeSpinLock(&PrivateMap->ReadAheadSpinLock);
/* Link it to the file */ /* Link it to the file */
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &OldIrql); KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
InsertTailList(&SharedCacheMap->PrivateList, &PrivateMap->PrivateLinks); InsertTailList(&SharedCacheMap->PrivateList, &PrivateMap->PrivateLinks);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, OldIrql); KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
FileObject->PrivateCacheMap = PrivateMap; FileObject->PrivateCacheMap = PrivateMap;
SharedCacheMap->OpenCount++; SharedCacheMap->OpenCount++;
} }
KeReleaseGuardedMutex(&ViewLock); KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1524,7 +1533,6 @@ CcInitView (
InitializeListHead(&CcDeferredWrites); InitializeListHead(&CcDeferredWrites);
InitializeListHead(&CcCleanSharedCacheMapList); InitializeListHead(&CcCleanSharedCacheMapList);
KeInitializeSpinLock(&CcDeferredWriteSpinLock); KeInitializeSpinLock(&CcDeferredWriteSpinLock);
KeInitializeGuardedMutex(&ViewLock);
ExInitializeNPagedLookasideList(&iBcbLookasideList, ExInitializeNPagedLookasideList(&iBcbLookasideList,
NULL, NULL,
NULL, NULL,