Example #1
0
/*
 * 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);
}