diff options
author | rees <rees@FreeBSD.org> | 2005-11-21 18:39:18 +0000 |
---|---|---|
committer | rees <rees@FreeBSD.org> | 2005-11-21 18:39:18 +0000 |
commit | 1a3808ebdf7e81e64227c3d14cc6846d975b0876 (patch) | |
tree | 5c032de9be9e65d3669a39a23ed056009adf00ff /sys | |
parent | f43bb7546346a694311becf1114bb2d99cb3739e (diff) | |
download | FreeBSD-src-1a3808ebdf7e81e64227c3d14cc6846d975b0876.zip FreeBSD-src-1a3808ebdf7e81e64227c3d14cc6846d975b0876.tar.gz |
fix a problem with XID re-use when a server returns NFSERR_JUKEBOX.
Submitted by: cel@citi.umich.edu
Fixed by: rick@snowhite.cis.uoguelph.ca
Approved by: alfred
MFC after: 3 weeks
Diffstat (limited to 'sys')
-rw-r--r-- | sys/nfsclient/nfs_socket.c | 11 | ||||
-rw-r--r-- | sys/nfsclient/nfs_subs.c | 7 | ||||
-rw-r--r-- | sys/nfsclient/nfsm_subs.h | 2 |
3 files changed, 13 insertions, 7 deletions
diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index 9e7a386..511e229 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -77,6 +77,8 @@ __FBSDID("$FreeBSD$"); #define TRUE 1 #define FALSE 0 +extern u_int32_t nfs_xid; + /* * Estimate rto for an nfs rpc sent via. an unreliable datagram. * Use the mean and mean deviation of rtt for the appropriate type of rpc @@ -924,7 +926,7 @@ nfs_request(struct vnode *vp, struct mbuf *mrest, int procnum, int s, error = 0, mrest_len, auth_len, auth_type; int trylater_delay = NQ_TRYLATERDEL, trylater_cnt = 0; struct timeval now; - u_int32_t xid; + u_int32_t *xidp; /* Reject requests while attempting a forced unmount. */ if (vp->v_mount->mnt_kern_flag & MNTK_UNMOUNTF) { @@ -956,7 +958,7 @@ nfs_request(struct vnode *vp, struct mbuf *mrest, int procnum, nmp->nm_numgrps : (cred->cr_ngroups - 1)) << 2) + 5 * NFSX_UNSIGNED; m = nfsm_rpchead(cred, nmp->nm_flag, procnum, auth_type, auth_len, - mrest, mrest_len, &mheadend, &xid); + mrest, mrest_len, &mheadend, &xidp); /* * For stream protocols, insert a Sun RPC Record Mark. @@ -967,7 +969,7 @@ nfs_request(struct vnode *vp, struct mbuf *mrest, int procnum, (m->m_pkthdr.len - NFSX_UNSIGNED)); } rep->r_mreq = m; - rep->r_xid = xid; + rep->r_xid = *xidp; tryagain: if (nmp->nm_flag & NFSMNT_SOFT) rep->r_retry = nmp->nm_retry; @@ -1128,6 +1130,9 @@ tryagain: trylater_delay *= nfs_backoff[trylater_cnt]; if (trylater_cnt < NFS_NBACKOFF - 1) trylater_cnt++; + if (++nfs_xid == 0) + nfs_xid++; + rep->r_xid = *xidp = txdr_unsigned(nfs_xid); goto tryagain; } diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index 444c47b..fb67091 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -85,7 +85,7 @@ u_int32_t rpc_call, rpc_vers, rpc_reply, rpc_msgdenied, rpc_autherr, u_int32_t nfs_true, nfs_false; /* And other global data */ -static u_int32_t nfs_xid = 0; +u_int32_t nfs_xid = 0; static enum vtype nv2tov_type[8]= { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON, VNON }; @@ -155,7 +155,7 @@ nfsm_reqhead(struct vnode *vp, u_long procid, int hsiz) struct mbuf * nfsm_rpchead(struct ucred *cr, int nmflag, int procid, int auth_type, int auth_len, struct mbuf *mrest, int mrest_len, struct mbuf **mbp, - u_int32_t *xidp) + u_int32_t **xidpp) { struct mbuf *mb; u_int32_t *tl; @@ -191,7 +191,8 @@ nfsm_rpchead(struct ucred *cr, int nmflag, int procid, int auth_type, if (++nfs_xid == 0) nfs_xid++; - *tl++ = *xidp = txdr_unsigned(nfs_xid); + *xidpp = tl; + *tl++ = txdr_unsigned(nfs_xid); *tl++ = rpc_call; *tl++ = rpc_vers; *tl++ = txdr_unsigned(NFS_PROG); diff --git a/sys/nfsclient/nfsm_subs.h b/sys/nfsclient/nfsm_subs.h index 8083a47..62666a5 100644 --- a/sys/nfsclient/nfsm_subs.h +++ b/sys/nfsclient/nfsm_subs.h @@ -56,7 +56,7 @@ struct mbuf *nfsm_reqhead(struct vnode *vp, u_long procid, int hsiz); struct mbuf *nfsm_rpchead(struct ucred *cr, int nmflag, int procid, int auth_type, int auth_len, struct mbuf *mrest, int mrest_len, - struct mbuf **mbp, u_int32_t *xidp); + struct mbuf **mbp, u_int32_t **xidpp); #define M_HASCL(m) ((m)->m_flags & M_EXT) #define NFSMINOFF(m) \ |