* 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:
Axel Dörfler 2006-08-30 23:09:04 +00:00
parent 96d67014ff
commit c40fe37f0b
3 changed files with 24 additions and 10 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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: