[NTOSKRNL]

- Fix inconsistent locking

svn path=/trunk/; revision=54746
This commit is contained in:
Cameron Gutman 2011-12-24 03:57:10 +00:00
parent ed15dc5d11
commit 6ababb3a3f

View file

@ -398,7 +398,7 @@ CcRosReleaseCacheSegment(PBCB Bcb,
BOOLEAN Dirty, BOOLEAN Dirty,
BOOLEAN Mapped) BOOLEAN Mapped)
{ {
BOOLEAN WasDirty = CacheSeg->Dirty; BOOLEAN WasDirty;
KIRQL oldIrql; KIRQL oldIrql;
ASSERT(Bcb); ASSERT(Bcb);
@ -406,10 +406,14 @@ CcRosReleaseCacheSegment(PBCB Bcb,
DPRINT("CcReleaseCacheSegment(Bcb 0x%p, CacheSeg 0x%p, Valid %d)\n", DPRINT("CcReleaseCacheSegment(Bcb 0x%p, CacheSeg 0x%p, Valid %d)\n",
Bcb, CacheSeg, Valid); Bcb, CacheSeg, Valid);
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
CacheSeg->Valid = Valid; CacheSeg->Valid = Valid;
WasDirty = CacheSeg->Dirty;
CacheSeg->Dirty = CacheSeg->Dirty || Dirty; CacheSeg->Dirty = CacheSeg->Dirty || Dirty;
KeAcquireGuardedMutex(&ViewLock);
if (!WasDirty && CacheSeg->Dirty) if (!WasDirty && CacheSeg->Dirty)
{ {
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
@ -420,7 +424,6 @@ CcRosReleaseCacheSegment(PBCB Bcb,
{ {
CacheSeg->MappedCount++; CacheSeg->MappedCount++;
} }
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
CcRosCacheSegmentDecRefCount(CacheSeg); CcRosCacheSegmentDecRefCount(CacheSeg);
if (Mapped && CacheSeg->MappedCount == 1) if (Mapped && CacheSeg->MappedCount == 1)
{ {
@ -430,6 +433,7 @@ CcRosReleaseCacheSegment(PBCB Bcb,
{ {
CcRosCacheSegmentIncRefCount(CacheSeg); CcRosCacheSegmentIncRefCount(CacheSeg);
} }
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock); KeReleaseGuardedMutex(&ViewLock);
KeReleaseMutex(&CacheSeg->Mutex, 0); KeReleaseMutex(&CacheSeg->Mutex, 0);
@ -450,7 +454,9 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
DPRINT("CcRosLookupCacheSegment(Bcb -x%p, FileOffset %d)\n", Bcb, FileOffset); DPRINT("CcRosLookupCacheSegment(Bcb -x%p, FileOffset %d)\n", Bcb, FileOffset);
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
current_entry = Bcb->BcbSegmentListHead.Flink; current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead) while (current_entry != &Bcb->BcbSegmentListHead)
{ {
@ -461,6 +467,7 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
{ {
CcRosCacheSegmentIncRefCount(current); CcRosCacheSegmentIncRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
KeWaitForSingleObject(&current->Mutex, KeWaitForSingleObject(&current->Mutex,
Executive, Executive,
KernelMode, KernelMode,
@ -470,7 +477,10 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
} }
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
} }
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
return(NULL); return(NULL);
} }
@ -490,29 +500,28 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset)
{ {
KeBugCheck(CACHE_MANAGER); KeBugCheck(CACHE_MANAGER);
} }
if (!CacheSeg->Dirty)
{
KeAcquireGuardedMutex(&ViewLock);
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE;
KeReleaseGuardedMutex(&ViewLock);
}
else
{
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
CcRosCacheSegmentDecRefCount(CacheSeg);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
}
KeAcquireGuardedMutex(&ViewLock); KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
if (!CacheSeg->Dirty)
{
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE;
}
else
{
CcRosCacheSegmentDecRefCount(CacheSeg);
}
/* Move to the tail of the LRU list */ /* Move to the tail of the LRU list */
RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry); RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry);
InsertTailList(&CacheSegmentLRUListHead, &CacheSeg->CacheSegmentLRUListEntry); InsertTailList(&CacheSegmentLRUListHead, &CacheSeg->CacheSegmentLRUListEntry);
KeReleaseGuardedMutex(&ViewLock);
CacheSeg->Dirty = TRUE; CacheSeg->Dirty = TRUE;
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
KeReleaseMutex(&CacheSeg->Mutex, 0); KeReleaseMutex(&CacheSeg->Mutex, 0);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -537,6 +546,9 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
WasDirty = CacheSeg->Dirty; WasDirty = CacheSeg->Dirty;
CacheSeg->Dirty = CacheSeg->Dirty || NowDirty; CacheSeg->Dirty = CacheSeg->Dirty || NowDirty;
@ -544,13 +556,10 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
if (!WasDirty && NowDirty) if (!WasDirty && NowDirty)
{ {
KeAcquireGuardedMutex(&ViewLock);
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE;
KeReleaseGuardedMutex(&ViewLock);
} }
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
CcRosCacheSegmentDecRefCount(CacheSeg); CcRosCacheSegmentDecRefCount(CacheSeg);
if (!WasDirty && NowDirty) if (!WasDirty && NowDirty)
{ {
@ -560,8 +569,9 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
{ {
CcRosCacheSegmentDecRefCount(CacheSeg); CcRosCacheSegmentDecRefCount(CacheSeg);
} }
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
KeReleaseMutex(&CacheSeg->Mutex, 0); KeReleaseMutex(&CacheSeg->Mutex, 0);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -1039,9 +1049,12 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
} }
} }
KeReleaseMutex(&current->Mutex, 0); KeReleaseMutex(&current->Mutex, 0);
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
CcRosCacheSegmentDecRefCount(current); CcRosCacheSegmentDecRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
} }
Offset.QuadPart += Bcb->CacheSegmentSize; Offset.QuadPart += Bcb->CacheSegmentSize;