[NTOSKRNL]

- Change the method of segment locking from a push lock to a mutex
- Fixes the 'OldValue.Locked' assertion failure

svn path=/trunk/; revision=54729
This commit is contained in:
Cameron Gutman 2011-12-21 19:08:59 +00:00
parent 45c965ea82
commit 80ee75c141
3 changed files with 39 additions and 28 deletions

View file

@ -240,8 +240,11 @@ CcUnpinRepinnedBcb (
IoStatus->Information = 0; IoStatus->Information = 0;
if (WriteThrough) if (WriteThrough)
{ {
KeEnterCriticalRegion(); KeWaitForSingleObject(&iBcb->CacheSegment->Mutex,
ExAcquirePushLockExclusive(&iBcb->CacheSegment->Lock); Executive,
KernelMode,
FALSE,
NULL);
if (iBcb->CacheSegment->Dirty) if (iBcb->CacheSegment->Dirty)
{ {
IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment); IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment);
@ -250,8 +253,7 @@ CcUnpinRepinnedBcb (
{ {
IoStatus->Status = STATUS_SUCCESS; IoStatus->Status = STATUS_SUCCESS;
} }
ExReleasePushLockExclusive(&iBcb->CacheSegment->Lock); KeReleaseMutex(&iBcb->CacheSegment->Mutex, 0);
KeLeaveCriticalRegion();
} }
else else
{ {

View file

@ -231,12 +231,16 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
continue; continue;
} }
ExAcquirePushLockExclusive(&current->Lock); KeWaitForSingleObject(&current->Mutex,
Executive,
KernelMode,
FALSE,
NULL);
ASSERT(current->Dirty); ASSERT(current->Dirty);
if (current->ReferenceCount > 1) if (current->ReferenceCount > 1)
{ {
ExReleasePushLock(&current->Lock); KeReleaseMutex(&current->Mutex, 0);
current->Bcb->Callbacks->ReleaseFromLazyWrite( current->Bcb->Callbacks->ReleaseFromLazyWrite(
current->Bcb->LazyWriteContext); current->Bcb->LazyWriteContext);
continue; continue;
@ -248,7 +252,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
Status = CcRosFlushCacheSegment(current); Status = CcRosFlushCacheSegment(current);
ExReleasePushLock(&current->Lock); KeReleaseMutex(&current->Mutex, 0);
current->Bcb->Callbacks->ReleaseFromLazyWrite( current->Bcb->Callbacks->ReleaseFromLazyWrite(
current->Bcb->LazyWriteContext); current->Bcb->LazyWriteContext);
@ -440,8 +444,7 @@ CcRosReleaseCacheSegment(PBCB Bcb,
} }
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock); KeReleaseGuardedMutex(&ViewLock);
ExReleasePushLock(&CacheSeg->Lock); KeReleaseMutex(&CacheSeg->Mutex, 0);
KeLeaveCriticalRegion();
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -470,8 +473,11 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
{ {
CcRosCacheSegmentIncRefCount(current); CcRosCacheSegmentIncRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeEnterCriticalRegion(); KeWaitForSingleObject(&current->Mutex,
ExAcquirePushLockExclusive(&current->Lock); Executive,
KernelMode,
FALSE,
NULL);
return(current); return(current);
} }
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
@ -519,8 +525,7 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset)
KeReleaseGuardedMutex(&ViewLock); KeReleaseGuardedMutex(&ViewLock);
CacheSeg->Dirty = TRUE; CacheSeg->Dirty = TRUE;
ExReleasePushLock(&CacheSeg->Lock); KeReleaseMutex(&CacheSeg->Mutex, 0);
KeLeaveCriticalRegion();
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -569,8 +574,7 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
} }
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
ExReleasePushLock(&CacheSeg->Lock); KeReleaseMutex(&CacheSeg->Mutex, 0);
KeLeaveCriticalRegion();
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -618,9 +622,12 @@ CcRosCreateCacheSegment(PBCB Bcb,
current->DirtySegmentListEntry.Flink = NULL; current->DirtySegmentListEntry.Flink = NULL;
current->DirtySegmentListEntry.Blink = NULL; current->DirtySegmentListEntry.Blink = NULL;
current->ReferenceCount = 1; current->ReferenceCount = 1;
ExInitializePushLock(&current->Lock); KeInitializeMutex(&current->Mutex, 0);
KeEnterCriticalRegion(); KeWaitForSingleObject(&current->Mutex,
ExAcquirePushLockExclusive(&current->Lock); Executive,
KernelMode,
FALSE,
NULL);
KeAcquireGuardedMutex(&ViewLock); KeAcquireGuardedMutex(&ViewLock);
*CacheSeg = current; *CacheSeg = current;
@ -650,12 +657,15 @@ CcRosCreateCacheSegment(PBCB Bcb,
current ); current );
} }
#endif #endif
ExReleasePushLock(&(*CacheSeg)->Lock); KeReleaseMutex(&(*CacheSeg)->Mutex, 0);
KeReleaseGuardedMutex(&ViewLock); KeReleaseGuardedMutex(&ViewLock);
ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg); ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg);
*CacheSeg = current; *CacheSeg = current;
/* We're still in the critical region from above */ KeWaitForSingleObject(&current->Mutex,
ExAcquirePushLockExclusive(&current->Lock); Executive,
KernelMode,
FALSE,
NULL);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
if (current->FileOffset < FileOffset) if (current->FileOffset < FileOffset)
@ -1040,8 +1050,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
IoStatus->Status = Status; IoStatus->Status = Status;
} }
} }
ExReleasePushLock(&current->Lock); KeReleaseMutex(&current->Mutex, 0);
KeLeaveCriticalRegion();
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
CcRosCacheSegmentDecRefCount(current); CcRosCacheSegmentDecRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);

View file

@ -145,8 +145,8 @@ typedef struct _CACHE_SEGMENT
LIST_ENTRY CacheSegmentLRUListEntry; LIST_ENTRY CacheSegmentLRUListEntry;
/* Offset in the file which this cache segment maps. */ /* Offset in the file which this cache segment maps. */
ULONG FileOffset; ULONG FileOffset;
/* Lock. */ /* Mutex */
EX_PUSH_LOCK Lock; KMUTEX Mutex;
/* Number of references. */ /* Number of references. */
ULONG ReferenceCount; ULONG ReferenceCount;
/* Pointer to the BCB for the file which this cache segment maps data for. */ /* Pointer to the BCB for the file which this cache segment maps data for. */