Index: coda/coda_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/coda/coda_vnops.c,v retrieving revision 1.19 diff -u -r1.19 coda_vnops.c --- coda_vnops.c 1999/08/28 00:40:58 1.19 +++ coda_vnops.c 1999/11/13 17:00:13 @@ -1578,6 +1578,7 @@ char *path = ap->a_target; struct ucred *cred = cnp->cn_cred; struct proc *p = cnp->cn_proc; + struct vnode **vpp = ap->a_vpp; /* locals */ int error; /* @@ -1590,7 +1591,6 @@ int len = cnp->cn_namelen; int plen = strlen(path); - /* XXX What about the vpp argument? Do we need it? */ /* * Here's the strategy for the moment: perform the symlink, then * do a lookup to grab the resulting vnode. I know this requires @@ -1625,12 +1625,8 @@ /* Invalidate the parent's attr cache, the modification time has changed */ tdcp->c_flags &= ~C_VATTR; - /* - * Free the name buffer - */ - if ((cnp->cn_flags & SAVESTART) == 0) { - zfree(namei_zone, cnp->cn_pnbuf); - } + if (error == 0) + error = VOP_LOOKUP(tdvp, vpp, cnp); exit: CODADEBUG(CODA_SYMLINK, myprintf(("in symlink result %d\n",error)); ) Index: gnu/ext2fs/ext2_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/gnu/ext2fs/ext2_vnops.c,v retrieving revision 1.48 diff -u -r1.48 ext2_vnops.c --- ext2_vnops.c 1999/11/12 03:34:23 1.48 +++ ext2_vnops.c 1999/11/13 15:11:06 @@ -1063,7 +1063,8 @@ error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0, UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, (int *)0, (struct proc *)0); - vput(vp); + if (error) + vput(vp); return (error); } Index: kern/vfs_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.141 diff -u -r1.141 vfs_syscalls.c --- vfs_syscalls.c 1999/11/12 03:34:24 1.141 +++ vfs_syscalls.c 1999/11/13 15:11:17 @@ -1305,6 +1305,8 @@ vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask; VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path); + if (error == 0) + vput(nd.ni_vp); vput(nd.ni_dvp); ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); Index: kern/vnode_if.src =================================================================== RCS file: /home/ncvs/src/sys/kern/vnode_if.src,v retrieving revision 1.24 diff -u -r1.24 vnode_if.src --- vnode_if.src 1999/11/12 03:34:25 1.24 +++ vnode_if.src 1999/11/13 16:40:17 @@ -304,13 +304,9 @@ #% symlink dvp L L L #% symlink vpp - U - # -# XXX - note that the return vnode has already been VRELE'ed -# by the filesystem layer. To use it you must use vget, -# possibly with a further namei. -# vop_symlink { IN struct vnode *dvp; - OUT WILLRELE struct vnode **vpp; + OUT struct vnode **vpp; IN struct componentname *cnp; IN struct vattr *vap; IN char *target; Index: miscfs/devfs/devfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/devfs/devfs_vnops.c,v retrieving revision 1.83 diff -u -r1.83 devfs_vnops.c --- devfs_vnops.c 1999/11/07 12:01:31 1.83 +++ devfs_vnops.c 1999/11/13 15:11:19 @@ -1069,7 +1069,6 @@ char *a_target; } */ { - struct vnode *vp; int error; dn_p dnp; union typeinfo by; @@ -1084,12 +1083,11 @@ by.Slnk.namelen = strlen(ap->a_target); dev_add_entry(ap->a_cnp->cn_nameptr, dnp, DEV_SLNK, &by, NULL, NULL, &nm_p); - if((error = devfs_dntovn(nm_p->dnp, &vp)) != 0) { + if((error = devfs_dntovn(nm_p->dnp, ap->a_vpp)) != 0) { return (error); } - VOP_SETATTR(vp, ap->a_vap, ap->a_cnp->cn_cred, ap->a_cnp->cn_proc); - *ap->a_vpp = NULL; - vput(vp); + VOP_SETATTR(*ap->a_vpp, ap->a_vap, ap->a_cnp->cn_cred, + ap->a_cnp->cn_proc); return 0; } Index: miscfs/union/union_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/union/union_vnops.c,v retrieving revision 1.67 diff -u -r1.67 union_vnops.c --- union_vnops.c 1999/11/12 03:34:25 1.67 +++ union_vnops.c 1999/11/13 15:11:20 @@ -1622,11 +1622,8 @@ int error = EROFS; if ((dvp = union_lock_upper(dun, p)) != NULLVP) { - struct vnode *vp; - - error = VOP_SYMLINK(dvp, &vp, cnp, ap->a_vap, ap->a_target); - /* vp is garbage whether an error occurs or not */ - *ap->a_vpp = NULLVP; + error = VOP_SYMLINK(dvp, ap->a_vpp, cnp, ap->a_vap, + ap->a_target); union_unlock_upper(dvp, p); } return (error); Index: nfs/nfs_serv.c =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfs_serv.c,v retrieving revision 1.87 diff -u -r1.87 nfs_serv.c --- nfs_serv.c 1999/11/12 03:34:26 1.87 +++ nfs_serv.c 1999/11/13 16:31:41 @@ -68,13 +68,10 @@ * error occurs. If no error occurs, the VOP_*() routines only free * the path component if SAVESTART is NOT set. * - * VOP_SYMLINK, lookup(), and namei() + * lookup() and namei() * may return garbage in various structural fields/return elements * if an error is returned, and may garbage up nd.ni_dvp even if no * error is returned and you did not request LOCKPARENT or WANTPARENT. - * VOP_SYMLINK return garbage in its return vnode (i.e. not - * something we need to release) even if no error occurs. Our cleanup - * code is sensitive to garbage, so we have to carefully clear it out. * * We use the ni_cnd.cn_flags 'HASBUF' flag to track whether the name * buffer has been freed or not. This is unique to nfs_serv.c for @@ -1699,10 +1696,6 @@ nd.ni_cnd.cn_flags &= ~HASBUF; goto nfsmreply0; } - - /* - * release vp we do not use - */ vput(nd.ni_vp); nd.ni_vp = NULL; @@ -1912,10 +1905,6 @@ nd.ni_cnd.cn_flags &= ~HASBUF; goto out; } - - /* - * release vp we do not use - */ vput(nd.ni_vp); nd.ni_vp = NULL; @@ -2559,14 +2548,16 @@ /* * issue symlink op. SAVESTART is set so the underlying path component - * is only freed by the VOP if an error occurs. VOP_SYMLINK does not - * return a referenced ni_vp, but it may fill the pointer with garbage. + * is only freed by the VOP if an error occurs. */ nqsrv_getl(nd.ni_dvp, ND_WRITE); error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap, pathcp); - nd.ni_vp = NULL; if (error) nd.ni_cnd.cn_flags &= ~HASBUF; + else { + vput(nd.ni_vp); + nd.ni_vp = NULL; + } /* * releases directory prior to potential lookup op. */ Index: nfs/nfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.143 diff -u -r1.143 nfs_vnops.c --- nfs_vnops.c 1999/10/25 19:22:33 1.143 +++ nfs_vnops.c 1999/11/13 16:33:52 @@ -1818,8 +1818,10 @@ nfsm_wcc_data(dvp, wccflag); } nfsm_reqdone; - if (newvp) + if (newvp && error) vput(newvp); + else + *ap->a_vpp = newvp; VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) VTONFS(dvp)->n_attrstamp = 0; Index: ufs/ufs/ufs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.126 diff -u -r1.126 ufs_vnops.c --- ufs_vnops.c 1999/11/12 03:34:28 1.126 +++ ufs_vnops.c 1999/11/13 15:11:44 @@ -1587,7 +1587,8 @@ error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0, UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, (int *)0, (struct proc *)0); - vput(vp); + if (error) + vput(vp); return (error); }