diff options
| author | Matthew Dillon <dillon@FreeBSD.org> | 1999-11-30 06:56:15 +0000 |
|---|---|---|
| committer | Matthew Dillon <dillon@FreeBSD.org> | 1999-11-30 06:56:15 +0000 |
| commit | 98733bd87142a106601484f88618dc74b1e4c1a8 (patch) | |
| tree | f2cbc518f822a965e8f7637c369d8617b5b3766b /sys | |
| parent | ac83689e019d3f6e2e883cd6411fd45b8973380d (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/nfs/nfs_vnops.c | 36 | ||||
| -rw-r--r-- | sys/nfsclient/nfs_vnops.c | 36 |
2 files changed, 66 insertions, 6 deletions
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index 6c6ae61b9c05..e53b295d8ca5 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -1805,24 +1805,54 @@ nfs_symlink(ap) txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); } + + /* + * Issue the NFS request and get the rpc response. + * + * Only NFSv3 responses returning an error of 0 actually return + * a file handle that can be converted into newvp without having + * to do an extra lookup rpc. + */ nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_proc, cnp->cn_cred); if (v3) { - if (!error) + if (error == 0) nfsm_mtofh(dvp, newvp, v3, gotvp); nfsm_wcc_data(dvp, wccflag); } + + /* + * out code jumps -> here, mrep is also freed. + */ + nfsm_reqdone; + /* - * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. + * If we get an EEXIST error, silently convert it to no-error + * in case of an NFS retry. */ if (error == EEXIST) error = 0; + /* + * If we do not have (or no longer have) an error, and we could + * not extract the newvp from the response due to the request being + * NFSv2 or the error being EEXIST. We have to do a lookup in order + * to obtain a newvp to return. + */ + if (error == 0 && newvp == NULL) { + struct nfsnode *np = NULL; + + error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen, + cnp->cn_cred, cnp->cn_proc, &np); + if (!error) + newvp = NFSTOV(np); + } if (error) { if (newvp) vput(newvp); - } else + } 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 6c6ae61b9c05..e53b295d8ca5 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -1805,24 +1805,54 @@ nfs_symlink(ap) txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); } + + /* + * Issue the NFS request and get the rpc response. + * + * Only NFSv3 responses returning an error of 0 actually return + * a file handle that can be converted into newvp without having + * to do an extra lookup rpc. + */ nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_proc, cnp->cn_cred); if (v3) { - if (!error) + if (error == 0) nfsm_mtofh(dvp, newvp, v3, gotvp); nfsm_wcc_data(dvp, wccflag); } + + /* + * out code jumps -> here, mrep is also freed. + */ + nfsm_reqdone; + /* - * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. + * If we get an EEXIST error, silently convert it to no-error + * in case of an NFS retry. */ if (error == EEXIST) error = 0; + /* + * If we do not have (or no longer have) an error, and we could + * not extract the newvp from the response due to the request being + * NFSv2 or the error being EEXIST. We have to do a lookup in order + * to obtain a newvp to return. + */ + if (error == 0 && newvp == NULL) { + struct nfsnode *np = NULL; + + error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen, + cnp->cn_cred, cnp->cn_proc, &np); + if (!error) + newvp = NFSTOV(np); + } if (error) { if (newvp) vput(newvp); - } else + } else { *ap->a_vpp = newvp; + } VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) VTONFS(dvp)->n_attrstamp = 0; |
