Remove WILLRELE from VOP_SYMLINK
Note: Previous commit to these files (except coda_vnops and devfs_vnops) that claimed to remove WILLRELE from VOP_RENAME actually removed it from VOP_MKNOD.
This commit is contained in:
parent
3973dacdb3
commit
dd8c04f4c7
@ -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)); )
|
||||
|
@ -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)); )
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user