From f1eccd05ecdbdc89017dbd62adcca8047f4bba8a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 2 Jul 2009 18:02:55 +0000 Subject: In vn_vget_ino() and their inline equivalents, mnt_ref() the mount point around the sequence that drop vnode lock and then busies the mount point. Not having vlocked node or direct reference to the mp allows for the forced unmount to proceed, making mp unmounted or reused. Tested by: pho Reviewed by: jeff Approved by: re (kensmith) MFC after: 2 weeks --- sys/fs/cd9660/cd9660_lookup.c | 2 ++ sys/kern/vfs_vnops.c | 2 ++ sys/nfsclient/nfs_vnops.c | 2 ++ sys/ufs/ffs/ffs_softdep.c | 2 ++ 4 files changed, 8 insertions(+) (limited to 'sys') diff --git a/sys/fs/cd9660/cd9660_lookup.c b/sys/fs/cd9660/cd9660_lookup.c index e23d8f3b030d..590fc1911428 100644 --- a/sys/fs/cd9660/cd9660_lookup.c +++ b/sys/fs/cd9660/cd9660_lookup.c @@ -376,9 +376,11 @@ found: ltype = VOP_ISLOCKED(pdp); error = vfs_busy(mp, MBF_NOWAIT); if (error != 0) { + vfs_ref(mp); VOP_UNLOCK(pdp, 0); error = vfs_busy(mp, 0); vn_lock(pdp, ltype | LK_RETRY); + vfs_rel(mp); if (error) return (ENOENT); if (pdp->v_iflag & VI_DOOMED) { diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index bef2804037b3..f67064613e06 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1307,9 +1307,11 @@ vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp) ("vn_vget_ino: vp not locked")); error = vfs_busy(mp, MBF_NOWAIT); if (error != 0) { + vfs_ref(mp); VOP_UNLOCK(vp, 0); error = vfs_busy(mp, 0); vn_lock(vp, ltype | LK_RETRY); + vfs_rel(mp); if (error != 0) return (ENOENT); if (vp->v_iflag & VI_DOOMED) { diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 060ac54134fd..07a79043681d 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -1043,9 +1043,11 @@ nfs_lookup(struct vop_lookup_args *ap) ltype = VOP_ISLOCKED(dvp); error = vfs_busy(mp, MBF_NOWAIT); if (error != 0) { + vfs_ref(mp); VOP_UNLOCK(dvp, 0); error = vfs_busy(mp, 0); vn_lock(dvp, ltype | LK_RETRY); + vfs_rel(mp); if (error == 0 && (dvp->v_iflag & VI_DOOMED)) { vfs_unbusy(mp); error = ENOENT; diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index d7b8818721fc..72522b2594e5 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -5104,9 +5104,11 @@ softdep_fsync(vp) FFSV_FORCEINSMQ)) { error = vfs_busy(mp, MBF_NOWAIT); if (error != 0) { + vfs_ref(mp); VOP_UNLOCK(vp, 0); error = vfs_busy(mp, 0); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + vfs_rel(mp); if (error != 0) return (ENOENT); if (vp->v_iflag & VI_DOOMED) { -- cgit v1.3