/* * Check that the vnode is still valid, and if so * acquire requested lock. */ int vn_lock(struct vnode *vp, int flags) { int error; #if 0 KASSERT(vp->v_usecount > 0 || (vp->v_iflag & VI_ONWORKLST) != 0); #endif KASSERT((flags & ~(LK_SHARED|LK_EXCLUSIVE|LK_NOWAIT|LK_RETRY)) == 0); KASSERT(!mutex_owned(vp->v_interlock)); #ifdef DIAGNOSTIC if (wapbl_vphaswapbl(vp)) WAPBL_JUNLOCK_ASSERT(wapbl_vptomp(vp)); #endif error = VOP_LOCK(vp, flags); if ((flags & LK_RETRY) != 0 && error == ENOENT) error = VOP_LOCK(vp, flags); KASSERT((flags & LK_RETRY) == 0 || (flags & LK_NOWAIT) != 0 || error == 0); return error; }
/* * Check that the vnode is still valid, and if so * acquire requested lock. */ int vn_lock(struct vnode *vp, int flags) { int error; #if 0 KASSERT(vp->v_usecount > 0 || (vp->v_iflag & VI_ONWORKLST) != 0); #endif KASSERT((flags & ~(LK_SHARED|LK_EXCLUSIVE|LK_NOWAIT|LK_RETRY)) == 0); KASSERT(!mutex_owned(vp->v_interlock)); #ifdef DIAGNOSTIC if (wapbl_vphaswapbl(vp)) WAPBL_JUNLOCK_ASSERT(wapbl_vptomp(vp)); #endif do { /* * XXX PR 37706 forced unmount of file systems is unsafe. * Race between vclean() and this the remaining problem. */ mutex_enter(vp->v_interlock); if (vp->v_iflag & VI_XLOCK) { if (flags & LK_NOWAIT) { mutex_exit(vp->v_interlock); return EBUSY; } vwait(vp, VI_XLOCK); mutex_exit(vp->v_interlock); error = ENOENT; } else { mutex_exit(vp->v_interlock); error = VOP_LOCK(vp, (flags & ~LK_RETRY)); if (error == 0 || error == EDEADLK || error == EBUSY) return (error); } } while (flags & LK_RETRY); return (error); }