Index: external/cddl/osnet/dist/uts/common/fs/zfs/zfs_replay.c =================================================================== RCS file: /cvsroot/src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_replay.c,v retrieving revision 1.9 diff -p -u -4 -r1.9 zfs_replay.c --- external/cddl/osnet/dist/uts/common/fs/zfs/zfs_replay.c 23 Jan 2014 10:13:55 -0000 1.9 +++ external/cddl/osnet/dist/uts/common/fs/zfs/zfs_replay.c 3 Feb 2014 09:08:50 -0000 @@ -571,8 +571,14 @@ zfs_replay_remove(zfsvfs_t *zfsvfs, lr_r if (error != 0) { VOP_UNLOCK(ZTOV(dzp)); goto fail; } + error = vn_lock(vp, LK_EXCLUSIVE); + if (error != 0) { + VOP_UNLOCK(ZTOV(dzp)); + vrele(vp); + goto fail; + } switch ((int)lr->lr_common.lrc_txtype) { case TX_REMOVE: error = VOP_REMOVE(ZTOV(dzp), vp, &cn /*,vflg*/); @@ -666,9 +672,8 @@ zfs_replay_rename(zfsvfs_t *zfsvfs, lr_r error = VOP_LOOKUP(ZTOV(sdzp), &svp, &scn); VOP_UNLOCK(ZTOV(sdzp)); if (error != 0) goto fail; - VOP_UNLOCK(svp); tcn.cn_nameptr = tname; tcn.cn_namelen = strlen(tname); tcn.cn_nameiop = RENAME; @@ -681,8 +686,15 @@ zfs_replay_rename(zfsvfs_t *zfsvfs, lr_r tvp = NULL; else if (error != 0) { VOP_UNLOCK(ZTOV(tdzp)); goto fail; + } else { + error = vn_lock(tvp, LK_EXCLUSIVE); + if (error != 0) { + VOP_UNLOCK(ZTOV(tdzp)); + vrele(tvp); + goto fail; + } } error = VOP_RENAME(ZTOV(sdzp), svp, &scn, ZTOV(tdzp), tvp, &tcn /*,vflg*/); return (error); Index: external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c =================================================================== RCS file: /cvsroot/src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c,v retrieving revision 1.16 diff -p -u -4 -r1.16 zfs_vnops.c --- external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c 23 Jan 2014 10:13:55 -0000 1.16 +++ external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c 3 Feb 2014 09:08:51 -0000 @@ -4812,9 +4812,9 @@ zfs_netbsd_access(void *v) static int zfs_netbsd_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -4889,29 +4889,21 @@ zfs_netbsd_lookup(void *v) goto out; } KASSERT(*vpp != NULL); /* XXX Correct? */ - /* - * Do a locking dance in conformance to the VOP_LOOKUP protocol. - */ if ((cnp->cn_namelen == 1) && (cnp->cn_nameptr[0] == '.')) { KASSERT(!(cnp->cn_flags & ISDOTDOT)); KASSERT(dvp == *vpp); } else if ((cnp->cn_namelen == 2) && (cnp->cn_nameptr[0] == '.') && (cnp->cn_nameptr[1] == '.')) { KASSERT(cnp->cn_flags & ISDOTDOT); - VOP_UNLOCK(dvp); - vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); } else { KASSERT(!(cnp->cn_flags & ISDOTDOT)); - vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); } out: KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); - KASSERT((*vpp == NULL) || (VOP_ISLOCKED(*vpp) == LK_EXCLUSIVE)); #if 0 /* Namecache too scary to contemplate. */ /* * Insert name into cache if appropriate. Index: lib/libp2k/p2k.c =================================================================== RCS file: /cvsroot/src/lib/libp2k/p2k.c,v retrieving revision 1.62 diff -p -u -4 -r1.62 p2k.c --- lib/libp2k/p2k.c 23 Jan 2014 10:13:55 -0000 1.62 +++ lib/libp2k/p2k.c 3 Feb 2014 09:09:33 -0000 @@ -730,9 +730,8 @@ p2k_node_lookup(struct puffs_usermount * rv = ENOENT; } return rv; } - RUMP_VOP_UNLOCK(vp); p2n = getp2n(p2m, vp, false, NULL); if (p2n == NULL) { return ENOMEM; Index: share/man/man9/namecache.9 =================================================================== RCS file: /cvsroot/src/share/man/man9/namecache.9,v retrieving revision 1.17 diff -p -u -4 -r1.17 namecache.9 --- share/man/man9/namecache.9 5 Nov 2012 22:49:14 -0000 1.17 +++ share/man/man9/namecache.9 3 Feb 2014 09:09:36 -0000 @@ -26,9 +26,9 @@ .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd November 5, 2012 +.Dd February 2, 2014 .Dt NAMECACHE 9 .Os .Sh NAME .Nm namecache , @@ -156,10 +156,9 @@ that requires aborting the operation in On a cache miss, .Fn cache_lookup returns zero .Pq false . -On a positive hit, the vnode for the object found is locked and stored -in +On a positive hit, the unlocked vnode for the object found is stored in .Fa vpp , and a nonzero .Pq true value is returned. Index: share/man/man9/vnodeops.9 =================================================================== RCS file: /cvsroot/src/share/man/man9/vnodeops.9,v retrieving revision 1.91 diff -p -u -4 -r1.91 vnodeops.9 --- share/man/man9/vnodeops.9 23 Jan 2014 10:13:56 -0000 1.91 +++ share/man/man9/vnodeops.9 3 Feb 2014 09:09:36 -0000 @@ -26,9 +26,9 @@ .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 23, 2014 +.Dd February 2, 2014 .Dt VNODEOPS 9 .Os .Sh NAME .Nm vnodeops , @@ -366,9 +366,9 @@ The argument is the locked vnode of the directory to search and .Fa cnp is the pathname component to be searched for. If the pathname component is found, the address of the resulting -locked vnode is returned in +unlocked vnode is returned in .Fa vpp . The operation specified in .Em cnp-\*[Gt]cn_nameiop indicates @@ -381,24 +381,17 @@ There are three types of lookups: ".", " If the pathname component being searched for is ".", then .Fa dvp has an extra reference added to it and it is returned in .Fa *vpp . -If the pathname component being search for is ".." (ISDOTDOT), -.Fa dvp -is unlocked, the ".." node is locked and then -.Fa dvp -is relocked. -This process preserves the protocol of always locking nodes from root -downward and prevents deadlock. For other pathname components, .Fn VOP_LOOKUP checks the accessibility of the directory and searches the name cache for the pathname component. See .Xr namecache 9 . If the pathname is not found in the name cache, the directory is searched for the pathname. -The resulting locked vnode is returned in +The resulting unlocked vnode is returned in .Fa vpp . .Fa dvp is always returned locked. .Pp @@ -410,9 +403,9 @@ and .Fa *dvp is left locked. If the operation is successful .Fa *vpp -is locked and zero is returned. +is unlocked and zero is returned. Typically, if .Fa *vpp and .Fa dvp Index: sys/coda/coda_vnops.c =================================================================== RCS file: /cvsroot/src/sys/coda/coda_vnops.c,v retrieving revision 1.93 diff -p -u -4 -r1.93 coda_vnops.c --- sys/coda/coda_vnops.c 23 Jan 2014 10:13:56 -0000 1.93 +++ sys/coda/coda_vnops.c 3 Feb 2014 09:09:45 -0000 @@ -881,9 +881,9 @@ coda_inactive(void *v) int coda_lookup(void *v) { /* true args */ - struct vop_lookup_args *ap = v; + struct vop_lookup_v2_args *ap = v; /* (locked) vnode of dir in which to do lookup */ vnode_t *dvp = ap->a_dvp; struct cnode *dcp = VTOC(dvp); /* output variable for result */ @@ -895,9 +895,8 @@ coda_lookup(void *v) /* locals */ struct cnode *cp; const char *nm = cnp->cn_nameptr; int len = cnp->cn_namelen; - int flags = cnp->cn_flags; CodaFid VFid; int vtype; int error = 0; @@ -911,11 +910,9 @@ coda_lookup(void *v) */ /* * The overall strategy is to switch on the lookup type and get a - * result vnode that is vref'd but not locked. Then, the code at - * exit: switches on ., .., and regular lookups and does the right - * locking. + * result vnode that is vref'd but not locked. */ /* Check for lookup of control object. */ if (IS_CTL_NAME(dvp, nm, len)) { @@ -989,34 +986,8 @@ coda_lookup(void *v) error = EJUSTRETURN; *ap->a_vpp = NULL; } - /* - * If the lookup succeeded, we must generally lock the returned - * vnode. This could be a ., .., or normal lookup. See - * vnodeops(9) for the details. - */ - /* - * XXX LK_RETRY is likely incorrect. Handle vn_lock failure - * somehow, and remove LK_RETRY. - */ - if (!error || (error == EJUSTRETURN)) { - /* Lookup has a value and it isn't "."? */ - if (*ap->a_vpp && (*ap->a_vpp != dvp)) { - if (flags & ISDOTDOT) - /* ..: unlock parent */ - VOP_UNLOCK(dvp); - /* all but .: lock child */ - vn_lock(*ap->a_vpp, LK_EXCLUSIVE | LK_RETRY); - if (flags & ISDOTDOT) - /* ..: relock parent */ - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); - } - /* else .: leave dvp locked */ - } else { - /* The lookup failed, so return NULL. Leave dvp locked. */ - *ap->a_vpp = NULL; - } return(error); } /*ARGSUSED*/ @@ -1553,11 +1524,8 @@ coda_symlink(void *v) saved_cn_flags = cnp->cn_flags; cnp->cn_flags &= ~(MODMASK | OPMASK); cnp->cn_flags |= LOOKUP; error = VOP_LOOKUP(dvp, ap->a_vpp, cnp); - /* XXX unlock node until lookup returns unlocked nodes. */ - if (error == 0) - VOP_UNLOCK(*ap->a_vpp); cnp->cn_flags = saved_cn_flags; } exit: Index: sys/fs/adosfs/adlookup.c =================================================================== RCS file: /cvsroot/src/sys/fs/adosfs/adlookup.c,v retrieving revision 1.18 diff -p -u -4 -r1.18 adlookup.c --- sys/fs/adosfs/adlookup.c 5 Nov 2012 17:27:37 -0000 1.18 +++ sys/fs/adosfs/adlookup.c 3 Feb 2014 09:09:48 -0000 @@ -63,9 +63,9 @@ __KERNEL_RCSID(0, "$NetBSD: adlookup.c,v */ int adosfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *sp = v; @@ -242,8 +242,10 @@ found: } if (vdp == *vpp) vref(vdp); found_lockdone: + if (*vpp != vdp) + VOP_UNLOCK(*vpp); if (nocache == 0) cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); Index: sys/fs/cd9660/cd9660_lookup.c =================================================================== RCS file: /cvsroot/src/sys/fs/cd9660/cd9660_lookup.c,v retrieving revision 1.25 diff -p -u -4 -r1.25 cd9660_lookup.c --- sys/fs/cd9660/cd9660_lookup.c 23 Jun 2013 07:28:36 -0000 1.25 +++ sys/fs/cd9660/cd9660_lookup.c 3 Feb 2014 09:09:48 -0000 @@ -93,9 +93,9 @@ struct nchstats iso_nchstats; */ int cd9660_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -401,8 +401,11 @@ found: /* * Insert name into cache if appropriate. */ cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); + + if (*vpp != vdp) + VOP_UNLOCK(*vpp); return 0; } /* Index: sys/fs/efs/efs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/efs/efs_vnops.c,v retrieving revision 1.30 diff -p -u -4 -r1.30 efs_vnops.c --- sys/fs/efs/efs_vnops.c 18 Mar 2013 19:35:36 -0000 1.30 +++ sys/fs/efs/efs_vnops.c 3 Feb 2014 09:09:48 -0000 @@ -57,9 +57,9 @@ MALLOC_DECLARE(M_EFSTMP); */ static int efs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -124,8 +124,11 @@ efs_lookup(void *v) cache_enter(ap->a_dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); + if (*ap->a_vpp != ap->a_dvp) + VOP_UNLOCK(*ap->a_vpp); + return 0; } static int Index: sys/fs/filecorefs/filecore_lookup.c =================================================================== RCS file: /cvsroot/src/sys/fs/filecorefs/filecore_lookup.c,v retrieving revision 1.18 diff -p -u -4 -r1.18 filecore_lookup.c --- sys/fs/filecorefs/filecore_lookup.c 20 Oct 2013 17:14:48 -0000 1.18 +++ sys/fs/filecorefs/filecore_lookup.c 3 Feb 2014 09:09:48 -0000 @@ -119,9 +119,9 @@ struct nchstats filecore_nchstats; */ int filecore_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -315,6 +315,8 @@ found: * Insert name into cache if appropriate. */ cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); + if (*vpp != vdp) + VOP_UNLOCK(*vpp); return 0; } Index: sys/fs/hfs/hfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/hfs/hfs_vnops.c,v retrieving revision 1.28 diff -p -u -4 -r1.28 hfs_vnops.c --- sys/fs/hfs/hfs_vnops.c 18 Oct 2013 19:58:11 -0000 1.28 +++ sys/fs/hfs/hfs_vnops.c 3 Feb 2014 09:09:49 -0000 @@ -319,9 +319,9 @@ const struct vnodeopv_desc hfs_fifoop_op int hfs_vop_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode * a_dvp; struct vnode ** a_vpp; struct componentname * a_cnp; } */ *ap = v; @@ -474,8 +474,10 @@ hfs_vop_lookup(void *v) #if 0 cache_enter(vdp, *vpp, cnp); #endif + if (*vpp != vdp) + VOP_UNLOCK(*vpp); error = 0; /* FALLTHROUGH */ error: Index: sys/fs/msdosfs/msdosfs_lookup.c =================================================================== RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_lookup.c,v retrieving revision 1.31 diff -p -u -4 -r1.31 msdosfs_lookup.c --- sys/fs/msdosfs/msdosfs_lookup.c 23 Jan 2014 10:13:56 -0000 1.31 +++ sys/fs/msdosfs/msdosfs_lookup.c 3 Feb 2014 09:09:49 -0000 @@ -93,9 +93,9 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_look */ int msdosfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -493,8 +493,9 @@ foundroot: } if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) return (error); *vpp = DETOV(tdp); + VOP_UNLOCK(*vpp); return (0); } /* @@ -524,8 +525,9 @@ foundroot: if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) return (error); *vpp = DETOV(tdp); + VOP_UNLOCK(*vpp); return (0); } /* @@ -569,8 +571,11 @@ foundroot: * Insert name into cache if appropriate. */ cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); + if (*vpp != vdp) + VOP_UNLOCK(*vpp); + return 0; } #endif /* _KERNEL */ Index: sys/fs/nilfs/nilfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/nilfs/nilfs_vnops.c,v retrieving revision 1.26 diff -p -u -4 -r1.26 nilfs_vnops.c --- sys/fs/nilfs/nilfs_vnops.c 23 Jan 2014 10:13:56 -0000 1.26 +++ sys/fs/nilfs/nilfs_vnops.c 3 Feb 2014 09:09:49 -0000 @@ -612,9 +612,9 @@ nilfs_readdir(void *v) int nilfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -770,8 +770,10 @@ out: cnp->cn_flags); DPRINTFIF(LOOKUP, error, ("nilfs_lookup returing error %d\n", error)); + if (error == 0 && *vpp != dvp) + VOP_UNLOCK(*vpp); return error; } /* --------------------------------------------------------------------- */ Index: sys/fs/ntfs/ntfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/ntfs/ntfs_vnops.c,v retrieving revision 1.55 diff -p -u -4 -r1.55 ntfs_vnops.c --- sys/fs/ntfs/ntfs_vnops.c 18 Mar 2013 19:35:38 -0000 1.55 +++ sys/fs/ntfs/ntfs_vnops.c 3 Feb 2014 09:09:50 -0000 @@ -648,9 +648,9 @@ ntfs_readdir(void *v) int ntfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -729,8 +729,11 @@ ntfs_lookup(void *v) cache_enter(dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); + if (*ap->a_vpp != dvp) + VOP_UNLOCK(*ap->a_vpp); + return error; } /* Index: sys/fs/ptyfs/ptyfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/ptyfs/ptyfs_vnops.c,v retrieving revision 1.42 diff -p -u -4 -r1.42 ptyfs_vnops.c --- sys/fs/ptyfs/ptyfs_vnops.c 5 Nov 2013 00:40:33 -0000 1.42 +++ sys/fs/ptyfs/ptyfs_vnops.c 3 Feb 2014 09:09:50 -0000 @@ -581,9 +581,9 @@ ptyfs_access(void *v) */ int ptyfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode * a_dvp; struct vnode ** a_vpp; struct componentname * a_cnp; } */ *ap = v; @@ -620,8 +620,10 @@ ptyfs_lookup(void *v) break; error = ptyfs_allocvp(dvp->v_mount, vpp, PTYFSpts, pty, curlwp); + if (error == 0) + VOP_UNLOCK(*vpp); return error; default: return ENOTDIR; Index: sys/fs/puffs/puffs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/puffs/puffs_vnops.c,v retrieving revision 1.179 diff -p -u -4 -r1.179 puffs_vnops.c --- sys/fs/puffs/puffs_vnops.c 23 Jan 2014 10:13:56 -0000 1.179 +++ sys/fs/puffs/puffs_vnops.c 3 Feb 2014 09:09:50 -0000 @@ -472,9 +472,9 @@ puffs_abortbutton(struct puffs_mount *pm ((int)((unsigned int)hardclock_ticks - (unsigned int)expire) > 0) int puffs_vnop_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { const struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; @@ -505,20 +505,14 @@ puffs_vnop_lookup(void *v) DPRINTF(("puffs_lookup: \"%s\", parent vnode %p, op: %x\n", cnp->cn_nameptr, dvp, cnp->cn_nameiop)); /* - * If dotdot cache is enabled, unlock parent, lock .. - * (grand-parent) and relock parent. + * If dotdot cache is enabled, add reference to .. and return. */ if (PUFFS_USE_DOTDOTCACHE(pmp) && (cnp->cn_flags & ISDOTDOT)) { - VOP_UNLOCK(dvp); - vp = VPTOPP(ap->a_dvp)->pn_parent; vref(vp); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); - *ap->a_vpp = vp; return 0; } @@ -541,9 +535,9 @@ puffs_vnop_lookup(void *v) if (TIMED_OUT(cpn->pn_cn_timeout)) { cache_purge(cvp); /* - * cached vnode (cvp) is still locked + * cached vnode (cvp) is still referenced * so that we can reuse it upon a new * successful lookup. */ *ap->a_vpp = NULL; @@ -581,10 +575,15 @@ puffs_vnop_lookup(void *v) *ap->a_vpp = vp; return 0; } - if (cvp != NULL) - mutex_enter(&cpn->pn_sizemtx); + if (cvp != NULL) { + if (vn_lock(cvp, LK_EXCLUSIVE) != 0) { + vrele(cvp); + cvp = NULL; + } else + mutex_enter(&cpn->pn_sizemtx); + } PUFFS_MSG_ALLOC(vn, lookup); puffs_makecn(&lookup_msg->pvnr_cn, &lookup_msg->pvnr_cn_cred, cnp, PUFFS_USE_FULLPNBUF(pmp)); @@ -721,8 +720,10 @@ puffs_vnop_lookup(void *v) if (error || (cvp != vp)) vput(cvp); } + if (error == 0) + VOP_UNLOCK(*ap->a_vpp); if (cnp->cn_flags & ISDOTDOT) vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); Index: sys/fs/smbfs/smbfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/smbfs/smbfs_vnops.c,v retrieving revision 1.88 diff -p -u -4 -r1.88 smbfs_vnops.c --- sys/fs/smbfs/smbfs_vnops.c 23 Jan 2014 10:13:56 -0000 1.88 +++ sys/fs/smbfs/smbfs_vnops.c 3 Feb 2014 09:09:51 -0000 @@ -1173,9 +1173,9 @@ smbfs_pathcheck(struct smbmount *smp, co */ int smbfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -1227,12 +1227,9 @@ smbfs_lookup(void *v) error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred); if (error != 0) { if (*vpp != NULLVP) { - if (*vpp != dvp) - vput(*vpp); - else - vrele(*vpp); + vrele(*vpp); } *vpp = NULLVP; return error; } @@ -1246,9 +1243,11 @@ smbfs_lookup(void *v) goto dolookup; } newvp = *vpp; + vn_lock(newvp, LK_SHARED | LK_RETRY); error = VOP_GETATTR(newvp, &vattr, cnp->cn_cred); + VOP_UNLOCK(newvp); /* * If the file type on the server is inconsistent * with what it was when we created the vnode, * kill the bogus vnode now and fall through to @@ -1350,8 +1349,10 @@ smbfs_lookup(void *v) if (flags & ISDOTDOT) vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); if (error) return (error); + if (*vpp != dvp) + VOP_UNLOCK(*vpp); return (0); } if (isdot) { @@ -1393,6 +1394,8 @@ smbfs_lookup(void *v) cnp->cn_flags); #endif } + if (*vpp != dvp) + VOP_UNLOCK(*vpp); return (0); } Index: sys/fs/sysvbfs/sysvbfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/sysvbfs/sysvbfs_vnops.c,v retrieving revision 1.52 diff -p -u -4 -r1.52 sysvbfs_vnops.c --- sys/fs/sysvbfs/sysvbfs_vnops.c 23 Jan 2014 10:13:56 -0000 1.52 +++ sys/fs/sysvbfs/sysvbfs_vnops.c 3 Feb 2014 09:09:51 -0000 @@ -64,9 +64,9 @@ static void sysvbfs_file_setsize(struct int sysvbfs_lookup(void *arg) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *a = arg; @@ -117,8 +117,9 @@ sysvbfs_lookup(void *arg) if ((error = sysvbfs_vget(v->v_mount, dirent->inode, &vpp)) != 0) { DPRINTF("%s: can't get vnode.\n", __func__); return error; } + VOP_UNLOCK(vpp); *a->a_vpp = vpp; } return 0; Index: sys/fs/tmpfs/tmpfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/tmpfs/tmpfs_vnops.c,v retrieving revision 1.114 diff -p -u -4 -r1.114 tmpfs_vnops.c --- sys/fs/tmpfs/tmpfs_vnops.c 23 Jan 2014 10:13:56 -0000 1.114 +++ sys/fs/tmpfs/tmpfs_vnops.c 3 Feb 2014 09:09:51 -0000 @@ -123,9 +123,9 @@ const struct vnodeopv_desc tmpfs_vnodeop */ int tmpfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -170,12 +170,12 @@ tmpfs_lookup(void *v) } if (cachefound && *vpp == NULLVP) { /* Negative cache hit. */ error = ENOENT; - goto out; + goto out_unlocked; } else if (cachefound) { error = 0; - goto out; + goto out_unlocked; } /* * Treat an unlinked directory as empty (no "." or "..") @@ -301,9 +301,11 @@ done: cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); } out: - KASSERT((*vpp && VOP_ISLOCKED(*vpp)) || error); + if (error == 0 && *vpp != dvp) + VOP_UNLOCK(*vpp); +out_unlocked: KASSERT(VOP_ISLOCKED(dvp)); return error; } Index: sys/fs/udf/udf_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/udf/udf_vnops.c,v retrieving revision 1.89 diff -p -u -4 -r1.89 udf_vnops.c --- sys/fs/udf/udf_vnops.c 23 Jan 2014 10:13:56 -0000 1.89 +++ sys/fs/udf/udf_vnops.c 3 Feb 2014 09:09:51 -0000 @@ -638,9 +638,9 @@ udf_readdir(void *v) int udf_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -833,8 +833,10 @@ done: cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); out: + if (error == 0 && *vpp != dvp) + VOP_UNLOCK(*vpp); DPRINTFIF(LOOKUP, error, ("udf_lookup returing error %d\n", error)); return error; } Index: sys/fs/union/union_subr.c =================================================================== RCS file: /cvsroot/src/sys/fs/union/union_subr.c,v retrieving revision 1.59 diff -p -u -4 -r1.59 union_subr.c --- sys/fs/union/union_subr.c 23 Jan 2014 10:13:56 -0000 1.59 +++ sys/fs/union/union_subr.c 3 Feb 2014 09:09:51 -0000 @@ -787,12 +787,9 @@ union_do_lookup(struct vnode *dvp, struc if (error == 0) { KASSERT(vp != NULL); VOP_ABORTOP(dvp, cnp); - if (dvp != vp) - vput(vp); - else - vrele(vp); + vrele(vp); error = EEXIST; } else if (error == EJUSTRETURN) { error = 0; } @@ -1187,9 +1184,9 @@ union_check_rmdir(struct union_node *un, error = 0; continue; } if (error == 0) - vput(tvp); + vrele(tvp); error = ENOTEMPTY; } } while (error == 0 && !eofflag); kmem_free(dirbuf, dirlen); Index: sys/fs/union/union_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/union/union_vnops.c,v retrieving revision 1.51 diff -p -u -4 -r1.51 union_vnops.c --- sys/fs/union/union_vnops.c 23 Jan 2014 10:13:56 -0000 1.51 +++ sys/fs/union/union_vnops.c 3 Feb 2014 09:09:51 -0000 @@ -227,8 +227,13 @@ union_lookup1(struct vnode *udvp, struct error = VOP_LOOKUP(dvp, &tdvp, cnp); if (error) return (error); + error = vn_lock(tdvp, LK_EXCLUSIVE); + if (error) { + vrele(tdvp); + return error; + } dvp = tdvp; /* @@ -255,9 +260,9 @@ union_lookup1(struct vnode *udvp, struct int union_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; @@ -309,8 +314,10 @@ start: if (upperdvp != NULLVP) { uerror = union_lookup1(um->um_uppervp, &upperdvp, &uppervp, cnp); if (cnp->cn_consume != 0) { + if (uppervp != upperdvp) + VOP_UNLOCK(uppervp); *ap->a_vpp = uppervp; return (uerror); } if (uerror == ENOENT || uerror == EJUSTRETURN) { @@ -483,8 +490,11 @@ start: if (lowervp != NULLVP) vrele(lowervp); } + if (error == 0 && *ap->a_vpp != dvp) + VOP_UNLOCK(*ap->a_vpp); + return (error); } int Index: sys/fs/v7fs/v7fs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/v7fs/v7fs_vnops.c,v retrieving revision 1.15 diff -p -u -4 -r1.15 v7fs_vnops.c --- sys/fs/v7fs/v7fs_vnops.c 23 Jan 2014 10:13:56 -0000 1.15 +++ sys/fs/v7fs/v7fs_vnops.c 3 Feb 2014 09:09:52 -0000 @@ -89,9 +89,9 @@ v7fs_mode_to_d_type(v7fs_mode_t mode) int v7fs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *a = v; @@ -179,8 +179,10 @@ v7fs_lookup(void *v) DPRINTF("exit vget\n"); if (isdotdot) { vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); } + if (vpp != dvp) + VOP_UNLOCK(vpp); *a->a_vpp = vpp; DPRINTF("done.(%s)\n", name); return 0; Index: sys/kern/vfs_cache.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_cache.c,v retrieving revision 1.93 diff -p -u -4 -r1.93 vfs_cache.c --- sys/kern/vfs_cache.c 20 Jan 2014 07:47:22 -0000 1.93 +++ sys/kern/vfs_cache.c 3 Feb 2014 09:09:52 -0000 @@ -464,29 +464,9 @@ cache_lookup(struct vnode *dvp, const ch */ ncp = NULL; #endif /* DEBUG */ - if (vp == dvp) { /* lookup on "." */ - error = 0; - } else if (cnflags & ISDOTDOT) { - VOP_UNLOCK(dvp); - error = vn_lock(vp, LK_EXCLUSIVE); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); - } else { - error = vn_lock(vp, LK_EXCLUSIVE); - } - - /* - * Check that the lock succeeded. - */ - if (error) { - /* We don't have the right lock, but this is only for stats. */ - COUNT(cpup->cpu_stats, ncs_badhits); - - vrele(vp); - /* found nothing */ - return 0; - } + KASSERT(error == 0); /* We don't have the right lock, but this is only for stats. */ COUNT(cpup->cpu_stats, ncs_goodhits); Index: sys/kern/vfs_getcwd.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_getcwd.c,v retrieving revision 1.49 diff -p -u -4 -r1.49 vfs_getcwd.c --- sys/kern/vfs_getcwd.c 9 Jun 2013 18:29:25 -0000 1.49 +++ sys/kern/vfs_getcwd.c 3 Feb 2014 09:09:52 -0000 @@ -131,20 +131,24 @@ getcwd_scandir(struct vnode **lvpp, stru cn.cn_nameptr = ".."; cn.cn_namelen = 2; cn.cn_consume = 0; - /* - * At this point, lvp is locked. - * On successful return, *uvpp will be locked - */ + /* At this point, lvp is locked */ error = VOP_LOOKUP(lvp, uvpp, &cn); vput(lvp); if (error) { *lvpp = NULL; *uvpp = NULL; return error; } uvp = *uvpp; + /* Now lvp is unlocked, try to lock uvp */ + error = vn_lock(uvp, LK_EXCLUSIVE); + if (error) { + *lvpp = NULL; + *uvpp = NULL; + return error; + } /* If we don't care about the pathname, we're done */ if (bufp == NULL) { *lvpp = NULL; Index: sys/kern/vfs_lookup.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_lookup.c,v retrieving revision 1.200 diff -p -u -4 -r1.200 vfs_lookup.c --- sys/kern/vfs_lookup.c 18 Nov 2012 17:41:53 -0000 1.200 +++ sys/kern/vfs_lookup.c 3 Feb 2014 09:09:52 -0000 @@ -1053,11 +1053,22 @@ unionlookup: cnp->cn_flags |= ISLASTCN; } /* - * "foundobj" and "searchdir" are both locked and held, - * and may be the same vnode. + * "searchdir" is locked and held, "foundobj" is held, + * they may be the same vnode. */ + if (searchdir != foundobj) { + if (cnp->cn_flags & ISDOTDOT) + VOP_UNLOCK(searchdir); + error = vn_lock(foundobj, LK_EXCLUSIVE); + if (cnp->cn_flags & ISDOTDOT) + vn_lock(searchdir, LK_EXCLUSIVE | LK_RETRY); + if (error != 0) { + vrele(foundobj); + goto done; + } + } /* * Check to see if the vnode has been mounted on; * if so find the root of the mounted file system. @@ -1750,12 +1761,22 @@ relookup(struct vnode *dvp, struct vnode */ if (rdonly && cnp->cn_nameiop != LOOKUP) { error = EROFS; if (*vpp) { - vput(*vpp); + vrele(*vpp); } goto bad; } + /* + * Lock result. + */ + if (*vpp && *vpp != dvp) { + error = vn_lock(*vpp, LK_EXCLUSIVE); + if (error != 0) { + vrele(*vpp); + goto bad; + } + } return (0); bad: *vpp = NULL; Index: sys/kern/vnode_if.c =================================================================== RCS file: /cvsroot/src/sys/kern/vnode_if.c,v retrieving revision 1.91 diff -p -u -4 -r1.91 vnode_if.c --- sys/kern/vnode_if.c 23 Jan 2014 10:13:57 -0000 1.91 +++ sys/kern/vnode_if.c 3 Feb 2014 09:09:52 -0000 @@ -1,5 +1,5 @@ -/* $NetBSD: vnode_if.c,v 1.91 2014/01/23 10:13:57 hannken Exp $ */ +/* $NetBSD$ */ /* * Warning: DO NOT EDIT! This file is automatically generated! * (Modifications made here may easily be lost!) @@ -39,9 +39,9 @@ * SUCH DAMAGE. */ #include -__KERNEL_RCSID(0, "$NetBSD: vnode_if.c,v 1.91 2014/01/23 10:13:57 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #include #include #include @@ -89,28 +89,28 @@ VOP_BWRITE(struct vnode *vp, return error; } const int vop_lookup_vp_offsets[] = { - VOPARG_OFFSETOF(struct vop_lookup_args,a_dvp), + VOPARG_OFFSETOF(struct vop_lookup_v2_args,a_dvp), VDESC_NO_OFFSET }; const struct vnodeop_desc vop_lookup_desc = { VOP_LOOKUP_DESCOFFSET, "vop_lookup", 0, vop_lookup_vp_offsets, - VOPARG_OFFSETOF(struct vop_lookup_args, a_vpp), + VOPARG_OFFSETOF(struct vop_lookup_v2_args, a_vpp), VDESC_NO_OFFSET, - VOPARG_OFFSETOF(struct vop_lookup_args, a_cnp), + VOPARG_OFFSETOF(struct vop_lookup_v2_args, a_cnp), }; int VOP_LOOKUP(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) { int error; bool mpsafe; - struct vop_lookup_args a; + struct vop_lookup_v2_args a; a.a_desc = VDESC(vop_lookup); a.a_dvp = dvp; a.a_vpp = vpp; a.a_cnp = cnp; Index: sys/kern/vnode_if.src =================================================================== RCS file: /cvsroot/src/sys/kern/vnode_if.src,v retrieving revision 1.65 diff -p -u -4 -r1.65 vnode_if.src --- sys/kern/vnode_if.src 23 Jan 2014 10:11:55 -0000 1.65 +++ sys/kern/vnode_if.src 3 Feb 2014 09:09:52 -0000 @@ -60,29 +60,19 @@ vop_bwrite { }; # #% lookup dvp L L L -#% lookup vpp - L - +#% lookup vpp - U - # -# XXX - the lookup locking protocol defies simple description. # Note especially that *vpp may equal dvp. # # More details: -# There are three types of lookups: ".", ".." (ISDOTDOT), and other. -# On successful lookup of ".", a reference is added to dvp, and it -# is returned in *vpp. -# To look up ISDOTDOT, dvp is unlocked, the ".." node is locked, and -# then dvp is relocked. This preserves the protocol of always -# locking nodes from root ("/") downward and prevents deadlock. -# Other lookups find the named node (creating the vnode if needed) and -# return it, locked, in *vpp. +# All lookups find the named node (creating the vnode if needed) and +# return it, referenced and unlocked, in *vpp. # On failure, *vpp is NULL, and *dvp is left locked. -# -# *vpp is always locked on return if the operation succeeds. -# Typically, if *vpp == dvp, you need to release twice, but -# unlock only once. # vop_lookup { + VERSION 2 IN struct vnode *dvp; OUT WILLMAKE struct vnode **vpp; IN struct componentname *cnp; }; Index: sys/miscfs/deadfs/dead_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/deadfs/dead_vnops.c,v retrieving revision 1.53 diff -p -u -4 -r1.53 dead_vnops.c --- sys/miscfs/deadfs/dead_vnops.c 17 Jan 2014 10:55:02 -0000 1.53 +++ sys/miscfs/deadfs/dead_vnops.c 3 Feb 2014 09:09:52 -0000 @@ -137,9 +137,9 @@ dead_bmap(void *v) int dead_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; Index: sys/miscfs/fdesc/fdesc_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/fdesc/fdesc_vnops.c,v retrieving revision 1.116 diff -p -u -4 -r1.116 fdesc_vnops.c --- sys/miscfs/fdesc/fdesc_vnops.c 23 Jan 2014 10:13:57 -0000 1.116 +++ sys/miscfs/fdesc/fdesc_vnops.c 3 Feb 2014 09:09:52 -0000 @@ -262,9 +262,9 @@ loop: */ int fdesc_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode * a_dvp; struct vnode ** a_vpp; struct componentname * a_cnp; } */ *ap = v; @@ -396,8 +396,9 @@ bad: *vpp = NULL; return (error); good: + VOP_UNLOCK(*vpp); return (0); } int Index: sys/miscfs/fifofs/fifo_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/fifofs/fifo_vnops.c,v retrieving revision 1.73 diff -p -u -4 -r1.73 fifo_vnops.c --- sys/miscfs/fifofs/fifo_vnops.c 8 Apr 2013 21:12:33 -0000 1.73 +++ sys/miscfs/fifofs/fifo_vnops.c 3 Feb 2014 09:09:52 -0000 @@ -101,9 +101,9 @@ struct fifoinfo { /* ARGSUSED */ static int fifo_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; Index: sys/miscfs/genfs/layer_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/genfs/layer_vnops.c,v retrieving revision 1.53 diff -p -u -4 -r1.53 layer_vnops.c --- sys/miscfs/genfs/layer_vnops.c 29 Jan 2014 08:27:04 -0000 1.53 +++ sys/miscfs/genfs/layer_vnops.c 3 Feb 2014 09:09:52 -0000 @@ -337,9 +337,9 @@ layer_bypass(void *v) */ int layer_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnodeop_desc *a_desc; struct vnode * a_dvp; struct vnode ** a_vpp; struct componentname * a_cnp; @@ -380,12 +380,12 @@ layer_lookup(void *v) vref(dvp); *ap->a_vpp = dvp; vrele(lvp); } else if (lvp != NULL) { - /* Note: dvp, ldvp and lvp are all locked. */ + /* Note: dvp and ldvp are all locked. */ error = layer_node_create(dvp->v_mount, lvp, ap->a_vpp); if (error) { - vput(lvp); + vrele(lvp); } } return error; } Index: sys/miscfs/kernfs/kernfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/kernfs/kernfs_vnops.c,v retrieving revision 1.149 diff -p -u -4 -r1.149 kernfs_vnops.c --- sys/miscfs/kernfs/kernfs_vnops.c 23 Jan 2014 10:13:57 -0000 1.149 +++ sys/miscfs/kernfs/kernfs_vnops.c 3 Feb 2014 09:09:52 -0000 @@ -467,9 +467,9 @@ kernfs_xwrite(const struct kernfs_node * */ int kernfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode * a_dvp; struct vnode ** a_vpp; struct componentname * a_cnp; } */ *ap = v; @@ -519,8 +519,10 @@ kernfs_lookup(void *v) break; found: error = kernfs_allocvp(dvp->v_mount, vpp, kt->kt_tag, kt, 0); + if (error == 0) + VOP_UNLOCK(*vpp); return (error); case KFSsubdir: ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data; Index: sys/miscfs/procfs/procfs_subr.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_subr.c,v retrieving revision 1.103 diff -p -u -4 -r1.103 procfs_subr.c --- sys/miscfs/procfs/procfs_subr.c 29 Oct 2013 09:53:51 -0000 1.103 +++ sys/miscfs/procfs/procfs_subr.c 3 Feb 2014 09:09:52 -0000 @@ -119,9 +119,9 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_subr. #include void procfs_hashins(struct pfsnode *); void procfs_hashrem(struct pfsnode *); -struct vnode *procfs_hashget(pid_t, pfstype, int, struct mount *, int); +struct vnode *procfs_hashget(pid_t, pfstype, int, struct mount *); LIST_HEAD(pfs_hashhead, pfsnode) *pfs_hashtbl; u_long pfs_ihash; /* size of hash table - 1 */ #define PFSPIDHASH(pid) ((pid) & pfs_ihash) @@ -164,10 +164,9 @@ procfs_allocvp(struct mount *mp, struct struct pfsnode *pfs; struct vnode *vp; int error; - retry: - *vpp = procfs_hashget(pid, pfs_type, fd, mp, LK_EXCLUSIVE); + *vpp = procfs_hashget(pid, pfs_type, fd, mp); if (*vpp != NULL) return (0); error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, NULL, &vp); @@ -177,13 +176,13 @@ procfs_allocvp(struct mount *mp, struct } pfs = malloc(sizeof(struct pfsnode), M_TEMP, M_WAITOK); mutex_enter(&pfs_hashlock); - if ((*vpp = procfs_hashget(pid, pfs_type, fd, mp, 0)) != NULL) { + if ((*vpp = procfs_hashget(pid, pfs_type, fd, mp)) != NULL) { mutex_exit(&pfs_hashlock); ungetnewvnode(vp); free(pfs, M_TEMP); - goto retry; + return 0; } vp->v_data = pfs; pfs->pfs_pid = pid; @@ -598,9 +597,9 @@ procfs_hashdone(void) mutex_destroy(&pfs_ihash_lock); } struct vnode * -procfs_hashget(pid_t pid, pfstype type, int fd, struct mount *mp, int flags) +procfs_hashget(pid_t pid, pfstype type, int fd, struct mount *mp) { struct pfs_hashhead *ppp; struct pfsnode *pp; struct vnode *vp; @@ -611,16 +610,12 @@ loop: LIST_FOREACH(pp, ppp, pfs_hash) { vp = PFSTOV(pp); if (pid == pp->pfs_pid && pp->pfs_type == type && pp->pfs_fd == fd && vp->v_mount == mp) { - if (flags == 0) { - mutex_exit(&pfs_ihash_lock); - } else { - mutex_enter(vp->v_interlock); - mutex_exit(&pfs_ihash_lock); - if (vget(vp, flags)) - goto loop; - } + mutex_enter(vp->v_interlock); + mutex_exit(&pfs_ihash_lock); + if (vget(vp, 0)) + goto loop; return (vp); } } mutex_exit(&pfs_ihash_lock); @@ -634,11 +629,8 @@ void procfs_hashins(struct pfsnode *pp) { struct pfs_hashhead *ppp; - /* lock the pfsnode, then put it on the appropriate hash list */ - VOP_LOCK(PFSTOV(pp), LK_EXCLUSIVE); - mutex_enter(&pfs_ihash_lock); ppp = &pfs_hashtbl[PFSPIDHASH(pp->pfs_pid)]; LIST_INSERT_HEAD(ppp, pp, pfs_hash); mutex_exit(&pfs_ihash_lock); Index: sys/miscfs/procfs/procfs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vfsops.c,v retrieving revision 1.87 diff -p -u -4 -r1.87 procfs_vfsops.c --- sys/miscfs/procfs/procfs_vfsops.c 30 Apr 2012 22:51:28 -0000 1.87 +++ sys/miscfs/procfs/procfs_vfsops.c 3 Feb 2014 09:09:52 -0000 @@ -198,10 +198,20 @@ procfs_unmount(struct mount *mp, int mnt int procfs_root(struct mount *mp, struct vnode **vpp) { + int error; + + error = procfs_allocvp(mp, vpp, 0, PFSroot, -1, NULL); + if (error == 0) { + error = vn_lock(*vpp, LK_EXCLUSIVE); + if (error != 0) { + vrele(*vpp); + *vpp = NULL; + } + } - return (procfs_allocvp(mp, vpp, 0, PFSroot, -1, NULL)); + return error; } /* ARGSUSED */ int Index: sys/miscfs/procfs/procfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vnops.c,v retrieving revision 1.188 diff -p -u -4 -r1.188 procfs_vnops.c --- sys/miscfs/procfs/procfs_vnops.c 23 Jan 2014 10:13:57 -0000 1.188 +++ sys/miscfs/procfs/procfs_vnops.c 3 Feb 2014 09:09:53 -0000 @@ -981,9 +981,9 @@ procfs_access(void *v) */ int procfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode * a_dvp; struct vnode ** a_vpp; struct componentname * a_cnp; } */ *ap = v; @@ -1059,18 +1059,11 @@ procfs_lookup(void *v) procfs_proc_unlock(p); return (error); case PFSproc: - /* - * do the .. dance. We unlock the directory, and then - * get the root dir. That will automatically return .. - * locked. Then if the caller wanted dvp locked, we - * re-lock. - */ if (cnp->cn_flags & ISDOTDOT) { - VOP_UNLOCK(dvp); - error = procfs_root(dvp->v_mount, vpp); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); + error = procfs_allocvp(dvp->v_mount, vpp, 0, PFSroot, + -1, NULL); return (error); } if (procfs_proc_lock(pfs->pfs_pid, &p, ESRCH) != 0) @@ -1111,9 +1104,8 @@ procfs_lookup(void *v) fvp = p->p_textvp; /* We already checked that it exists. */ vref(fvp); procfs_proc_unlock(p); - vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY); *vpp = fvp; return (0); } @@ -1128,19 +1120,12 @@ procfs_lookup(void *v) if ((error = procfs_proc_lock(pfs->pfs_pid, &p, ENOENT)) != 0) return error; - /* - * do the .. dance. We unlock the directory, and then - * get the proc dir. That will automatically return .. - * locked. Then re-lock the directory. - */ if (cnp->cn_flags & ISDOTDOT) { - VOP_UNLOCK(dvp); error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, PFSproc, -1, p); procfs_proc_unlock(p); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); return (error); } fd = atoi(pname, cnp->cn_namelen); @@ -1155,9 +1140,8 @@ procfs_lookup(void *v) if (fp->f_type == DTYPE_VNODE && fvp->v_type != VDIR) { vref(fvp); closef(fp); procfs_proc_unlock(p); - vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY); *vpp = fvp; return 0; } @@ -1172,19 +1156,12 @@ procfs_lookup(void *v) if ((error = procfs_proc_lock(pfs->pfs_pid, &p, ENOENT)) != 0) return error; - /* - * do the .. dance. We unlock the directory, and then - * get the proc dir. That will automatically return .. - * locked. Then re-lock the directory. - */ if (cnp->cn_flags & ISDOTDOT) { - VOP_UNLOCK(dvp); error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, PFSproc, -1, p); procfs_proc_unlock(p); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); return (error); } xpid = atoi(pname, cnp->cn_namelen); Index: sys/miscfs/specfs/spec_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/specfs/spec_vnops.c,v retrieving revision 1.141 diff -p -u -4 -r1.141 spec_vnops.c --- sys/miscfs/specfs/spec_vnops.c 30 Sep 2013 18:58:00 -0000 1.141 +++ sys/miscfs/specfs/spec_vnops.c 3 Feb 2014 09:09:53 -0000 @@ -467,9 +467,9 @@ spec_node_destroy(vnode_t *vp) */ int spec_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; Index: sys/miscfs/umapfs/umap_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/umapfs/umap_vnops.c,v retrieving revision 1.53 diff -p -u -4 -r1.53 umap_vnops.c --- sys/miscfs/umapfs/umap_vnops.c 11 Jul 2011 08:27:39 -0000 1.53 +++ sys/miscfs/umapfs/umap_vnops.c 3 Feb 2014 09:09:53 -0000 @@ -330,9 +330,9 @@ umap_bypass(void *v) */ int umap_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnodeop_desc *a_desc; struct vnode * a_dvp; struct vnode ** a_vpp; struct componentname * a_cnp; @@ -400,9 +400,9 @@ umap_lookup(void *v) vrele(vp); } else if (vp != NULL) { error = layer_node_create(mp, vp, ap->a_vpp); if (error) { - vput(vp); + vrele(vp); } } /* Index: sys/nfs/nfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.303 diff -p -u -4 -r1.303 nfs_vnops.c --- sys/nfs/nfs_vnops.c 23 Jan 2014 10:13:57 -0000 1.303 +++ sys/nfs/nfs_vnops.c 3 Feb 2014 09:09:53 -0000 @@ -760,9 +760,9 @@ nfs_setattrrpc(struct vnode *vp, struct */ int nfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; @@ -858,9 +858,9 @@ nfs_lookup(void *v) newvp = *vpp; if ((flags & ISDOTDOT) != 0) { VOP_UNLOCK(dvp); } - error = vn_lock(newvp, LK_EXCLUSIVE); + error = vn_lock(newvp, LK_SHARED); if ((flags & ISDOTDOT) != 0) { vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); } if (error != 0) { @@ -872,8 +872,9 @@ nfs_lookup(void *v) if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred) && vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime) { nfsstats.lookupcache_hits++; KASSERT(newvp->v_type != VNON); + VOP_UNLOCK(newvp); return (0); } cache_purge1(newvp, NULL, 0, PURGE_PARENTS); vput(newvp); @@ -1047,9 +1048,10 @@ validate: vput(newvp); *vpp = NULL; } } - + if (error == 0 && newvp != dvp) + VOP_UNLOCK(newvp); return error; } /* Index: sys/rump/include/rump/rumpvnode_if.h =================================================================== RCS file: /cvsroot/src/sys/rump/include/rump/rumpvnode_if.h,v retrieving revision 1.15 diff -p -u -4 -r1.15 rumpvnode_if.h --- sys/rump/include/rump/rumpvnode_if.h 23 Jan 2014 10:13:57 -0000 1.15 +++ sys/rump/include/rump/rumpvnode_if.h 3 Feb 2014 09:09:53 -0000 @@ -1,5 +1,5 @@ -/* $NetBSD: rumpvnode_if.h,v 1.15 2014/01/23 10:13:57 hannken Exp $ */ +/* $NetBSD$ */ /* * Warning: DO NOT EDIT! This file is automatically generated! * (Modifications made here may easily be lost!) Index: sys/rump/librump/rumpvfs/rumpfs.c =================================================================== RCS file: /cvsroot/src/sys/rump/librump/rumpvfs/rumpfs.c,v retrieving revision 1.123 diff -p -u -4 -r1.123 rumpfs.c --- sys/rump/librump/rumpvfs/rumpfs.c 23 Jan 2014 10:13:57 -0000 1.123 +++ sys/rump/librump/rumpvfs/rumpfs.c 3 Feb 2014 09:09:54 -0000 @@ -652,9 +652,9 @@ freedir(struct rumpfs_node *rnd, struct */ static int rump_vop_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; }; */ *ap = v; @@ -796,32 +796,20 @@ rump_vop_lookup(void *v) rn = rd->rd_node; getvnode: KASSERT(rn); - if (dotdot) - VOP_UNLOCK(dvp); mutex_enter(&reclock); if ((vp = rn->rn_vp)) { mutex_enter(vp->v_interlock); mutex_exit(&reclock); - if (vget(vp, LK_EXCLUSIVE)) { - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); + if (vget(vp, 0)) { goto getvnode; } *vpp = vp; } else { mutex_exit(&reclock); rv = makevnode(dvp->v_mount, rn, vpp); - if (rv == 0) { - rv = vn_lock(*vpp, LK_EXCLUSIVE); - if (rv != 0) { - vrele(*vpp); - *vpp = NULL; - } - } } - if (dotdot) - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); return rv; } Index: sys/rump/librump/rumpvfs/rumpvnode_if.c =================================================================== RCS file: /cvsroot/src/sys/rump/librump/rumpvfs/rumpvnode_if.c,v retrieving revision 1.14 diff -p -u -4 -r1.14 rumpvnode_if.c --- sys/rump/librump/rumpvfs/rumpvnode_if.c 23 Jan 2014 10:13:57 -0000 1.14 +++ sys/rump/librump/rumpvfs/rumpvnode_if.c 3 Feb 2014 09:09:54 -0000 @@ -1,5 +1,5 @@ -/* $NetBSD: rumpvnode_if.c,v 1.14 2014/01/23 10:13:57 hannken Exp $ */ +/* $NetBSD$ */ /* * Warning: DO NOT EDIT! This file is automatically generated! * (Modifications made here may easily be lost!) @@ -39,9 +39,9 @@ * SUCH DAMAGE. */ #include -__KERNEL_RCSID(0, "$NetBSD: rumpvnode_if.c,v 1.14 2014/01/23 10:13:57 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #include #include #include Index: sys/sys/vnode_if.h =================================================================== RCS file: /cvsroot/src/sys/sys/vnode_if.h,v retrieving revision 1.86 diff -p -u -4 -r1.86 vnode_if.h --- sys/sys/vnode_if.h 23 Jan 2014 10:13:57 -0000 1.86 +++ sys/sys/vnode_if.h 3 Feb 2014 09:09:54 -0000 @@ -1,5 +1,5 @@ -/* $NetBSD: vnode_if.h,v 1.86 2014/01/23 10:13:57 hannken Exp $ */ +/* $NetBSD$ */ /* * Warning: DO NOT EDIT! This file is automatically generated! * (Modifications made here may easily be lost!) @@ -59,9 +59,9 @@ struct vop_bwrite_args { extern const struct vnodeop_desc vop_bwrite_desc; int VOP_BWRITE(struct vnode *, struct buf *); #define VOP_LOOKUP_DESCOFFSET 2 -struct vop_lookup_args { +struct vop_lookup_v2_args { const struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; Index: sys/ufs/chfs/chfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/chfs/chfs_vnops.c,v retrieving revision 1.20 diff -p -u -4 -r1.20 chfs_vnops.c --- sys/ufs/chfs/chfs_vnops.c 23 Jan 2014 10:13:57 -0000 1.20 +++ sys/ufs/chfs/chfs_vnops.c 3 Feb 2014 09:09:54 -0000 @@ -52,11 +52,11 @@ int chfs_lookup(void *v) { - struct vnode *dvp = ((struct vop_lookup_args *) v)->a_dvp; - struct vnode **vpp = ((struct vop_lookup_args *) v)->a_vpp; - struct componentname *cnp = ((struct vop_lookup_args *) v)->a_cnp; + struct vnode *dvp = ((struct vop_lookup_v2_args *) v)->a_dvp; + struct vnode **vpp = ((struct vop_lookup_v2_args *) v)->a_vpp; + struct componentname *cnp = ((struct vop_lookup_v2_args *) v)->a_cnp; int error; struct chfs_inode* ip; struct ufsmount* ump; @@ -160,11 +160,12 @@ chfs_lookup(void *v) cnp->cn_flags); } out: - /* If there were no errors, *vpp cannot be null and it must be - * locked. */ - KASSERT(IFF(error == 0, *vpp != NULL && VOP_ISLOCKED(*vpp))); + if (error == 0 && *vpp != dvp) + VOP_UNLOCK(*vpp); + /* If there were no errors, *vpp cannot be NULL. */ + KASSERT(IFF(error == 0, *vpp != NULL)); KASSERT(VOP_ISLOCKED(dvp)); return error; } Index: sys/ufs/ext2fs/ext2fs_lookup.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_lookup.c,v retrieving revision 1.73 diff -p -u -4 -r1.73 ext2fs_lookup.c --- sys/ufs/ext2fs/ext2fs_lookup.c 22 Jan 2013 09:39:15 -0000 1.73 +++ sys/ufs/ext2fs/ext2fs_lookup.c 3 Feb 2014 09:09:54 -0000 @@ -260,9 +260,9 @@ ext2fs_readdir(void *v) */ int ext2fs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -629,8 +629,10 @@ found: vput(tdp); return (EPERM); } } + if (tdp != vdp) + VOP_UNLOCK(tdp); *vpp = tdp; return (0); } @@ -656,8 +658,10 @@ found: if (flags & ISDOTDOT) vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY); if (error) return (error); + if (tdp != vdp) + VOP_UNLOCK(tdp); *vpp = tdp; return (0); } @@ -702,8 +706,10 @@ found: /* * Insert name into cache if appropriate. */ cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); + if (*vpp != vdp) + VOP_UNLOCK(*vpp); return 0; } /* Index: sys/ufs/lfs/ulfs_extattr.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/ulfs_extattr.c,v retrieving revision 1.6 diff -p -u -4 -r1.6 ulfs_extattr.c --- sys/ufs/lfs/ulfs_extattr.c 8 Jun 2013 22:23:52 -0000 1.6 +++ sys/ufs/lfs/ulfs_extattr.c 3 Feb 2014 09:09:54 -0000 @@ -436,9 +436,9 @@ ulfs_extattr_start(struct mount *mp, str static int ulfs_extattr_lookup(struct vnode *start_dvp, int lockparent, const char *dirname, struct vnode **vp, struct lwp *l) { - struct vop_lookup_args vargs; + struct vop_lookup_v2_args vargs; struct componentname cnp; struct vnode *target_vp; char *pnbuf; int error; @@ -478,10 +478,17 @@ ulfs_extattr_lookup(struct vnode *start_ if (target_vp == start_dvp) panic("ulfs_extattr_lookup: target_vp == start_dvp"); #endif - if ((target_vp != start_dvp) && (lockparent == 0)) - VOP_UNLOCK(start_dvp); + if (target_vp != start_dvp) { + error = vn_lock(target_vp, LK_EXCLUSIVE); + if (lockparent == 0) + VOP_UNLOCK(start_dvp); + if (error) { + vrele(target_vp); + return error; + } + } KASSERT(VOP_ISLOCKED(target_vp) == LK_EXCLUSIVE); *vp = target_vp; return (0); Index: sys/ufs/lfs/ulfs_lookup.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/ulfs_lookup.c,v retrieving revision 1.18 diff -p -u -4 -r1.18 ulfs_lookup.c --- sys/ufs/lfs/ulfs_lookup.c 28 Jan 2014 13:25:53 -0000 1.18 +++ sys/ufs/lfs/ulfs_lookup.c 3 Feb 2014 09:09:54 -0000 @@ -112,9 +112,9 @@ int lfs_dirchk = 0; */ int ulfs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -683,8 +683,10 @@ found: cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); error = 0; out: + if (error == 0 && *vpp != vdp) + VOP_UNLOCK(*vpp); fstrans_done(vdp->v_mount); return error; } Index: sys/ufs/ufs/ufs_extattr.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_extattr.c,v retrieving revision 1.42 diff -p -u -4 -r1.42 ufs_extattr.c --- sys/ufs/ufs/ufs_extattr.c 9 Jun 2013 17:57:09 -0000 1.42 +++ sys/ufs/ufs/ufs_extattr.c 3 Feb 2014 09:09:55 -0000 @@ -436,9 +436,9 @@ ufs_extattr_start(struct mount *mp, stru static int ufs_extattr_lookup(struct vnode *start_dvp, int lockparent, const char *dirname, struct vnode **vp, struct lwp *l) { - struct vop_lookup_args vargs; + struct vop_lookup_v2_args vargs; struct componentname cnp; struct vnode *target_vp; char *pnbuf; int error; @@ -478,10 +478,17 @@ ufs_extattr_lookup(struct vnode *start_d if (target_vp == start_dvp) panic("ufs_extattr_lookup: target_vp == start_dvp"); #endif - if ((target_vp != start_dvp) && (lockparent == 0)) - VOP_UNLOCK(start_dvp); + if (target_vp != start_dvp) { + error = vn_lock(target_vp, LK_EXCLUSIVE); + if (lockparent == 0) + VOP_UNLOCK(start_dvp); + if (error) { + vrele(target_vp); + return error; + } + } KASSERT(VOP_ISLOCKED(target_vp) == LK_EXCLUSIVE); *vp = target_vp; return (0); Index: sys/ufs/ufs/ufs_lookup.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_lookup.c,v retrieving revision 1.128 diff -p -u -4 -r1.128 ufs_lookup.c --- sys/ufs/ufs/ufs_lookup.c 4 Nov 2013 19:58:02 -0000 1.128 +++ sys/ufs/ufs/ufs_lookup.c 3 Feb 2014 09:09:55 -0000 @@ -111,9 +111,9 @@ int dirchk = 0; */ int ufs_lookup(void *v) { - struct vop_lookup_args /* { + struct vop_lookup_v2_args /* { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; } */ *ap = v; @@ -683,8 +683,10 @@ found: cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); error = 0; out: + if (error == 0 && *vpp != vdp) + VOP_UNLOCK(*vpp); fstrans_done(vdp->v_mount); return error; } Index: tests/rump/rumpvfs/t_p2kifs.c =================================================================== RCS file: /cvsroot/src/tests/rump/rumpvfs/t_p2kifs.c,v retrieving revision 1.3 diff -p -u -4 -r1.3 t_p2kifs.c --- tests/rump/rumpvfs/t_p2kifs.c 2 Jan 2011 12:58:17 -0000 1.3 +++ tests/rump/rumpvfs/t_p2kifs.c 3 Feb 2014 09:09:55 -0000 @@ -72,17 +72,15 @@ ATF_TC_BODY(makecn, tc) /* try it once with the right path */ cn = rump_pub_makecn(RUMP_NAMEI_LOOKUP, 0, pathstr, strlen(pathstr), rump_pub_cred_create(0, 0, 0, NULL), rump_pub_lwproc_curlwp()); RZ(RUMP_VOP_LOOKUP(rumpns_rootvnode, &vp, cn)); - RUMP_VOP_UNLOCK(vp); rump_pub_freecn(cn, RUMPCN_FREECRED); /* and then with modification-in-the-middle */ cn = rump_pub_makecn(RUMP_NAMEI_LOOKUP, 0, pathstr, strlen(pathstr), rump_pub_cred_create(0, 0, 0, NULL), rump_pub_lwproc_curlwp()); strcpy(pathstr, "/muuta"); RZ(RUMP_VOP_LOOKUP(rumpns_rootvnode, &vp, cn)); - RUMP_VOP_UNLOCK(vp); rump_pub_freecn(cn, RUMPCN_FREECRED); } ATF_TP_ADD_TCS(tp)