diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -106,61 +106,6 @@ static int enforce_lkflags(struct mount *mp, int lkflags); -/* Placeholder vnode for mp traversal. */ -static struct vnode *vp_crossmp; - -static int -crossmp_vop_islocked(struct vop_islocked_args *ap) -{ - - return (LK_SHARED); -} - -static int -crossmp_vop_lock1(struct vop_lock1_args *ap) -{ - struct vnode *vp; - struct lock *lk __diagused; - int flags; - - vp = ap->a_vp; - lk = vp->v_vnlock; - flags = ap->a_flags; - - KASSERT((flags & (LK_SHARED | LK_NOWAIT)) == (LK_SHARED | LK_NOWAIT), - ("%s: invalid lock request 0x%x for crossmp", __func__, flags)); - - if ((flags & LK_INTERLOCK) != 0) - VI_UNLOCK(vp); - LOCK_LOG_LOCK("SLOCK", &lk->lock_object, 0, 0, ap->a_file, ap->a_line); - return (0); -} - -static int -crossmp_vop_unlock(struct vop_unlock_args *ap) -{ - struct vnode *vp; - struct lock *lk __diagused; - - vp = ap->a_vp; - lk = vp->v_vnlock; - - LOCK_LOG_LOCK("SUNLOCK", &lk->lock_object, 0, 0, LOCK_FILE, - LOCK_LINE); - return (0); -} - -static struct vop_vector crossmp_vnodeops = { - .vop_default = &default_vnodeops, - .vop_islocked = crossmp_vop_islocked, - .vop_lock1 = crossmp_vop_lock1, - .vop_unlock = crossmp_vop_unlock, -}; -/* - * VFS_VOP_VECTOR_REGISTER(crossmp_vnodeops) is not used here since the vnode - * gets allocated early. See nameiinit for the direct call below. - */ - /* See vn_busy_mountedhere() in 'vnode.h'. */ int vn_busy_mountedhere_mounted(struct vnode *vp, bool *unlocked, struct mount **mp) @@ -375,10 +320,6 @@ namei_zone = uma_zcreate("NAMEI", MAXPATHLEN, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); - vfs_vector_op_register(&crossmp_vnodeops); - getnewvnode("crossmp", NULL, &crossmp_vnodeops, &vp_crossmp); - vp_crossmp->v_state = VSTATE_CONSTRUCTED; - vp_crossmp->v_irflag |= VIRF_CROSSMP; } SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL); @@ -1377,7 +1318,7 @@ * last operation. */ if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN) && - dp != vp_crossmp && VOP_ISLOCKED(dp) == LK_SHARED) + VOP_ISLOCKED(dp) == LK_SHARED) vn_lock(dp, LK_UPGRADE|LK_RETRY); if (VN_IS_DOOMED(dp)) { error = ENOENT; @@ -1514,8 +1455,7 @@ * reference, can only happen on a forced unmount. We could * climb to the "parent" directory (in the resolution, i.e., * 'ni_dvp'), but this is likely to be useless (if on the same - * mount it can have been doomed already, and if not, it - * currently is equal to 'vp_crossmp' anyway) and problematic + * mount it can have been doomed already) and problematic * semantically if done standalone. The most sensible * alternative would be to restart the whole resolution, but we * are not there yet. @@ -1528,11 +1468,13 @@ * is going to be replaced by 'vp_crossmp'. */ ndp->ni_vp = dp; - vrele(ndp->ni_dvp); - vrefact(vp_crossmp); - if (vn_lock(vp_crossmp, LK_SHARED | LK_NOWAIT)) - panic("vp_crossmp exclusively locked or reclaimed"); - ndp->ni_dvp = vp_crossmp; + vn_lock_pair(dp, true, enforce_lkflags(dp->v_mount, cnp->cn_lkflags), + ndp->ni_dvp, false, + enforce_lkflags(ndp->ni_dvp->v_mount, cnp->cn_lkflags)); + if (VN_IS_DOOMED(ndp->ni_dvp) || VN_IS_DOOMED(dp)) { + error = ENOENT; + goto bad2; + } nextname: /* @@ -1608,11 +1550,6 @@ if ((cnp->cn_flags & LOCKLEAF) == 0) VOP_UNLOCK(dp); success: - /* - * FIXME: for lookups which only cross a mount point to fetch the - * root vnode, ni_dvp will be set to vp_crossmp. This can be a problem - * if either WANTPARENT or LOCKPARENT is set. - */ /* * Because of shared lookup we may have the vnode shared locked, but * the caller may want it to be exclusively locked.