From 62454aae669ee5458ef7077c3a858c094d0d68fb Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 8 Sep 2007 17:03:19 +0000 Subject: [PATCH] Fixed get_mount(). It must also acquire the vnode lock before trying to increment the root node vnode reference count. Otherwise it could race with fs_unmount(). Fixes bug #1438. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22203 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/fs/vfs.cpp | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index fccad665be..f9e5c9950b 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -474,27 +474,20 @@ get_mount(dev_t id, struct fs_mount **_mount) struct fs_mount *mount; status_t status; - mutex_lock(&sMountMutex); + MutexLocker nodeLocker(sVnodeMutex); + MutexLocker mountLocker(sMountMutex); mount = find_mount(id); - if (mount) { - // ToDo: the volume is locked (against removal) by locking - // its root node - investigate if that's a good idea - if (mount->root_vnode) - inc_vnode_ref_count(mount->root_vnode); - else { - // might have been called during a mount operation in which - // case the root node may still be NULL - mount = NULL; - } - } else - status = B_BAD_VALUE; - - mutex_unlock(&sMountMutex); - if (mount == NULL) - return B_BUSY; + return B_BAD_VALUE; + struct vnode* rootNode = mount->root_vnode; + if (rootNode == NULL || rootNode->busy || rootNode->ref_count == 0) { + // might have been called during a mount/unmount operation + return B_BUSY; + } + + inc_vnode_ref_count(mount->root_vnode); *_mount = mount; return B_OK; }