Applied change proposed in #1917 after encountering the bug the third
time. Releasing the cache's store reference while holding the cache lock could reverse the usual locking order -- the VFS could potentially call the remove_vnode() or put_vnode() FS hook, which in turn could use the file cache, thus resulting in a deadlock. Now we release the store ref before locking the cache. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24548 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -545,14 +545,17 @@ vm_cache_remove_consumer(vm_cache *cache, vm_cache *consumer)
|
||||
TRACE(("remove consumer vm cache %p from cache %p\n", consumer, cache));
|
||||
ASSERT_LOCKED_MUTEX(&consumer->lock);
|
||||
|
||||
// Remove the store ref before locking the cache. Otherwise we'd call into
|
||||
// the VFS while holding the cache lock, which would reverse the usual
|
||||
// locking order.
|
||||
if (cache->store->ops->release_ref)
|
||||
cache->store->ops->release_ref(cache->store);
|
||||
|
||||
// remove the consumer from the cache, but keep its reference until later
|
||||
mutex_lock(&cache->lock);
|
||||
list_remove_item(&cache->consumers, consumer);
|
||||
consumer->source = NULL;
|
||||
|
||||
if (cache->store->ops->release_ref)
|
||||
cache->store->ops->release_ref(cache->store);
|
||||
|
||||
if (cache->areas == NULL && cache->source != NULL
|
||||
&& !list_is_empty(&cache->consumers)
|
||||
&& cache->consumers.link.next == cache->consumers.link.prev) {
|
||||
|
||||
Reference in New Issue
Block a user