Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Apr 2010 22:52:14 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r207170 - in head/sys/fs: nfs nfsclient nfsserver
Message-ID:  <201004242252.o3OMqEd3070173@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sat Apr 24 22:52:14 2010
New Revision: 207170
URL: http://svn.freebsd.org/changeset/base/207170

Log:
  An NFSv4 server will reply NFSERR_GRACE for non-recovery RPCs
  during the grace period after startup. This grace period must
  be at least the lease duration, which is typically 1-2 minutes.
  It seems prudent for the experimental NFS client to wait a few
  seconds before retrying such an RPC, so that the server isn't
  flooded with non-recovery RPCs during recovery. This patch adds
  an argument to nfs_catnap() to implement a 5 second delay
  for this case.
  
  MFC after:	1 week

Modified:
  head/sys/fs/nfs/nfs_commonkrpc.c
  head/sys/fs/nfs/nfs_commonport.c
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfs/nfsport.h
  head/sys/fs/nfsclient/nfs_clrpcops.c
  head/sys/fs/nfsclient/nfs_clstate.c
  head/sys/fs/nfsclient/nfs_clvfsops.c
  head/sys/fs/nfsclient/nfs_clvnops.c
  head/sys/fs/nfsserver/nfs_nfsdstate.c

Modified: head/sys/fs/nfs/nfs_commonkrpc.c
==============================================================================
--- head/sys/fs/nfs/nfs_commonkrpc.c	Sat Apr 24 22:31:51 2010	(r207169)
+++ head/sys/fs/nfs/nfs_commonkrpc.c	Sat Apr 24 22:52:14 2010	(r207170)
@@ -650,7 +650,7 @@ tryagain:
 					trylater_delay = NFS_TRYLATERDEL;
 				waituntil = NFSD_MONOSEC + trylater_delay;
 				while (NFSD_MONOSEC < waituntil)
-					(void) nfs_catnap(PZERO, "nfstry");
+					(void) nfs_catnap(PZERO, 0, "nfstry");
 				trylater_delay *= 2;
 				goto tryagain;
 			}

Modified: head/sys/fs/nfs/nfs_commonport.c
==============================================================================
--- head/sys/fs/nfs/nfs_commonport.c	Sat Apr 24 22:31:51 2010	(r207169)
+++ head/sys/fs/nfs/nfs_commonport.c	Sat Apr 24 22:52:14 2010	(r207170)
@@ -345,17 +345,21 @@ newnfs_timer(void *arg)
 
 
 /*
- * sleep for a short period of time.
+ * Sleep for a short period of time unless errval == NFSERR_GRACE, where
+ * the sleep should be for 5 seconds.
  * Since lbolt doesn't exist in FreeBSD-CURRENT, just use a timeout on
  * an event that never gets a wakeup. Only return EINTR or 0.
  */
 int
-nfs_catnap(int prio, const char *wmesg)
+nfs_catnap(int prio, int errval, const char *wmesg)
 {
 	static int non_event;
 	int ret;
 
-	ret = tsleep(&non_event, prio, wmesg, 1);
+	if (errval == NFSERR_GRACE)
+		ret = tsleep(&non_event, prio, wmesg, 5 * hz);
+	else
+		ret = tsleep(&non_event, prio, wmesg, 1);
 	if (ret != EINTR)
 		ret = 0;
 	return (ret);

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h	Sat Apr 24 22:31:51 2010	(r207169)
+++ head/sys/fs/nfs/nfs_var.h	Sat Apr 24 22:52:14 2010	(r207170)
@@ -322,7 +322,7 @@ int nfsvno_v4rootexport(struct nfsrv_des
 void newnfs_portinit(void);
 struct ucred *newnfs_getcred(void);
 void newnfs_setroot(struct ucred *);
-int nfs_catnap(int, const char *);
+int nfs_catnap(int, int, const char *);
 struct nfsreferral *nfsv4root_getreferral(vnode_t, vnode_t, u_int32_t);
 int nfsrv_atroot(vnode_t, long *);
 void newnfs_timer(void *);

Modified: head/sys/fs/nfs/nfsport.h
==============================================================================
--- head/sys/fs/nfs/nfsport.h	Sat Apr 24 22:31:51 2010	(r207169)
+++ head/sys/fs/nfs/nfsport.h	Sat Apr 24 22:52:14 2010	(r207170)
@@ -143,21 +143,21 @@
 #define	NFSMGET(m)	do { 					\
 		MGET((m), M_TRYWAIT, MT_DATA); 			\
 		while ((m) == NULL ) { 				\
-			(void) nfs_catnap(PZERO, "nfsmget");	\
+			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
 			MGET((m), M_TRYWAIT, MT_DATA); 		\
 		} 						\
 	} while (0)
 #define	NFSMGETHDR(m)	do { 					\
 		MGETHDR((m), M_TRYWAIT, MT_DATA);		\
 		while ((m) == NULL ) { 				\
-			(void) nfs_catnap(PZERO, "nfsmget");	\
+			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
 			MGETHDR((m), M_TRYWAIT, MT_DATA); 	\
 		} 						\
 	} while (0)
 #define	NFSMCLGET(m, w)	do { 					\
 		MGET((m), M_TRYWAIT, MT_DATA); 			\
 		while ((m) == NULL ) { 				\
-			(void) nfs_catnap(PZERO, "nfsmget");	\
+			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
 			MGET((m), M_TRYWAIT, MT_DATA); 		\
 		} 						\
 		MCLGET((m), (w));				\
