https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fc4744da5f9cf16f5559e7...
commit fc4744da5f9cf16f5559e78981702158066ce626 Author: Pierre Schweitzer pierre@reactos.org AuthorDate: Fri Feb 9 11:05:15 2018 +0100 Commit: Pierre Schweitzer pierre@reactos.org CommitDate: Fri Feb 9 11:05:15 2018 +0100
[NTOSKRNL] Use better locking for private cache map in CcRosReleaseFileCache(). Suggested by Thomas --- ntoskrnl/cc/view.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index 377c1ef84d..cb6991b19c 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -1171,6 +1171,8 @@ CcRosReleaseFileCache ( * has been closed. */ { + KIRQL OldIrql; + PPRIVATE_CACHE_MAP PrivateMap; PROS_SHARED_CACHE_MAP SharedCacheMap;
KeAcquireGuardedMutex(&ViewLock); @@ -1178,27 +1180,25 @@ CcRosReleaseFileCache ( if (FileObject->SectionObjectPointer->SharedCacheMap != NULL) { SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; - if (FileObject->PrivateCacheMap != NULL) - { - KIRQL OldIrql; - PPRIVATE_CACHE_MAP PrivateMap;
- /* Closing the handle, so kill the private cache map */ - PrivateMap = FileObject->PrivateCacheMap; + /* Closing the handle, so kill the private cache map + * Before you event try to remove it from FO, always + * lock the master lock, to be sure not to race + * with a potential read ahead ongoing! + */ + OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock); + PrivateMap = FileObject->PrivateCacheMap; + FileObject->PrivateCacheMap = NULL; + KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
+ if (PrivateMap != NULL) + { /* Remove it from the file */ KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &OldIrql); RemoveEntryList(&PrivateMap->PrivateLinks); KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, OldIrql);
- /* And free it. - * Before you event try to remove it from FO, always - * lock the master lock, to be sure not to race - * with a potential read ahead ongoing! - */ - OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock); - FileObject->PrivateCacheMap = NULL; - KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql); + /* And free it. */ ExFreePoolWithTag(PrivateMap, TAG_PRIVATE_CACHE_MAP);
if (SharedCacheMap->OpenCount > 0)