コード例 #1
0
ファイル: vnode.c プロジェクト: AhmadTux/freebsd
/*
 * Like vn_rele() except if we are going to call VOP_INACTIVE() then do it
 * asynchronously using a taskq. This can avoid deadlocks caused by re-entering
 * the file system as a result of releasing the vnode. Note, file systems
 * already have to handle the race where the vnode is incremented before the
 * inactive routine is called and does its locking.
 *
 * Warning: Excessive use of this routine can lead to performance problems.
 * This is because taskqs throttle back allocation if too many are created.
 */
void
vn_rele_async(vnode_t *vp, taskq_t *taskq)
{
	VERIFY(vp->v_count > 0);
	VI_LOCK(vp);
	if (vp->v_count == 1 && !(vp->v_iflag & VI_DOINGINACT)) {
		VI_UNLOCK(vp);
		VERIFY(taskq_dispatch((taskq_t *)taskq,
		    (task_func_t *)vn_rele_inactive, vp, TQ_SLEEP) != 0);
		return;
	}
	vp->v_usecount--;
	vdropl(vp);
}
コード例 #2
0
static int
ufs_lookup_upgrade_lock(struct vnode *vp)
{
	int error;

	ASSERT_VOP_LOCKED(vp, __FUNCTION__);
	if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE)
		return (0);

	error = 0;

	/*
	 * Upgrade vnode lock, since getinoquota()
	 * requires exclusive lock to modify inode.
	 */
	vhold(vp);
	vn_lock(vp, LK_UPGRADE | LK_RETRY);
	VI_LOCK(vp);
	if (vp->v_iflag & VI_DOOMED)
		error = ENOENT;
	vdropl(vp);
	return (error);
}