@@ -165,7 +165,7 @@
 #define	NFSMCLGETHDR(m, w) do { 				\
 		MGETHDR((m), M_TRYWAIT, MT_DATA);		\
 		while ((m) == NULL ) { 				\
-			(void) nfs_catnap(PZERO, "nfsmget");	\
+			(void) nfs_catnap(PZERO, 0, "nfsmget");	\
 			MGETHDR((m), M_TRYWAIT, MT_DATA); 	\
 		} 						\
 	} while (0)

Modified: head/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clrpcops.c	Sat Apr 24 22:31:51 2010	(r207169)
+++ head/sys/fs/nfsclient/nfs_clrpcops.c	Sat Apr 24 22:52:14 2010	(r207170)
@@ -298,7 +298,7 @@ else printf(" fhl=0\n");
 	    nfscl_openrelease(op, error, newone);
 	    if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
 		error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) {
-		(void) nfs_catnap(PZERO, "nfs_open");
+		(void) nfs_catnap(PZERO, error, "nfs_open");
 	    } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID)
 		&& clidrev != 0) {
 		expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
@@ -460,7 +460,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vno
 			ret = nfsrpc_openconfirm(vp, newfhp, newfhlen, op,
 			    cred, p);
 			if (ret == NFSERR_DELAY)
-			    (void) nfs_catnap(PZERO, "nfs_open");
+			    (void) nfs_catnap(PZERO, ret, "nfs_open");
 		    } while (ret == NFSERR_DELAY);
 		    error = ret;
 		}
@@ -484,7 +484,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vno
 			    newfhlen, mode, op, name, namelen, &ndp, 0, 0x0,
 			    cred, p, syscred, 1);
 			if (ret == NFSERR_DELAY)
