Author: cgutman Date: Fri Dec 23 23:20:09 2011 New Revision: 54745
URL: http://svn.reactos.org/svn/reactos?rev=54745&view=rev Log: [NTOSKRNL] - Reference the cache segment when flushing to avoid a race between deleting the file cache and the balancer flushing pages to disk which causes random cache segments to be freed while we're holding a lock on it - Fixes a crash in KeReleaseMutex (used to be a crash in ExReleasePushLock) during periods of high memory load
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] Fri Dec 23 23:20:09 2011 @@ -204,10 +204,13 @@ DirtySegmentListEntry); current_entry = current_entry->Flink;
+ CcRosCacheSegmentIncRefCount(current); + Locked = current->Bcb->Callbacks->AcquireForLazyWrite( current->Bcb->LazyWriteContext, Wait); if (!Locked) { + CcRosCacheSegmentDecRefCount(current); continue; }
@@ -220,6 +223,7 @@ { current->Bcb->Callbacks->ReleaseFromLazyWrite( current->Bcb->LazyWriteContext); + CcRosCacheSegmentDecRefCount(current); continue; }
@@ -229,6 +233,7 @@ KeReleaseMutex(¤t->Mutex, 0); current->Bcb->Callbacks->ReleaseFromLazyWrite( current->Bcb->LazyWriteContext); + CcRosCacheSegmentDecRefCount(current); continue; }
@@ -241,6 +246,9 @@ KeReleaseMutex(¤t->Mutex, 0); current->Bcb->Callbacks->ReleaseFromLazyWrite( current->Bcb->LazyWriteContext); + + KeAcquireGuardedMutex(&ViewLock); + CcRosCacheSegmentDecRefCount(current);
if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) { @@ -251,8 +259,7 @@ (*Count) += PagesPerSegment; Target -= PagesPerSegment; } - - KeAcquireGuardedMutex(&ViewLock); + current_entry = DirtySegmentListHead.Flink; }