* Reverted the changes r17693 made to vfs_get_vnode_cache(); instead, vm_create_vnode_cache()
will now grab a reference to the vnode as well if successful. This way, vfs_get_vnode_cache() now actually works how it should: it will now always grab a reference to the cache and its underlying vnode. This removes an extra reference to the vnode (and vm_cache) that got ignored before and prevented volumes to be unmounted (or file caches to be removed). Thanks to Korli for pointing this out. * file_cache_create() is now aware of that extra vnode reference and releases it; unmounting volumes is now working again as it should. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18716 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
96d67014ff
commit
c40fe37f0b
16
src/system/kernel/cache/file_cache.cpp
vendored
16
src/system/kernel/cache/file_cache.cpp
vendored
@ -1176,7 +1176,7 @@ file_cache_create(mount_id mountID, vnode_id vnodeID, off_t size, int fd)
|
||||
if (ref == NULL)
|
||||
return NULL;
|
||||
|
||||
// ToDo: delay vm_cache/vm_cache_ref creation until data is
|
||||
// TODO: delay vm_cache/vm_cache_ref creation until data is
|
||||
// requested/written for the first time? Listing lots of
|
||||
// files in Tracker (and elsewhere) could be slowed down.
|
||||
// Since the file_cache_ref itself doesn't have a lock,
|
||||
@ -1186,21 +1186,29 @@ file_cache_create(mount_id mountID, vnode_id vnodeID, off_t size, int fd)
|
||||
// use atomic_test_and_set(), and free the resources again
|
||||
// when that fails...
|
||||
|
||||
// get the vnode of the underlying device
|
||||
// Get the vnode of the underlying device
|
||||
if (vfs_get_vnode_from_fd(fd, true, &ref->device) != B_OK)
|
||||
goto err1;
|
||||
|
||||
// we also need the cookie of the underlying device to properly access it
|
||||
// We also need the cookie of the underlying device to properly access it
|
||||
if (vfs_get_cookie_from_fd(fd, &ref->cookie) != B_OK)
|
||||
goto err2;
|
||||
|
||||
// get the vnode for the object (note, this does not grab a reference to the node)
|
||||
// Get the vnode for the object (note, this does not grab a reference to the node)
|
||||
if (vfs_lookup_vnode(mountID, vnodeID, &ref->vnode) != B_OK)
|
||||
goto err2;
|
||||
|
||||
// Gets (usually creates) the cache for the node - note, this does grab a
|
||||
// reference to the node...
|
||||
if (vfs_get_vnode_cache(ref->vnode, &ref->cache, true) != B_OK)
|
||||
goto err2;
|
||||
|
||||
// ... that we don't need, and therefore release it again.
|
||||
// Our caller already holds a reference to the vnode; it will destroy us
|
||||
// when the last one goes away (which, of course, can only ever happen if
|
||||
// we don't grab an extra reference).
|
||||
vfs_put_vnode(ref->vnode);
|
||||
|
||||
ref->cache->cache->virtual_size = size;
|
||||
((vnode_store *)ref->cache->cache->store)->file_cache_ref = ref;
|
||||
return ref;
|
||||
|
@ -3063,7 +3063,7 @@ vfs_write_pages(void *_vnode, void *cookie, off_t pos, const iovec *vecs, size_t
|
||||
/** Gets the vnode's vm_cache object. If it didn't have one, it will be
|
||||
* created if \a allocate is \c true.
|
||||
* In case it's successful, it will also grab a reference to the cache
|
||||
* it returns.
|
||||
* it returns (and therefore, one from the \a vnode in question as well).
|
||||
*/
|
||||
|
||||
extern "C" status_t
|
||||
@ -3096,12 +3096,11 @@ vfs_get_vnode_cache(void *_vnode, vm_cache_ref **_cache, bool allocate)
|
||||
vnode->busy = wasBusy;
|
||||
} else
|
||||
status = B_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (status == B_OK) {
|
||||
} else
|
||||
vm_cache_acquire_ref(vnode->cache);
|
||||
|
||||
if (status == B_OK)
|
||||
*_cache = vnode->cache;
|
||||
}
|
||||
|
||||
mutex_unlock(&sVnodeMutex);
|
||||
return status;
|
||||
@ -5468,7 +5467,6 @@ fs_unmount(char *path, uint32 flags, bool kernel)
|
||||
// a vnode while we're figuring out if we can continue
|
||||
mutex_lock(&sVnodeMutex);
|
||||
|
||||
|
||||
bool disconnectedDescriptors = false;
|
||||
|
||||
while (true) {
|
||||
|
@ -1101,6 +1101,13 @@ err1:
|
||||
}
|
||||
|
||||
|
||||
/** Creates the vnode cache for the specified \a vnode.
|
||||
* The vnode has to be marked busy when calling this function.
|
||||
* If successful, it will also acquire an extra reference to
|
||||
* the vnode (as the vnode store itself can't do this
|
||||
* automatically).
|
||||
*/
|
||||
|
||||
status_t
|
||||
vm_create_vnode_cache(void *vnode, struct vm_cache_ref **_cacheRef)
|
||||
{
|
||||
@ -1121,6 +1128,7 @@ vm_create_vnode_cache(void *vnode, struct vm_cache_ref **_cacheRef)
|
||||
goto err2;
|
||||
|
||||
*_cacheRef = cache->ref;
|
||||
vfs_acquire_vnode(vnode);
|
||||
return B_OK;
|
||||
|
||||
err2:
|
||||
|
Loading…
Reference in New Issue
Block a user