-			    (void) nfs_catnap(PZERO, "nfs_open2");
+			    (void) nfs_catnap(PZERO, ret, "nfs_open2");
 		    } while (ret == NFSERR_DELAY);
 		    if (ret) {
 			if (ndp != NULL)
@@ -624,6 +624,7 @@ nfsrpc_doclose(struct nfsmount *nmp, str
 					    nd->nd_repstat == NFSERR_DELAY) &&
 					    error == 0)
 						(void) nfs_catnap(PZERO,
+						    (int)nd->nd_repstat,
 						    "nfs_close");
 				} while ((nd->nd_repstat == NFSERR_GRACE ||
 				    nd->nd_repstat == NFSERR_DELAY) &&
@@ -645,7 +646,7 @@ nfsrpc_doclose(struct nfsmount *nmp, str
 	do {
 		error = nfscl_tryclose(op, tcred, nmp, p);
 		if (error == NFSERR_GRACE)
-			(void) nfs_catnap(PZERO, "nfs_close");
+			(void) nfs_catnap(PZERO, error, "nfs_close");
 	} while (error == NFSERR_GRACE);
 	NFSLOCKCLSTATE();
 	nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
@@ -999,7 +1000,7 @@ nfsrpc_setattr(vnode_t vp, struct vattr 
 		if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
 		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
 		    error == NFSERR_OLDSTATEID) {
-			(void) nfs_catnap(PZERO, "nfs_setattr");
+			(void) nfs_catnap(PZERO, error, "nfs_setattr");
 		} else if ((error == NFSERR_EXPIRED ||
 		    error == NFSERR_BADSTATEID) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
@@ -1244,7 +1245,7 @@ nfsrpc_read(vnode_t vp, struct uio *uiop
 		if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
 		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
 		    error == NFSERR_OLDSTATEID) {
-			(void) nfs_catnap(PZERO, "nfs_read");
+			(void) nfs_catnap(PZERO, error, "nfs_read");
 		} else if ((error == NFSERR_EXPIRED ||
 		    error == NFSERR_BADSTATEID) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
@@ -1409,7 +1410,7 @@ nfscl_dumpstate(nmp, 1, 1, 0, 0);
 		if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
 		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
 		    error == NFSERR_OLDSTATEID) {
-			(void) nfs_catnap(PZERO, "nfs_write");
+			(void) nfs_catnap(PZERO, error, "nfs_write");
 		} else if ((error == NFSERR_EXPIRED ||
 		    error == NFSERR_BADSTATEID) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
@@ -1736,7 +1737,7 @@ nfsrpc_create(vnode_t dvp, char *name, i
 		nfscl_ownerrelease(owp, error, newone, unlocked);
 		if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
 		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) {
-			(void) nfs_catnap(PZERO, "nfs_open");
+			(void) nfs_catnap(PZERO, error, "nfs_open");
 		} else if ((error == NFSERR_EXPIRED ||
 		    error == NFSERR_BADSTATEID) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
@@ -1969,7 +1970,7 @@ nfsrpc_createv4(vnode_t dvp, char *name,
 			ret = nfsrpc_openconfirm(dvp, nfhp->nfh_fh,
 			    nfhp->nfh_len, op, cred, p);
 			if (ret == NFSERR_DELAY)
-			    (void) nfs_catnap(PZERO, "nfs_create");
+			    (void) nfs_catnap(PZERO, ret, "nfs_create");
 		    } while (ret == NFSERR_DELAY);
 		    error = ret;
 		}
@@ -1991,7 +1992,7 @@ nfsrpc_createv4(vnode_t dvp, char *name,
 			    (NFSV4OPEN_ACCESSWRITE | NFSV4OPEN_ACCESSREAD), op,
 			    name, namelen, &dp, 0, 0x0, cred, p, 0, 1);
 			if (ret == NFSERR_DELAY)
-			    (void) nfs_catnap(PZERO, "nfs_crt2");
+			    (void) nfs_catnap(PZERO, ret, "nfs_crt2");
 		    } while (ret == NFSERR_DELAY);
 		    if (ret) {
 			if (dp != NULL)
@@ -3533,7 +3534,8 @@ nfsrpc_advlock(vnode_t vp, off_t size, i
 			    if ((nd->nd_repstat == NFSERR_GRACE ||
 				 nd->nd_repstat == NFSERR_DELAY) &&
 				error == 0)
-				(void) nfs_catnap(PZERO, "nfs_advlock");
+				(void) nfs_catnap(PZERO, (int)nd->nd_repstat,
+				    "nfs_advlock");
 			} while ((nd->nd_repstat == NFSERR_GRACE ||
 			    nd->nd_repstat == NFSERR_DELAY) && error == 0);
 		    }
@@ -3570,7 +3572,7 @@ nfsrpc_advlock(vnode_t vp, off_t size, i
 	    if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
 		error == NFSERR_STALEDONTRECOVER ||
 		error == NFSERR_STALECLIENTID || error == NFSERR_DELAY) {
-		(void) nfs_catnap(PZERO, "nfs_advlock");
+		(void) nfs_catnap(PZERO, error, "nfs_advlock");
 	    } else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID)
 		&& clidrev != 0) {
 		expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);

Modified: head/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clstate.c	Sat Apr 24 22:31:51 2010	(r207169)
+++ head/sys/fs/nfsclient/nfs_clstate.c	Sat Apr 24 22:52:14 2010	(r207170)
@@ -784,7 +784,7 @@ nfscl_getcl(vnode_t vp, struct ucred *cr
 			if (error == NFSERR_STALECLIENTID ||
 			    error == NFSERR_STALEDONTRECOVER ||
 			    error == NFSERR_CLIDINUSE) {
-				(void) nfs_catnap(PZERO, "nfs_setcl");
+				(void) nfs_catnap(PZERO, error, "nfs_setcl");
 			}
 		} while (((error == NFSERR_STALECLIENTID ||
 		     error == NFSERR_STALEDONTRECOVER) && --trystalecnt > 0) ||
@@ -2046,7 +2046,7 @@ nfscl_recover(struct nfsclclient *clp, s
 			newnfs_copycred(&op->nfso_cred, tcred);
 			error = nfscl_tryclose(op, tcred, nmp, p);
 			if (error == NFSERR_GRACE)
-				(void) nfs_catnap(PZERO, "nfsexcls");
+				(void) nfs_catnap(PZERO, error, "nfsexcls");
 		} while (error == NFSERR_GRACE);
 		LIST_REMOVE(op, nfso_list);
 		FREE((caddr_t)op, M_NFSCLOPEN);
@@ -2059,7 +2059,7 @@ nfscl_recover(struct nfsclclient *clp, s
 			newnfs_copycred(&dp->nfsdl_cred, tcred);
 			error = nfscl_trydelegreturn(dp, tcred, nmp, p);
 			if (error == NFSERR_GRACE)
-				(void) nfs_catnap(PZERO, "nfsexdlg");
+				(void) nfs_catnap(PZERO, error, "nfsexdlg");
 		} while (error == NFSERR_GRACE);
 		TAILQ_REMOVE(&extra_deleg, dp, nfsdl_list);
 		FREE((caddr_t)dp, M_NFSCLDELEG);
@@ -3619,7 +3619,7 @@ nfscl_tryopen(struct nfsmount *nmp, vnod
 		    mode, op, name, namelen, ndpp, reclaim, delegtype, cred, p,
 		    0, 0);
 		if (error == NFSERR_DELAY)
-			(void) nfs_catnap(PZERO, "nfstryop");
+			(void) nfs_catnap(PZERO, error, "nfstryop");
 	} while (error == NFSERR_DELAY);
 	if (error == EAUTH || error == EACCES) {
 		/* Try again using system credentials */
@@ -3629,7 +3629,7 @@ nfscl_tryopen(struct nfsmount *nmp, vnod
 			newfhlen, mode, op, name, namelen, ndpp, reclaim,
 			delegtype, cred, p, 1, 0);
 		    if (error == NFSERR_DELAY)
-			(void) nfs_catnap(PZERO, "nfstryop");
+			(void) nfs_catnap(PZERO, error, "nfstryop");
 		} while (error == NFSERR_DELAY);
 	}
 	return (error);
