* 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)
|
if (ref == NULL)
|
||||||
return 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
|
// requested/written for the first time? Listing lots of
|
||||||
// files in Tracker (and elsewhere) could be slowed down.
|
// files in Tracker (and elsewhere) could be slowed down.
|
||||||
// Since the file_cache_ref itself doesn't have a lock,
|
// 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
|
// use atomic_test_and_set(), and free the resources again
|
||||||
// when that fails...
|
// 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)
|
if (vfs_get_vnode_from_fd(fd, true, &ref->device) != B_OK)
|
||||||
goto err1;
|
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)
|
if (vfs_get_cookie_from_fd(fd, &ref->cookie) != B_OK)
|
||||||
goto err2;
|
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)
|
if (vfs_lookup_vnode(mountID, vnodeID, &ref->vnode) != B_OK)
|
||||||
goto err2;
|
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)
|
if (vfs_get_vnode_cache(ref->vnode, &ref->cache, true) != B_OK)
|
||||||
goto err2;
|
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;
|
ref->cache->cache->virtual_size = size;
|
||||||
((vnode_store *)ref->cache->cache->store)->file_cache_ref = ref;
|
((vnode_store *)ref->cache->cache->store)->file_cache_ref = ref;
|
||||||
return 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
|
/** Gets the vnode's vm_cache object. If it didn't have one, it will be
|
||||||
* created if \a allocate is \c true.
|
* created if \a allocate is \c true.
|
||||||
* In case it's successful, it will also grab a reference to the cache
|
* 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
|
extern "C" status_t
|
||||||
@ -3096,12 +3096,11 @@ 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
|
||||||
|
|
||||||
if (status == B_OK) {
|
|
||||||
vm_cache_acquire_ref(vnode->cache);
|
vm_cache_acquire_ref(vnode->cache);
|
||||||
|
|
||||||
|
if (status == B_OK)
|
||||||
*_cache = vnode->cache;
|
*_cache = vnode->cache;
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&sVnodeMutex);
|
mutex_unlock(&sVnodeMutex);
|
||||||
return status;
|
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
|
// a vnode while we're figuring out if we can continue
|
||||||
mutex_lock(&sVnodeMutex);
|
mutex_lock(&sVnodeMutex);
|
||||||
|
|
||||||
|
|
||||||
bool disconnectedDescriptors = false;
|
bool disconnectedDescriptors = false;
|
||||||
|
|
||||||
while (true) {
|
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
|
status_t
|
||||||
vm_create_vnode_cache(void *vnode, struct vm_cache_ref **_cacheRef)
|
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;
|
goto err2;
|
||||||
|
|
||||||
*_cacheRef = cache->ref;
|
*_cacheRef = cache->ref;
|
||||||
|
vfs_acquire_vnode(vnode);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
err2:
|
err2:
|
||||||
|
Loading…
Reference in New Issue
Block a user