_vm_map_file() did in fact not work correctly, but the main problem was
vfs_get_vnode_cache() which did not acquire an extra reference to the cache_ref when the cache had to be created. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17693 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -3085,11 +3085,12 @@ vfs_get_vnode_cache(void *_vnode, vm_cache_ref **_cache, bool allocate)
|
|||||||
vnode->busy = wasBusy;
|
vnode->busy = wasBusy;
|
||||||
} else
|
} else
|
||||||
status = B_BAD_VALUE;
|
status = B_BAD_VALUE;
|
||||||
} else
|
}
|
||||||
vm_cache_acquire_ref(vnode->cache);
|
|
||||||
|
|
||||||
if (status == B_OK)
|
if (status == B_OK) {
|
||||||
|
vm_cache_acquire_ref(vnode->cache);
|
||||||
*_cache = vnode->cache;
|
*_cache = vnode->cache;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_unlock(&sVnodeMutex);
|
mutex_unlock(&sVnodeMutex);
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -1179,14 +1179,17 @@ _vm_map_file(team_id aid, const char *name, void **_address, uint32 addressSpec,
|
|||||||
|
|
||||||
status = map_backing_store(addressSpace, cacheRef->cache->store, _address,
|
status = map_backing_store(addressSpace, cacheRef->cache->store, _address,
|
||||||
offset, size, addressSpec, 0, protection, mapping, &area, name);
|
offset, size, addressSpec, 0, protection, mapping, &area, name);
|
||||||
|
|
||||||
|
if (status < B_OK || mapping == REGION_PRIVATE_MAP) {
|
||||||
|
// map_backing_store() cannot know we no longer need the ref
|
||||||
|
vm_cache_release_ref(cacheRef);
|
||||||
|
}
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err2;
|
goto err1;
|
||||||
|
|
||||||
vm_put_address_space(addressSpace);
|
vm_put_address_space(addressSpace);
|
||||||
return area->id;
|
return area->id;
|
||||||
|
|
||||||
err2:
|
|
||||||
vm_cache_release_ref(cacheRef);
|
|
||||||
err1:
|
err1:
|
||||||
vm_put_address_space(addressSpace);
|
vm_put_address_space(addressSpace);
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
Reference in New Issue
Block a user