@@ -3652,7 +3652,8 @@ nfscl_trylock(struct nfsmount *nmp, vnod
 		error = nfsrpc_lock(nd, nmp, vp, fhp, fhlen, nlp, newone,
 		    reclaim, off, len, type, cred, p, 0);
 		if (!error && nd->nd_repstat == NFSERR_DELAY)
-			(void) nfs_catnap(PZERO, "nfstrylck");
+			(void) nfs_catnap(PZERO, (int)nd->nd_repstat,
+			    "nfstrylck");
 	} while (!error && nd->nd_repstat == NFSERR_DELAY);
 	if (!error)
 		error = nd->nd_repstat;
@@ -3663,7 +3664,8 @@ nfscl_trylock(struct nfsmount *nmp, vnod
 			error = nfsrpc_lock(nd, nmp, vp, fhp, fhlen, nlp,
 			    newone, reclaim, off, len, type, cred, p, 1);
 			if (!error && nd->nd_repstat == NFSERR_DELAY)
-				(void) nfs_catnap(PZERO, "nfstrylck");
+				(void) nfs_catnap(PZERO, (int)nd->nd_repstat,
+				    "nfstrylck");
 		} while (!error && nd->nd_repstat == NFSERR_DELAY);
 		if (!error)
 			error = nd->nd_repstat;
