diff options
author | iedowse <iedowse@FreeBSD.org> | 2001-08-20 19:16:31 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2001-08-20 19:16:31 +0000 |
commit | 22613ae234c4f1befd9d621adc27ca4aa78cb25c (patch) | |
tree | cbcbfda4f924b6a5633aa55bacf99e1378de7497 /sys/kern/vfs_extattr.c | |
parent | 5ba6edf189c79e6f033a79a60979ea33c63f93d8 (diff) | |
download | FreeBSD-src-22613ae234c4f1befd9d621adc27ca4aa78cb25c.zip FreeBSD-src-22613ae234c4f1befd9d621adc27ca4aa78cb25c.tar.gz |
Avoid sleeping while holding a mutex in dounmount(). This problem
has existed for a long time, but I made it worse a few months ago
by by adding calls to VFS_ROOT() and checkdirs() in revision 1.179.
Also, remove the LK_REENABLE flag in the lockmgr() call; this flag
has been ignored by the lockmgr code for 4 years. This was the only
remaining mention of it apart from its definition.
Reviewed by: jhb
Diffstat (limited to 'sys/kern/vfs_extattr.c')
-rw-r--r-- | sys/kern/vfs_extattr.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 187727f..086fd16 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -545,7 +545,6 @@ dounmount(mp, flags, p) error = VFS_UNMOUNT(mp, flags, p); } vn_finished_write(mp); - mtx_lock(&mountlist_mtx); if (error) { /* Undo cdir/rdir and rootvnode changes made above. */ if (VFS_ROOT(mp, &fsrootvp) == 0) { @@ -559,24 +558,26 @@ dounmount(mp, flags, p) } if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL) (void) vfs_allocate_syncvnode(mp); + mtx_lock(&mountlist_mtx); mp->mnt_kern_flag &= ~MNTK_UNMOUNT; mp->mnt_flag |= async_flag; - lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE, + lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_mtx, p); if (mp->mnt_kern_flag & MNTK_MWAIT) wakeup((caddr_t)mp); return (error); } + mtx_lock(&mountlist_mtx); TAILQ_REMOVE(&mountlist, mp, mnt_list); - if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) { - coveredvp->v_mountedhere = (struct mount *)0; - vrele(coveredvp); - } + if ((coveredvp = mp->mnt_vnodecovered) != NULL) + coveredvp->v_mountedhere = NULL; mp->mnt_vfc->vfc_refcount--; if (!LIST_EMPTY(&mp->mnt_vnodelist)) panic("unmount: dangling vnode"); lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_mtx, p); lockdestroy(&mp->mnt_lock); + if (coveredvp != NULL) + vrele(coveredvp); if (mp->mnt_kern_flag & MNTK_MWAIT) wakeup((caddr_t)mp); free((caddr_t)mp, M_MOUNT); |