diff --git a/sys/nfs/nfs.h b/sys/nfs/nfs.h index b2a72334a43d..a52140e16a86 100644 --- a/sys/nfs/nfs.h +++ b/sys/nfs/nfs.h @@ -1,4 +1,4 @@ -/* $NetBSD: nfs.h,v 1.44 2003/12/06 02:48:35 jonathan Exp $ */ +/* $NetBSD: nfs.h,v 1.45 2004/05/10 10:40:42 yamt Exp $ */ /* * Copyright (c) 1989, 1993, 1995 * The Regents of the University of California. All rights reserved. @@ -340,6 +340,7 @@ extern TAILQ_HEAD(nfsreqhead, nfsreq) nfs_reqq; #define R_TPRINTFMSG 0x20 /* Did a tprintf msg. */ #define R_MUSTRESEND 0x40 /* Must resend request */ #define R_GETONEREP 0x80 /* Probe for one reply only */ +#define R_REXMITTED 0x100 /* retransmitted after reconnect */ /* * A list of nfssvc_sock structures is maintained with all the sockets diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index 8c92af3b875e..1bdfc5adba4c 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_socket.c,v 1.103 2004/04/21 01:05:42 christos Exp $ */ +/* $NetBSD: nfs_socket.c,v 1.104 2004/05/10 10:40:42 yamt Exp $ */ /* * Copyright (c) 1989, 1991, 1993, 1995 @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.103 2004/04/21 01:05:42 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.104 2004/05/10 10:40:42 yamt Exp $"); #include "fs_nfs.h" #include "opt_nfs.h" @@ -351,8 +351,8 @@ nfs_reconnect(rep) * on old socket. */ TAILQ_FOREACH(rp, &nfs_reqq, r_chain) { - if (rp->r_nmp == nmp) - rp->r_flags |= R_MUSTRESEND; + if (rp->r_nmp == nmp && (rp->r_flags & R_MUSTRESEND) == 0) + rp->r_flags |= R_MUSTRESEND | R_REXMITTED; } return (0); } @@ -910,7 +910,7 @@ nfsmout: * nb: always frees up mreq mbuf list */ int -nfs_request(np, mrest, procnum, procp, cred, mrp, mdp, dposp) +nfs_request(np, mrest, procnum, procp, cred, mrp, mdp, dposp, rexmitp) struct nfsnode *np; struct mbuf *mrest; int procnum; @@ -919,6 +919,7 @@ nfs_request(np, mrest, procnum, procp, cred, mrp, mdp, dposp) struct mbuf **mrp; struct mbuf **mdp; caddr_t *dposp; + int *rexmitp; { struct mbuf *m, *mrep; struct nfsreq *rep; @@ -941,6 +942,9 @@ nfs_request(np, mrest, procnum, procp, cred, mrp, mdp, dposp) u_quad_t frev; #endif + if (rexmitp != NULL) + *rexmitp = 0; + KASSERT(cred != NULL); nmp = VFSTONFS(np->n_vnode->v_mount); MALLOC(rep, struct nfsreq *, sizeof(struct nfsreq), M_NFSREQ, M_WAITOK); @@ -1080,6 +1084,16 @@ tryagain: nmp->nm_sent -= NFS_CWNDSCALE; } + if (rexmitp != NULL) { + int rexmit; + + if (nmp->nm_sotype != SOCK_DGRAM) + rexmit = (rep->r_flags & R_REXMITTED) != 0; + else + rexmit = rep->r_rexmit; + *rexmitp = rexmit; + } + /* * If there was a successful reply and a tprintf msg. * tprintf a response. diff --git a/sys/nfs/nfs_var.h b/sys/nfs/nfs_var.h index bbfb3c08262f..d82fd1f3fec7 100644 --- a/sys/nfs/nfs_var.h +++ b/sys/nfs/nfs_var.h @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_var.h,v 1.43 2004/04/05 10:44:09 yamt Exp $ */ +/* $NetBSD: nfs_var.h,v 1.44 2004/05/10 10:40:42 yamt Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -220,7 +220,7 @@ int nfs_receive __P((struct nfsreq *, struct mbuf **, struct mbuf **)); int nfs_reply __P((struct nfsreq *)); int nfs_request __P((struct nfsnode *, struct mbuf *, int, struct proc *, struct ucred *, struct mbuf **, struct mbuf **, - caddr_t *)); + caddr_t *, int *)); int nfs_rephead __P((int, struct nfsrv_descript *, struct nfssvc_sock *, int, int, u_quad_t *, struct mbuf **, struct mbuf **, caddr_t *)); void nfs_timer __P((void *)); diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index 9e7d2b69f667..47d7d7bc6b3b 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_vnops.c,v 1.196 2004/05/08 21:35:13 yamt Exp $ */ +/* $NetBSD: nfs_vnops.c,v 1.197 2004/05/10 10:40:42 yamt Exp $ */ /* * Copyright (c) 1989, 1993 @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.196 2004/05/08 21:35:13 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.197 2004/05/10 10:40:42 yamt Exp $"); #include "opt_nfs.h" #include "opt_uvmhist.h" @@ -1779,14 +1779,6 @@ nfs_remove(v) if (error != EINTR) error = nfs_removerpc(dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc); - /* - * Kludge City: If the first reply to the remove rpc is lost.. - * the reply to the retransmitted request will be ENOENT - * since the file was in fact removed - * Therefore, we cheat and return success. - */ - if (error == ENOENT) - error = 0; } else if (!np->n_sillyrename) error = nfs_sillyrename(dvp, vp, cnp); PNBUF_PUT(cnp->cn_pnbuf); @@ -1835,6 +1827,7 @@ nfs_removerpc(dvp, name, namelen, cred, proc) int error = 0, wccflag = NFSV3_WCCRATTR; struct mbuf *mreq, *mrep, *md, *mb; const int v3 = NFS_ISV3(dvp); + int rexmit; struct nfsnode *dnp = VTONFS(dvp); nfsstats.rpccnt[NFSPROC_REMOVE]++; @@ -1842,13 +1835,21 @@ nfs_removerpc(dvp, name, namelen, cred, proc) NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen)); nfsm_fhtom(dnp, v3); nfsm_strtom(name, namelen, NFS_MAXNAMLEN); - nfsm_request(dnp, NFSPROC_REMOVE, proc, cred); + nfsm_request1(dnp, NFSPROC_REMOVE, proc, cred, &rexmit); if (v3) nfsm_wcc_data(dvp, wccflag, 0); nfsm_reqdone; VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp)); + /* + * Kludge City: If the first reply to the remove rpc is lost.. + * the reply to the retransmitted request will be ENOENT + * since the file was in fact removed + * Therefore, we cheat and return success. + */ + if (rexmit && error == ENOENT) + error = 0; return (error); } @@ -1918,11 +1919,6 @@ out: vput(tvp); vrele(fdvp); vrele(fvp); - /* - * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. - */ - if (error == ENOENT) - error = 0; return (error); } @@ -1960,6 +1956,7 @@ nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, proc) int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR; struct mbuf *mreq, *mrep, *md, *mb; const int v3 = NFS_ISV3(fdvp); + int rexmit; struct nfsnode *fdnp = VTONFS(fdvp); nfsstats.rpccnt[NFSPROC_RENAME]++; @@ -1970,7 +1967,7 @@ nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, proc) nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN); nfsm_fhtom(VTONFS(tdvp), v3); nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN); - nfsm_request(fdnp, NFSPROC_RENAME, proc, cred); + nfsm_request1(fdnp, NFSPROC_RENAME, proc, cred, &rexmit); if (v3) { nfsm_wcc_data(fdvp, fwccflag, 0); nfsm_wcc_data(tdvp, twccflag, 0); @@ -1982,6 +1979,11 @@ nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, proc) NFS_INVALIDATE_ATTRCACHE(VTONFS(fdvp)); if (!twccflag) NFS_INVALIDATE_ATTRCACHE(VTONFS(tdvp)); + /* + * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. + */ + if (rexmit && error == ENOENT) + error = 0; return (error); } @@ -2008,6 +2010,7 @@ nfs_link(v) struct mbuf *mreq, *mrep, *md, *mb; /* XXX Should be const and initialised? */ int v3; + int rexmit; struct nfsnode *np; if (dvp->v_mount != vp->v_mount) { @@ -2039,7 +2042,7 @@ nfs_link(v) nfsm_fhtom(np, v3); nfsm_fhtom(VTONFS(dvp), v3); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - nfsm_request(np, NFSPROC_LINK, cnp->cn_proc, cnp->cn_cred); + nfsm_request1(np, NFSPROC_LINK, cnp->cn_proc, cnp->cn_cred, &rexmit); if (v3) { nfsm_postop_attr(vp, attrflag, 0); nfsm_wcc_data(dvp, wccflag, 0); @@ -2059,7 +2062,7 @@ nfs_link(v) /* * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. */ - if (error == EEXIST) + if (rexmit && error == EEXIST) error = 0; return (error); } @@ -2090,6 +2093,7 @@ nfs_symlink(v) struct mbuf *mreq, *mrep, *md, *mb; struct vnode *newvp = (struct vnode *)0; const int v3 = NFS_ISV3(dvp); + int rexmit; struct nfsnode *dnp = VTONFS(dvp); *ap->a_vpp = NULL; @@ -2111,7 +2115,8 @@ nfs_symlink(v) txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); } - nfsm_request(dnp, NFSPROC_SYMLINK, cnp->cn_proc, cnp->cn_cred); + nfsm_request1(dnp, NFSPROC_SYMLINK, cnp->cn_proc, cnp->cn_cred, + &rexmit); if (v3) { if (!error) nfsm_mtofh(dvp, newvp, v3, gotvp); @@ -2121,7 +2126,7 @@ nfs_symlink(v) /* * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. */ - if (error == EEXIST) + if (rexmit && error == EEXIST) error = 0; if (error == 0 && newvp == NULL) { struct nfsnode *np = NULL; @@ -2172,6 +2177,7 @@ nfs_mkdir(v) caddr_t bpos, dpos, cp2; int error = 0, wccflag = NFSV3_WCCRATTR; int gotvp = 0; + int rexmit; struct mbuf *mreq, *mrep, *md, *mb; const int v3 = NFS_ISV3(dvp); @@ -2192,7 +2198,7 @@ nfs_mkdir(v) txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); } - nfsm_request(dnp, NFSPROC_MKDIR, cnp->cn_proc, cnp->cn_cred); + nfsm_request1(dnp, NFSPROC_MKDIR, cnp->cn_proc, cnp->cn_cred, &rexmit); if (!error) nfsm_mtofh(dvp, newvp, v3, gotvp); if (v3) @@ -2205,7 +2211,7 @@ nfs_mkdir(v) * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry * if we can succeed in looking up the directory. */ - if (error == EEXIST || (!error && !gotvp)) { + if ((rexmit && error == EEXIST) || (!error && !gotvp)) { if (newvp) { vput(newvp); newvp = (struct vnode *)0; @@ -2256,6 +2262,7 @@ nfs_rmdir(v) int32_t t1, t2; caddr_t bpos, dpos, cp2; int error = 0, wccflag = NFSV3_WCCRATTR; + int rexmit; struct mbuf *mreq, *mrep, *md, *mb; const int v3 = NFS_ISV3(dvp); struct nfsnode *dnp; @@ -2272,7 +2279,7 @@ nfs_rmdir(v) NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); nfsm_fhtom(dnp, v3); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - nfsm_request(dnp, NFSPROC_RMDIR, cnp->cn_proc, cnp->cn_cred); + nfsm_request1(dnp, NFSPROC_RMDIR, cnp->cn_proc, cnp->cn_cred, &rexmit); if (v3) nfsm_wcc_data(dvp, wccflag, 0); nfsm_reqdone; @@ -2288,7 +2295,7 @@ nfs_rmdir(v) /* * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. */ - if (error == ENOENT) + if (rexmit && error == ENOENT) error = 0; return (error); } diff --git a/sys/nfs/nfsm_subs.h b/sys/nfs/nfsm_subs.h index 69336a159b7b..bdd0cfdf1780 100644 --- a/sys/nfs/nfsm_subs.h +++ b/sys/nfs/nfsm_subs.h @@ -1,4 +1,4 @@ -/* $NetBSD: nfsm_subs.h,v 1.36 2004/04/05 10:41:45 yamt Exp $ */ +/* $NetBSD: nfsm_subs.h,v 1.37 2004/05/10 10:40:43 yamt Exp $ */ /* * Copyright (c) 1989, 1993 @@ -395,15 +395,17 @@ #define nfsm_rndup(a) (((a)+3)&(~0x3)) #define nfsm_padlen(a) (nfsm_rndup(a) - (a)) -#define nfsm_request(v, t, p, c) \ +#define nfsm_request1(v, t, p, c, rexmitp) \ if ((error = nfs_request((v), mreq, (t), (p), \ - (c), &mrep, &md, &dpos)) != 0) { \ + (c), &mrep, &md, &dpos, (rexmitp))) != 0) { \ if (error & NFSERR_RETERR) \ error &= ~NFSERR_RETERR; \ else \ goto nfsmout; \ } +#define nfsm_request(v, t, p, c) nfsm_request1((v), (t), (p), (c), NULL) + #define nfsm_strtom(a,s,m) \ if ((s) > (m)) { \ m_freem(mreq); \