@@ -3685,7 +3687,7 @@ nfscl_trydelegreturn(struct nfscldeleg *
 	do {
 		error = nfsrpc_delegreturn(dp, cred, nmp, p, 0);
 		if (error == NFSERR_DELAY)
-			(void) nfs_catnap(PZERO, "nfstrydp");
+			(void) nfs_catnap(PZERO, error, "nfstrydp");
 	} while (error == NFSERR_DELAY);
 	if (error == EAUTH || error == EACCES) {
 		/* Try again using system credentials */
@@ -3693,7 +3695,7 @@ nfscl_trydelegreturn(struct nfscldeleg *
 		do {
 			error = nfsrpc_delegreturn(dp, cred, nmp, p, 1);
 			if (error == NFSERR_DELAY)
-				(void) nfs_catnap(PZERO, "nfstrydp");
+				(void) nfs_catnap(PZERO, error, "nfstrydp");
 		} while (error == NFSERR_DELAY);
 	}
 	return (error);
@@ -3714,7 +3716,7 @@ nfscl_tryclose(struct nfsclopen *op, str
 	do {
 		error = nfsrpc_closerpc(nd, nmp, op, cred, p, 0);
 		if (error == NFSERR_DELAY)
-			(void) nfs_catnap(PZERO, "nfstrycl");
+			(void) nfs_catnap(PZERO, error, "nfstrycl");
 	} while (error == NFSERR_DELAY);
 	if (error == EAUTH || error == EACCES) {
 		/* Try again using system credentials */
@@ -3722,7 +3724,7 @@ nfscl_tryclose(struct nfsclopen *op, str
 		do {
 			error = nfsrpc_closerpc(nd, nmp, op, cred, p, 1);
 			if (error == NFSERR_DELAY)
-				(void) nfs_catnap(PZERO, "nfstrycl");
+				(void) nfs_catnap(PZERO, error, "nfstrycl");
 		} while (error == NFSERR_DELAY);
 	}
 	return (error);

Modified: head/sys/fs/nfsclient/nfs_clvfsops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvfsops.c	Sat Apr 24 22:31:51 2010	(r207169)
+++ head/sys/fs/nfsclient/nfs_clvfsops.c	Sat Apr 24 22:52:14 2010	(r207170)
@@ -652,7 +652,7 @@ nfs_decode_args(struct mount *mp, struct
 			while (newnfs_connect(nmp, &nmp->nm_sockreq,
 			    cred, td, 0)) {
 				printf("newnfs_args: retrying connect\n");
-				(void) nfs_catnap(PSOCK, "newnfscon");
+				(void) nfs_catnap(PSOCK, 0, "newnfscon");
 			}
 		}
 	} else {
@@ -1188,7 +1188,7 @@ mountnfs(struct nfs_args *argp, struct m
 			error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
 			    cred, td);
 			if (error)
-				(void) nfs_catnap(PZERO, "nfsgetdirp");
+				(void) nfs_catnap(PZERO, error, "nfsgetdirp");
 		} while (error && --trycnt > 0);
 		if (error) {
 			error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
@@ -1284,7 +1284,7 @@ nfs_unmount(struct mount *mp, int mntfla
 	do {
 		error = vflush(mp, 1, flags, td);
 		if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
-			(void) nfs_catnap(PSOCK, "newndm");
+			(void) nfs_catnap(PSOCK, error, "newndm");
 	} while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
 	if (error)
 		goto out;

Modified: head/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvnops.c	Sat Apr 24 22:31:51 2010	(r207169)
+++ head/sys/fs/nfsclient/nfs_clvnops.c	Sat Apr 24 22:52:14 2010	(r207170)
@@ -2871,7 +2871,8 @@ nfs_advlock(struct vop_advlock_args *ap)
 			if (ret == NFSERR_DENIED && (ap->a_flags & F_WAIT) &&
 			    ap->a_op == F_SETLK) {
 				VOP_UNLOCK(vp, 0);
-				error = nfs_catnap(PZERO | PCATCH, "ncladvl");
+				error = nfs_catnap(PZERO | PCATCH, ret,
+				    "ncladvl");
 				if (error)
 					return (EINTR);
 				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);

Modified: head/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdstate.c	Sat Apr 24 22:31:51 2010	(r207169)
+++ head/sys/fs/nfsserver/nfs_nfsdstate.c	Sat Apr 24 22:52:14 2010	(r207170)
@@ -4578,7 +4578,7 @@ nfsd_recalldelegation(vnode_t vp, NFSPRO
 			    100000)
 				return;
 			/* Sleep for a short period of time */
-			(void) nfs_catnap(PZERO, "nfsremove");
+			(void) nfs_catnap(PZERO, 0, "nfsremove");
 		}
 	} while (error == NFSERR_DELAY);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004242252.o3OMqEd3070173>