Author: cgutman Date: Sat Dec 24 03:57:10 2011 New Revision: 54746
URL: http://svn.reactos.org/svn/reactos?rev=54746&view=rev Log: [NTOSKRNL] - Fix inconsistent locking
Modified: trunk/reactos/ntoskrnl/cc/view.c
Modified: trunk/reactos/ntoskrnl/cc/view.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cc/view.c?rev=5474... ============================================================================== --- trunk/reactos/ntoskrnl/cc/view.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/cc/view.c [iso-8859-1] Sat Dec 24 03:57:10 2011 @@ -398,7 +398,7 @@ BOOLEAN Dirty, BOOLEAN Mapped) { - BOOLEAN WasDirty = CacheSeg->Dirty; + BOOLEAN WasDirty; KIRQL oldIrql;
ASSERT(Bcb); @@ -406,10 +406,14 @@ DPRINT("CcReleaseCacheSegment(Bcb 0x%p, CacheSeg 0x%p, Valid %d)\n", Bcb, CacheSeg, Valid);
+ KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + CacheSeg->Valid = Valid; + + WasDirty = CacheSeg->Dirty; CacheSeg->Dirty = CacheSeg->Dirty || Dirty;
- KeAcquireGuardedMutex(&ViewLock); if (!WasDirty && CacheSeg->Dirty) { InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); @@ -420,7 +424,6 @@ { CacheSeg->MappedCount++; } - KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); CcRosCacheSegmentDecRefCount(CacheSeg); if (Mapped && CacheSeg->MappedCount == 1) { @@ -430,6 +433,7 @@ { CcRosCacheSegmentIncRefCount(CacheSeg); } + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseGuardedMutex(&ViewLock); KeReleaseMutex(&CacheSeg->Mutex, 0); @@ -449,8 +453,10 @@ ASSERT(Bcb);
DPRINT("CcRosLookupCacheSegment(Bcb -x%p, FileOffset %d)\n", Bcb, FileOffset); - + + KeAcquireGuardedMutex(&ViewLock); KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + current_entry = Bcb->BcbSegmentListHead.Flink; while (current_entry != &Bcb->BcbSegmentListHead) { @@ -461,6 +467,7 @@ { CcRosCacheSegmentIncRefCount(current); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + KeReleaseGuardedMutex(&ViewLock); KeWaitForSingleObject(¤t->Mutex, Executive, KernelMode, @@ -470,7 +477,10 @@ } current_entry = current_entry->Flink; } + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + KeReleaseGuardedMutex(&ViewLock); + return(NULL); }
@@ -490,29 +500,28 @@ { KeBugCheck(CACHE_MANAGER); } + + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + 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); + CcRosCacheSegmentDecRefCount(CacheSeg); + }
/* Move to the tail of the LRU list */ RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry); InsertTailList(&CacheSegmentLRUListHead, &CacheSeg->CacheSegmentLRUListEntry);
+ CacheSeg->Dirty = TRUE; + + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseGuardedMutex(&ViewLock); - - CacheSeg->Dirty = TRUE; KeReleaseMutex(&CacheSeg->Mutex, 0);
return(STATUS_SUCCESS); @@ -537,6 +546,9 @@ return(STATUS_UNSUCCESSFUL); }
+ KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + WasDirty = CacheSeg->Dirty; CacheSeg->Dirty = CacheSeg->Dirty || NowDirty;
@@ -544,13 +556,10 @@
if (!WasDirty && NowDirty) { - KeAcquireGuardedMutex(&ViewLock); InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; - KeReleaseGuardedMutex(&ViewLock); - } - - KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + } + CcRosCacheSegmentDecRefCount(CacheSeg); if (!WasDirty && NowDirty) { @@ -560,8 +569,9 @@ { CcRosCacheSegmentDecRefCount(CacheSeg); } + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - + KeReleaseGuardedMutex(&ViewLock); KeReleaseMutex(&CacheSeg->Mutex, 0);
return(STATUS_SUCCESS); @@ -1039,9 +1049,12 @@ } } KeReleaseMutex(¤t->Mutex, 0); + + KeAcquireGuardedMutex(&ViewLock); KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); CcRosCacheSegmentDecRefCount(current); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + KeReleaseGuardedMutex(&ViewLock); }
Offset.QuadPart += Bcb->CacheSegmentSize;