diff options
-rw-r--r-- | sys/coda/coda_vnops.c | 10 | ||||
-rw-r--r-- | sys/fs/coda/coda_vnops.c | 10 | ||||
-rw-r--r-- | sys/fs/unionfs/union_vnops.c | 7 | ||||
-rw-r--r-- | sys/gnu/ext2fs/ext2_vnops.c | 3 | ||||
-rw-r--r-- | sys/gnu/fs/ext2fs/ext2_vnops.c | 3 | ||||
-rw-r--r-- | sys/kern/vfs_extattr.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 2 | ||||
-rw-r--r-- | sys/kern/vnode_if.src | 6 | ||||
-rw-r--r-- | sys/miscfs/devfs/devfs_vnops.c | 8 | ||||
-rw-r--r-- | sys/miscfs/union/union_vnops.c | 7 | ||||
-rw-r--r-- | sys/nfs/nfs_serv.c | 21 | ||||
-rw-r--r-- | sys/nfs/nfs_vnops.c | 4 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 4 | ||||
-rw-r--r-- | sys/nfsserver/nfs_serv.c | 21 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 3 |
15 files changed, 42 insertions, 69 deletions
diff --git a/sys/coda/coda_vnops.c b/sys/coda/coda_vnops.c index 6614b4b..5f86c09 100644 --- a/sys/coda/coda_vnops.c +++ b/sys/coda/coda_vnops.c @@ -1578,6 +1578,7 @@ coda_symlink(v) 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 @@ coda_symlink(v) 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 @@ coda_symlink(v) /* 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)); ) diff --git a/sys/fs/coda/coda_vnops.c b/sys/fs/coda/coda_vnops.c index 6614b4b..5f86c09 100644 --- a/sys/fs/coda/coda_vnops.c +++ b/sys/fs/coda/coda_vnops.c @@ -1578,6 +1578,7 @@ coda_symlink(v) 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 @@ coda_symlink(v) 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 @@ coda_symlink(v) /* 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)); ) diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c index a7af32b..7f9d8ee 100644 --- a/sys/fs/unionfs/union_vnops.c +++ b/sys/fs/unionfs/union_vnops.c @@ -1622,11 +1622,8 @@ union_symlink(ap) 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); diff --git a/sys/gnu/ext2fs/ext2_vnops.c b/sys/gnu/ext2fs/ext2_vnops.c index ee64c44..c1fcc83 100644 --- a/sys/gnu/ext2fs/ext2_vnops.c +++ b/sys/gnu/ext2fs/ext2_vnops.c @@ -1063,7 +1063,8 @@ ext2_symlink(ap) 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); } diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c index ee64c44..c1fcc83 100644 --- a/sys/gnu/fs/ext2fs/ext2_vnops.c +++ b/sys/gnu/fs/ext2fs/ext2_vnops.c @@ -1063,7 +1063,8 @@ ext2_symlink(ap) 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); } diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 2f4aa01..19c9d90 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -1303,6 +1303,8 @@ symlink(p, uap) 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"); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 2f4aa01..19c9d90 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1303,6 +1303,8 @@ symlink(p, uap) 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"); diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index e2cd43e..2b16704 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -304,13 +304,9 @@ vop_rmdir { #% 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; diff --git a/sys/miscfs/devfs/devfs_vnops.c b/sys/miscfs/devfs/devfs_vnops.c index 96252d4..d64ce80 100644 --- a/sys/miscfs/devfs/devfs_vnops.c +++ b/sys/miscfs/devfs/devfs_vnops.c @@ -1069,7 +1069,6 @@ devfs_symlink(struct vop_symlink_args *ap) char *a_target; } */ { - struct vnode *vp; int error; dn_p dnp; union typeinfo by; @@ -1084,12 +1083,11 @@ DBPRINT(("symlink\n")); 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; } diff --git a/sys/miscfs/union/union_vnops.c b/sys/miscfs/union/union_vnops.c index a7af32b..7f9d8ee 100644 --- a/sys/miscfs/union/union_vnops.c +++ b/sys/miscfs/union/union_vnops.c @@ -1622,11 +1622,8 @@ union_symlink(ap) 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); diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c index 681c3a6..122e7f3 100644 --- a/sys/nfs/nfs_serv.c +++ b/sys/nfs/nfs_serv.c @@ -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 @@ nfsrv_create(nfsd, slp, procp, mrq) 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 @@ nfsrv_mknod(nfsd, slp, procp, mrq) 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 @@ nfsrv_symlink(nfsd, slp, procp, mrq) /* * 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. */ diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index 816273e..b8fbc8b 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -1818,8 +1818,10 @@ nfs_symlink(ap) 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; diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 816273e..b8fbc8b 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -1818,8 +1818,10 @@ nfs_symlink(ap) 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; diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c index 681c3a6..122e7f3 100644 --- a/sys/nfsserver/nfs_serv.c +++ b/sys/nfsserver/nfs_serv.c @@ -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 @@ nfsrv_create(nfsd, slp, procp, mrq) 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 @@ nfsrv_mknod(nfsd, slp, procp, mrq) 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 @@ nfsrv_symlink(nfsd, slp, procp, mrq) /* * 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. */ diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 6e394c1..437b4f5 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1587,7 +1587,8 @@ ufs_symlink(ap) 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); } |