From e9aff35739558a0eaf546aa91adec0f619718fa4 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 21 Jan 2009 14:51:38 +0000 Subject: [PATCH] Move the code from ufs_lookup.c used to do dotdot lookup, into the helper function. It is supposed to be useful for any filesystem that has to unlock dvp to walk to the ".." entry in lookup routine. Requested by: jhb Tested by: pho MFC after: 1 month --- sys/kern/vfs_vnops.c | 32 ++++++++++++++++++++++++++++++++ sys/sys/vnode.h | 3 +++ sys/ufs/ufs/ufs_lookup.c | 23 +---------------------- 3 files changed, 36 insertions(+), 22 deletions(-) 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 @@ ufs_lookup(ap) */ 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;