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:
Ingo Weinhold
2008-03-24 05:15:42 +00:00
parent 92af28df98
commit 0956fd0502
+6 -3
View File
@@ -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) {