diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 03b8ba1fe57f..e210fee0810a 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1286,3 +1286,35 @@ vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace, return (error); } + +int +vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp) +{ + struct mount *mp; + int ltype, error; + + mp = vp->v_mount; + ltype = VOP_ISLOCKED(vp); + KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED, + ("vn_vget_ino: vp not locked")); + for (;;) { + error = vfs_busy(mp, MBF_NOWAIT); + if (error == 0) + break; + VOP_UNLOCK(vp, 0); + pause("vn_vget", 1); + vn_lock(vp, ltype | LK_RETRY); + if (vp->v_iflag & VI_DOOMED) + return (ENOENT); + } + VOP_UNLOCK(vp, 0); + error = VFS_VGET(mp, ino, lkflags, rvp); + vfs_unbusy(mp); + vn_lock(vp, ltype | LK_RETRY); + if (vp->v_iflag & VI_DOOMED) { + if (error == 0) + vput(*rvp); + error = ENOENT; + } + return (error); +} diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index de640908fa8e..d6d99ade8329 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -636,6 +636,9 @@ int vn_extattr_set(struct vnode *vp, int ioflg, int attrnamespace, const char *attrname, int buflen, char *buf, struct thread *td); int vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace, const char *attrname, struct thread *td); +int vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, + struct vnode **rvp); + int vfs_cache_lookup(struct vop_lookup_args *ap); void vfs_timestamp(struct timespec *); void vfs_write_resume(struct mount *mp); diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 65ab0da10e40..bc11a6a26bef 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -157,7 +157,6 @@ ufs_lookup(ap) int nameiop = cnp->cn_nameiop; ino_t ino; int ltype; - struct mount *mp; bp = NULL; slotoffset = -1; @@ -578,27 +577,7 @@ found: */ pdp = vdp; if (flags & ISDOTDOT) { - ltype = VOP_ISLOCKED(pdp); - mp = pdp->v_mount; - for (;;) { - error = vfs_busy(mp, MBF_NOWAIT); - if (error == 0) - break; - VOP_UNLOCK(pdp, 0); - pause("ufs_dd", 1); - vn_lock(pdp, ltype | LK_RETRY); - if (pdp->v_iflag & VI_DOOMED) - return (ENOENT); - } - VOP_UNLOCK(pdp, 0); /* race to get the inode */ - error = VFS_VGET(mp, ino, cnp->cn_lkflags, &tdp); - vfs_unbusy(mp); - vn_lock(pdp, ltype | LK_RETRY); - if (pdp->v_iflag & VI_DOOMED) { - if (error == 0) - vput(tdp); - error = ENOENT; - } + error = vn_vget_ino(pdp, ino, cnp->cn_lkflags, &tdp); if (error) return (error); *vpp = tdp;