/* * 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); }
/* * Calculate the logical to physical mapping if not done already, * then call the device strategy routine. */ int ufs_strategy(void *v) { struct vop_strategy_args /* { struct vnode *a_vp; struct buf *a_bp; } */ *ap = v; struct buf *bp; struct vnode *vp; struct inode *ip; struct mount *mp; int error; bp = ap->a_bp; vp = ap->a_vp; ip = VTOI(vp); if (vp->v_type == VBLK || vp->v_type == VCHR) panic("ufs_strategy: spec"); KASSERT(bp->b_bcount != 0); if (bp->b_blkno == bp->b_lblkno) { error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL); if (error) { bp->b_error = error; biodone(bp); return (error); } if (bp->b_blkno == -1) /* no valid data */ clrbuf(bp); } if (bp->b_blkno < 0) { /* block is not on disk */ biodone(bp); return (0); } vp = ip->i_devvp; error = VOP_STRATEGY(vp, bp); if (error) return error; if (!BUF_ISREAD(bp)) return 0; mp = wapbl_vptomp(vp); if (mp == NULL || mp->mnt_wapbl_replay == NULL || !WAPBL_REPLAY_ISOPEN(mp) || !WAPBL_REPLAY_CAN_READ(mp, bp->b_blkno, bp->b_bcount)) return 0; error = biowait(bp); if (error) return error; error = WAPBL_REPLAY_READ(mp, bp->b_data, bp->b_blkno, bp->b_bcount); if (error) { mutex_enter(&bufcache_lock); SET(bp->b_cflags, BC_INVAL); mutex_exit(&bufcache_lock); } return error; }