diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c index a00b2121308a..18219a84519a 100644 --- a/sys/fs/ext2fs/ext2_vnops.c +++ b/sys/fs/ext2fs/ext2_vnops.c @@ -919,7 +919,7 @@ ext2_rename(struct vop_rename_args *ap) if (error) goto out; VREF(tdvp); - error = relookup(tdvp, &tvp, tcnp); + error = relookup(tdvp, &tvp, tcnp, true); if (error) goto out; vrele(tdvp); @@ -1045,7 +1045,7 @@ ext2_rename(struct vop_rename_args *ap) fcnp->cn_flags &= ~MODMASK; fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; VREF(fdvp); - error = relookup(fdvp, &fvp, fcnp); + error = relookup(fdvp, &fvp, fcnp, true); if (error == 0) vrele(fdvp); if (fvp != NULL) { diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 36da35257d2c..fa0a5c5879ce 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -1130,8 +1130,6 @@ msdosfs_rename(struct vop_rename_args *ap) } if (error != 0) goto unlock; - if ((tcnp->cn_flags & SAVESTART) == 0) - panic("msdosfs_rename: lost to startdir"); } if (tip != NULL) { diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 03f299ff0a10..d4b167d84bc8 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -783,6 +783,11 @@ nfsvno_namei(struct nfsrv_descript *nd, struct nameidata *ndp, } out1: + if (error) { + NDPOISON_ERROR(ndp); + } else { + NDPOISON_SUCCESS(ndp); + } NFSEXITCODE2(error, nd); return (error); } @@ -1175,7 +1180,6 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp, error = nd->nd_repstat; if (!error && ndp->ni_vp == NULL) { if (nvap->na_type == VREG || nvap->na_type == VSOCK) { - vrele(ndp->ni_startdir); error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); /* For a pNFS server, create the data file on a DS. */ @@ -1216,7 +1220,6 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp, nvap->na_type = VFIFO; if (nvap->na_type != VFIFO && (error = priv_check_cred(nd->nd_cred, PRIV_VFS_MKNOD_DEV))) { - vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); vput(ndp->ni_dvp); goto out; @@ -1227,11 +1230,9 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp, VOP_VPUT_PAIR(ndp->ni_dvp, error == 0 ? &ndp->ni_vp : NULL, false); nfsvno_relpathbuf(ndp); - vrele(ndp->ni_startdir); if (error) goto out; } else { - vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); vput(ndp->ni_dvp); error = ENXIO; @@ -1245,7 +1246,6 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp, * 1 - clean up the lookup * 2 - iff !error and na_size set, truncate it */ - vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); *vpp = ndp->ni_vp; if (ndp->ni_dvp == *vpp) @@ -1288,7 +1288,6 @@ nfsvno_mknod(struct nameidata *ndp, struct nfsvattr *nvap, struct ucred *cred, * Iff doesn't exist, create it. */ if (ndp->ni_vp) { - vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); vput(ndp->ni_dvp); vrele(ndp->ni_vp); @@ -1296,14 +1295,12 @@ nfsvno_mknod(struct nameidata *ndp, struct nfsvattr *nvap, struct ucred *cred, goto out; } if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) { - vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); vput(ndp->ni_dvp); error = NFSERR_BADTYPE; goto out; } if (vtyp == VSOCK) { - vrele(ndp->ni_startdir); error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); VOP_VPUT_PAIR(ndp->ni_dvp, error == 0 ? &ndp->ni_vp : NULL, @@ -1312,7 +1309,6 @@ nfsvno_mknod(struct nameidata *ndp, struct nfsvattr *nvap, struct ucred *cred, } else { if (nvap->na_type != VFIFO && (error = priv_check_cred(cred, PRIV_VFS_MKNOD_DEV))) { - vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); vput(ndp->ni_dvp); goto out; @@ -1322,7 +1318,6 @@ nfsvno_mknod(struct nameidata *ndp, struct nfsvattr *nvap, struct ucred *cred, VOP_VPUT_PAIR(ndp->ni_dvp, error == 0 ? &ndp->ni_vp : NULL, false); nfsvno_relpathbuf(ndp); - vrele(ndp->ni_startdir); /* * Since VOP_MKNOD returns the ni_vp, I can't * see any reason to do the lookup. @@ -1374,7 +1369,6 @@ nfsvno_symlink(struct nameidata *ndp, struct nfsvattr *nvap, char *pathcp, int error = 0; if (ndp->ni_vp) { - vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); if (ndp->ni_dvp == ndp->ni_vp) vrele(ndp->ni_dvp); @@ -1394,7 +1388,6 @@ nfsvno_symlink(struct nameidata *ndp, struct nfsvattr *nvap, char *pathcp, * Just vput it for v2. */ VOP_VPUT_PAIR(ndp->ni_dvp, &ndp->ni_vp, !not_v2 && error == 0); - vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); out: @@ -1647,10 +1640,8 @@ nfsvno_rename(struct nameidata *fromndp, struct nameidata *tondp, NFSD_DEBUG(4, "nfsvno_rename: pnfsremove\n"); } - vrele(tondp->ni_startdir); nfsvno_relpathbuf(tondp); out1: - vrele(fromndp->ni_startdir); nfsvno_relpathbuf(fromndp); NFSEXITCODE(error); return (error); @@ -1867,7 +1858,6 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp, stateidp, stp, NULL, nd, p, nd->nd_repstat); if (!nd->nd_repstat) { if (ndp->ni_vp == NULL) { - vrele(ndp->ni_startdir); nd->nd_repstat = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); /* For a pNFS server, create the data file on a DS. */ @@ -1905,8 +1895,6 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp, } vp = ndp->ni_vp; } else { - if (ndp->ni_startdir) - vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); vp = ndp->ni_vp; if (create == NFSV4OPEN_CREATE) { @@ -1939,16 +1927,16 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp, } } } else { - if (ndp->ni_cnd.cn_flags & HASBUF) + if (ndp->ni_cnd.cn_flags & HASBUF) { nfsvno_relpathbuf(ndp); - if (ndp->ni_startdir && create == NFSV4OPEN_CREATE) { - vrele(ndp->ni_startdir); - if (ndp->ni_dvp == ndp->ni_vp) - vrele(ndp->ni_dvp); - else - vput(ndp->ni_dvp); - if (ndp->ni_vp) - vput(ndp->ni_vp); + if (create == NFSV4OPEN_CREATE) { + if (ndp->ni_dvp == ndp->ni_vp) + vrele(ndp->ni_dvp); + else + vput(ndp->ni_dvp); + if (ndp->ni_vp) + vput(ndp->ni_vp); + } } } *vpp = vp; @@ -4192,7 +4180,7 @@ nfsrv_dscreate(struct vnode *dvp, struct vattr *vap, struct vattr *nvap, int error; NFSNAMEICNDSET(&named.ni_cnd, tcred, CREATE, - LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE); + LOCKPARENT | LOCKLEAF | SAVENAME | NOCACHE); nfsvno_setpathbuf(&named, &bufp, &hashp); named.ni_cnd.cn_lkflags = LK_EXCLUSIVE; named.ni_cnd.cn_nameptr = bufp; diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 21d8fe05c0ad..ae3bc6b39589 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -611,7 +611,7 @@ nfsrvd_lookup(struct nfsrv_descript *nd, __unused int isdgram, } NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, LOOKUP, - LOCKLEAF | SAVESTART); + LOCKLEAF | SAVENAME); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (error) { @@ -636,8 +636,6 @@ nfsrvd_lookup(struct nfsrv_descript *nd, __unused int isdgram, nfsrv_postopattr(nd, dattr_ret, &dattr); goto out; } - if (named.ni_startdir) - vrele(named.ni_startdir); nfsvno_relpathbuf(&named); vp = named.ni_vp; if ((nd->nd_flag & ND_NFSV4) != 0 && !NFSVNO_EXPORTED(exp) && @@ -1160,7 +1158,7 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram, goto out; } NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, - LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE); + LOCKPARENT | LOCKLEAF | SAVENAME | NOCACHE); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (error) @@ -1325,7 +1323,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, struct thread *p = curthread; NFSVNO_ATTRINIT(&nva); - cnflags = (LOCKPARENT | SAVESTART); + cnflags = (LOCKPARENT | SAVENAME); if (nd->nd_repstat) { nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft); goto out; @@ -1633,7 +1631,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram, fdirfor_ret = nfsvno_getattr(dp, &fdirfor, nd, p, 1, NULL); tond.ni_cnd.cn_nameiop = 0; tond.ni_startdir = NULL; - NFSNAMEICNDSET(&fromnd.ni_cnd, nd->nd_cred, DELETE, WANTPARENT | SAVESTART); + NFSNAMEICNDSET(&fromnd.ni_cnd, nd->nd_cred, DELETE, WANTPARENT | SAVENAME); nfsvno_setpathbuf(&fromnd, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &fromnd.ni_pathlen); if (error) { @@ -1694,7 +1692,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram, } } } - NFSNAMEICNDSET(&tond.ni_cnd, nd->nd_cred, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART); + NFSNAMEICNDSET(&tond.ni_cnd, nd->nd_cred, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVENAME); nfsvno_setpathbuf(&tond, &tbufp, &hashp); if (!nd->nd_repstat) { error = nfsrv_parsename(nd, tbufp, hashp, &tond.ni_pathlen); @@ -1901,7 +1899,7 @@ nfsrvd_symlink(struct nfsrv_descript *nd, __unused int isdgram, *vpp = NULL; NFSVNO_ATTRINIT(&nva); NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, - LOCKPARENT | SAVESTART | NOCACHE); + LOCKPARENT | SAVENAME | NOCACHE); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (!error && !nd->nd_repstat) @@ -3020,10 +3018,10 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, } if (create == NFSV4OPEN_CREATE) NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, - LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE); + LOCKPARENT | LOCKLEAF | SAVENAME | NOCACHE); else NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, LOOKUP, - LOCKLEAF | SAVESTART); + LOCKLEAF | SAVENAME); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (error) { @@ -3689,7 +3687,7 @@ nfsrvd_secinfo(struct nfsrv_descript *nd, int isdgram, * All this just to get the export flags for the name. */ NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, LOOKUP, - LOCKLEAF | SAVESTART); + LOCKLEAF | SAVENAME); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (error) { @@ -3707,7 +3705,6 @@ nfsrvd_secinfo(struct nfsrv_descript *nd, int isdgram, vrele(dirp); if (nd->nd_repstat) goto out; - vrele(named.ni_startdir); nfsvno_relpathbuf(&named); fh.nfsrvfh_len = NFSX_MYFH; vp = named.ni_vp; @@ -3823,7 +3820,7 @@ nfsrvd_secinfononame(struct nfsrv_descript *nd, int isdgram, switch (fhstyle) { case NFSSECINFONONAME_PARENT: NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, LOOKUP, - LOCKLEAF | SAVESTART); + LOCKLEAF | SAVENAME); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (error != 0) { @@ -3837,7 +3834,6 @@ nfsrvd_secinfononame(struct nfsrv_descript *nd, int isdgram, vput(dp); if (dirp != NULL) vrele(dirp); - vrele(named.ni_startdir); nfsvno_relpathbuf(&named); vp = named.ni_vp; break; diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c index 08202501fe02..320ecceaf236 100644 --- a/sys/fs/unionfs/union_subr.c +++ b/sys/fs/unionfs/union_subr.c @@ -662,6 +662,7 @@ unionfs_relookup(struct vnode *dvp, struct vnode **vpp, char *path, int pathlen, u_long nameiop) { int error; + bool refstart; cn->cn_namelen = pathlen; cn->cn_pnbuf = path; @@ -671,17 +672,20 @@ unionfs_relookup(struct vnode *dvp, struct vnode **vpp, cn->cn_cred = cnp->cn_cred; cn->cn_nameptr = cn->cn_pnbuf; - if (nameiop == DELETE) - cn->cn_flags |= (cnp->cn_flags & (DOWHITEOUT | SAVESTART)); - else if (RENAME == nameiop) - cn->cn_flags |= (cnp->cn_flags & SAVESTART); - else if (nameiop == CREATE) + refstart = false; + if (nameiop == DELETE) { + cn->cn_flags |= (cnp->cn_flags & DOWHITEOUT); + refstart = (cnp->cn_flags & SAVESTART) != 0; + } else if (nameiop == RENAME) { + refstart = (cnp->cn_flags & SAVESTART) != 0; + } else if (nameiop == CREATE) { cn->cn_flags |= NOCACHE; + } vref(dvp); VOP_UNLOCK(dvp); - if ((error = relookup(dvp, vpp, cn))) { + if ((error = relookup(dvp, vpp, cn, refstart))) { vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); } else vrele(dvp); @@ -1028,7 +1032,7 @@ unionfs_vn_create_on_upper(struct vnode **vpp, struct vnode *udvp, NDPREINIT(&nd); vref(udvp); - if ((error = relookup(udvp, &vp, &nd.ni_cnd)) != 0) + if ((error = relookup(udvp, &vp, &nd.ni_cnd, false)) != 0) goto unionfs_vn_create_on_upper_free_out2; vrele(udvp); diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index e91a43572cbd..44f0d5096c1a 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -504,10 +504,12 @@ namei_emptypath(struct nameidata *ndp) } } SDT_PROBE4(vfs, namei, lookup, return, 0, ndp->ni_vp, false, ndp); + NDPOISON_SUCCESS(ndp); return (0); errout: SDT_PROBE4(vfs, namei, lookup, return, error, NULL, false, ndp); + NDPOISON_ERROR(ndp); return (error); } @@ -594,6 +596,7 @@ namei(struct nameidata *ndp) namei_cleanup_cnp(cnp); SDT_PROBE4(vfs, namei, lookup, return, error, NULL, false, ndp); + NDPOISON_ERROR(ndp); return (error); } @@ -615,8 +618,12 @@ namei(struct nameidata *ndp) __assert_unreachable(); break; case CACHE_FPL_STATUS_HANDLED: - if (error == 0) + if (error == 0) { NDVALIDATE(ndp); + NDPOISON_SUCCESS(ndp); + } else { + NDPOISON_ERROR(ndp); + } return (error); case CACHE_FPL_STATUS_PARTIAL: TAILQ_INIT(&ndp->ni_cap_tracker); @@ -627,6 +634,7 @@ namei(struct nameidata *ndp) error = namei_getpath(ndp); if (__predict_false(error != 0)) { namei_cleanup_cnp(cnp); + NDPOISON_ERROR(ndp); return (error); } /* FALLTHROUGH */ @@ -640,11 +648,13 @@ namei(struct nameidata *ndp) namei_cleanup_cnp(cnp); SDT_PROBE4(vfs, namei, lookup, return, ENOENT, NULL, false, ndp); + NDPOISON_ERROR(ndp); return (ENOENT); } error = namei_setup(ndp, &dp, &pwd); if (error != 0) { namei_cleanup_cnp(cnp); + NDPOISON_ERROR(ndp); return (error); } break; @@ -671,8 +681,12 @@ namei(struct nameidata *ndp) cnp->cn_flags |= HASBUF; nameicap_cleanup(ndp); pwd_drop(pwd); - if (error == 0) + if (error == 0) { NDVALIDATE(ndp); + NDPOISON_SUCCESS(ndp); + } else { + NDPOISON_ERROR(ndp); + } return (error); } if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { @@ -748,6 +762,7 @@ namei(struct nameidata *ndp) namei_cleanup_cnp(cnp); nameicap_cleanup(ndp); pwd_drop(pwd); + NDPOISON_ERROR(ndp); return (error); } @@ -1388,7 +1403,8 @@ lookup(struct nameidata *ndp) * Used by lookup to re-acquire things. */ int -relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) +relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, + bool refstart) { struct vnode *dp = NULL; /* the directory we are searching */ int rdonly; /* lookup read-only flag bit */ @@ -1435,7 +1451,7 @@ relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) VOP_UNLOCK(dp); *vpp = dp; /* XXX This should probably move to the top of function. */ - if (cnp->cn_flags & SAVESTART) + if (refstart) panic("lookup: SAVESTART"); return (0); } @@ -1462,7 +1478,7 @@ relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) goto bad; } /* ASSERT(dvp == ndp->ni_startdir) */ - if (cnp->cn_flags & SAVESTART) + if (refstart) VREF(dvp); if ((cnp->cn_flags & LOCKPARENT) == 0) VOP_UNLOCK(dp); @@ -1500,7 +1516,7 @@ relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) ("relookup: symlink found.\n")); /* ASSERT(dvp == ndp->ni_startdir) */ - if (cnp->cn_flags & SAVESTART) + if (refstart) VREF(dvp); if ((cnp->cn_flags & LOCKLEAF) == 0) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 19e06732a9d0..d689b1a03eb4 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -3638,8 +3638,8 @@ kern_renameat_mac(struct thread *td, int oldfd, const char *old, int newfd, { int error; - NDINIT_ATRIGHTS(fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | - AUDITVNODE1, pathseg, old, oldfd, &cap_renameat_source_rights); + NDINIT_ATRIGHTS(fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVENAME | AUDITVNODE1, + pathseg, old, oldfd, &cap_renameat_source_rights); if ((error = namei(fromnd)) != 0) return (error); error = mac_vnode_check_rename_from(td->td_ucred, fromnd->ni_dvp, @@ -3651,8 +3651,6 @@ kern_renameat_mac(struct thread *td, int oldfd, const char *old, int newfd, NDFREE(fromnd, NDF_ONLY_PNBUF); vrele(fromnd->ni_dvp); vrele(fromnd->ni_vp); - if (fromnd->ni_startdir) - vrele(fromnd->ni_startdir); } return (error); } @@ -3678,7 +3676,7 @@ kern_renameat(struct thread *td, int oldfd, const char *old, int newfd, return (error); } else { #endif - NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | AUDITVNODE1, + NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVENAME | AUDITVNODE1, pathseg, old, oldfd, &cap_renameat_source_rights); if ((error = namei(&fromnd)) != 0) return (error); @@ -3686,7 +3684,7 @@ kern_renameat(struct thread *td, int oldfd, const char *old, int newfd, } #endif fvp = fromnd.ni_vp; - tondflags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | AUDITVNODE2; + tondflags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVENAME | AUDITVNODE2; if (fromnd.ni_vp->v_type == VDIR) tondflags |= WILLBEDIR; NDINIT_ATRIGHTS(&tond, RENAME, tondflags, pathseg, new, newfd, @@ -3714,9 +3712,6 @@ kern_renameat(struct thread *td, int oldfd, const char *old, int newfd, vput(tdvp); vrele(fromnd.ni_dvp); vrele(fvp); - vrele(tond.ni_startdir); - if (fromnd.ni_startdir != NULL) - vrele(fromnd.ni_startdir); error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH); if (error != 0) return (error); @@ -3776,11 +3771,8 @@ kern_renameat(struct thread *td, int oldfd, const char *old, int newfd, vrele(fromnd.ni_dvp); vrele(fvp); } - vrele(tond.ni_startdir); vn_finished_write(mp); out1: - if (fromnd.ni_startdir) - vrele(fromnd.ni_startdir); if (error == ERESTART) return (0); if (error == ERELOOKUP) diff --git a/sys/sys/namei.h b/sys/sys/namei.h index 965a2b757f49..0482d1146093 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -276,6 +276,23 @@ do { \ (ndp)->ni_vp_seqc = SEQC_MOD; \ } while (0) +#ifdef INVARIANTS +#define NDPOISON_SUCCESS(ndp) \ +do { \ + struct nameidata *_ndp = (ndp); \ + if ((_ndp->ni_cnd.cn_flags & SAVESTART) == 0) \ + _ndp->ni_startdir = BADVP; \ +} while (0) +#define NDPOISON_ERROR(ndp) \ +do { \ + struct nameidata *_ndp = (ndp); \ + _ndp->ni_startdir = BADVP; \ +} while (0) +#else +#define NDPOISON_SUCCESS(ndp) do { } while (0) +#define NDPOISON_ERROR(ndp) do { } while (0) +#endif + #define NDF_NO_DVP_RELE 0x00000001 #define NDF_NO_DVP_UNLOCK 0x00000002 #define NDF_NO_DVP_PUT 0x00000003 @@ -307,7 +324,7 @@ void NDVALIDATE(struct nameidata *); int namei(struct nameidata *ndp); int lookup(struct nameidata *ndp); int relookup(struct vnode *dvp, struct vnode **vpp, - struct componentname *cnp); + struct componentname *cnp, bool refstart); #endif /* diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 6e8373379587..311ac7f33e01 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -448,6 +448,7 @@ extern int vttoif_tab[]; #endif /* DIAGNOSTIC */ #define NULLVP ((struct vnode *)NULL) +#define BADVP ((struct vnode *)0xdeadbeef) /* FIXME: pick a better value */ /* * Global vnode data. diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index f32953f19a23..c076e7538adc 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1477,8 +1477,6 @@ ufs_rename(ap) } if (error) goto unlockout; - if ((tcnp->cn_flags & SAVESTART) == 0) - panic("ufs_rename: lost to startdir"); } if (fip->i_effnlink == 0 || fdp->i_effnlink == 0 || tdp->i_effnlink == 0)