nfs XID doesn't change after NFSERR_JUKEBOX

rick at snowhite.cis.uoguelph.ca rick at snowhite.cis.uoguelph.ca
Fri Nov 4 13:51:38 PST 2005


Here is a patch that I think fixes the problem. It only got a 2 minute
mount test, so someone should test it more thoroughly before committing
it. (I think a similar patch is in NetBSD, but I can't seem to get onto
their site at this time.) It is for FreeBSD5.4, so expect somewhat different
source line #s.

My current client code recreates the RPC header on every retry, but changing
to that requires a lot more coding. (It's necessary for RPCSEC_GSS, since
a seq# in the RPC header has to change each retry and then be re-checksummed.)

Hopefully this is useful for you, rick
--- quick and dirty fix for xid not changing for NFSERR_JUKEBOX ---
*** nfs_socket.c.orig	Fri Nov  4 16:21:15 2005
--- nfs_socket.c	Fri Nov  4 16:29:48 2005
***************
*** 76,81 ****
--- 76,83 ----
  #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
***************
*** 919,925 ****
  	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;
  
  	/* Reject requests while attempting a forced unmount. */
  	if (vp->v_mount->mnt_kern_flag & MNTK_UNMOUNTF) {
--- 921,927 ----
  	int s, error = 0, mrest_len, auth_len, auth_type;
  	int trylater_delay = NQ_TRYLATERDEL, trylater_cnt = 0;
  	struct timeval now;
! 	u_int32_t *xidp;
  
  	/* Reject requests while attempting a forced unmount. */
  	if (vp->v_mount->mnt_kern_flag & MNTK_UNMOUNTF) {
***************
*** 950,956 ****
  		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);
  
  	/*
  	 * For stream protocols, insert a Sun RPC Record Mark.
--- 952,958 ----
  		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, &xidp);
  
  	/*
  	 * For stream protocols, insert a Sun RPC Record Mark.
***************
*** 961,967 ****
  			 (m->m_pkthdr.len - NFSX_UNSIGNED));
  	}
  	rep->r_mreq = m;
! 	rep->r_xid = xid;
  tryagain:
  	if (nmp->nm_flag & NFSMNT_SOFT)
  		rep->r_retry = nmp->nm_retry;
--- 963,969 ----
  			 (m->m_pkthdr.len - NFSX_UNSIGNED));
  	}
  	rep->r_mreq = m;
! 	rep->r_xid = *xidp;
  tryagain:
  	if (nmp->nm_flag & NFSMNT_SOFT)
  		rep->r_retry = nmp->nm_retry;
***************
*** 1088,1093 ****
--- 1090,1098 ----
  				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;
  			}
  
*** nfs_subs.c.orig	Fri Nov  4 16:24:00 2005
--- nfs_subs.c	Fri Nov  4 16:29:04 2005
***************
*** 85,91 ****
  u_int32_t	nfs_true, nfs_false;
  
  /* And other global data */
! static u_int32_t nfs_xid = 0;
  static enum vtype nv2tov_type[8]= {
  	VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON,  VNON
  };
--- 85,91 ----
  u_int32_t	nfs_true, nfs_false;
  
  /* And other global data */
! u_int32_t nfs_xid = 0;
  static enum vtype nv2tov_type[8]= {
  	VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON,  VNON
  };
***************
*** 156,162 ****
  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 *mb;
  	u_int32_t *tl;
--- 156,162 ----
  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 **xidpp)
  {
  	struct mbuf *mb;
  	u_int32_t *tl;
***************
*** 192,198 ****
  	if (++nfs_xid == 0)
  		nfs_xid++;
  
! 	*tl++ = *xidp = txdr_unsigned(nfs_xid);
  	*tl++ = rpc_call;
  	*tl++ = rpc_vers;
  	*tl++ = txdr_unsigned(NFS_PROG);
--- 192,199 ----
  	if (++nfs_xid == 0)
  		nfs_xid++;
  
! 	*xidpp = tl;
! 	*tl++ = txdr_unsigned(nfs_xid);
  	*tl++ = rpc_call;
  	*tl++ = rpc_vers;
  	*tl++ = txdr_unsigned(NFS_PROG);
*** nfsm_subs.h.orig	Fri Nov  4 16:27:54 2005
--- nfsm_subs.h	Fri Nov  4 16:28:11 2005
***************
*** 56,62 ****
  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);
  
  #define	M_HASCL(m)	((m)->m_flags & M_EXT)
  #define	NFSMINOFF(m) \
--- 56,62 ----
  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 **xidpp);
  
  #define	M_HASCL(m)	((m)->m_flags & M_EXT)
  #define	NFSMINOFF(m) \


More information about the freebsd-fs mailing list