svn commit: r334248 - in projects/pnfs-planb-server/sys/fs: nfs nfsserver

Rick Macklem rmacklem at FreeBSD.org
Sat May 26 21:31:03 UTC 2018


Author: rmacklem
Date: Sat May 26 21:31:01 2018
New Revision: 334248
URL: https://svnweb.freebsd.org/changeset/base/334248

Log:
  Add handling of errors other than NFSERR_NOMATCHLAYOUT returned by a
  CBLAYOUTRECALL callback. For these other errors, do retries for a while.

Modified:
  projects/pnfs-planb-server/sys/fs/nfs/nfsrvstate.h
  projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c

Modified: projects/pnfs-planb-server/sys/fs/nfs/nfsrvstate.h
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfs/nfsrvstate.h	Sat May 26 21:14:49 2018	(r334247)
+++ projects/pnfs-planb-server/sys/fs/nfs/nfsrvstate.h	Sat May 26 21:31:01 2018	(r334248)
@@ -134,7 +134,8 @@ struct nfslayout {
 	fhandle_t		lay_fh;
 	fsid_t			lay_fsid;
 	uint32_t		lay_layoutlen;
-	uint32_t		lay_mirrorcnt;
+	uint16_t		lay_mirrorcnt;
+	uint16_t		lay_trycnt;
 	uint16_t		lay_type;
 	uint16_t		lay_flags;
 	uint32_t		lay_xdr[0];

Modified: projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c	Sat May 26 21:14:49 2018	(r334247)
+++ projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c	Sat May 26 21:31:01 2018	(r334248)
@@ -217,7 +217,8 @@ static void nfsrv_freealldevids(void);
 static void nfsrv_flexlayouterr(struct nfsrv_descript *nd, uint32_t *layp,
     int maxcnt, NFSPROC_T *p);
 static int nfsrv_recalllayout(nfsquad_t clid, nfsv4stateid_t *stateidp,
-    fhandle_t *fhp, struct nfslayout *lyp, int laytype, NFSPROC_T *p);
+    fhandle_t *fhp, struct nfslayout *lyp, struct nfslayouthead *lyheadp,
+    int laytype, NFSPROC_T *p);
 static int nfsrv_findlayout(nfsquad_t *clientidp, fhandle_t *fhp, int laytype,
     NFSPROC_T *, struct nfslayout **lypp);
 static int nfsrv_fndclid(nfsquad_t *clidvec, nfsquad_t clid, int clidcnt);
@@ -6621,11 +6622,13 @@ nfsrv_flexmirrordel(char *devid, NFSPROC_T *p)
 		/*
 		 * The layout stateid.seqid needs to be incremented
 		 * before doing a LAYOUT_RECALL callback.
+		 * Set lay_trycnt to UINT16_MAX so it won't set up a retry.
 		 */
 		if (++lyp->lay_stateid.seqid == 0)
 			lyp->lay_stateid.seqid = 1;
+		lyp->lay_trycnt = UINT16_MAX;
 		nfsrv_recalllayout(lyp->lay_clientid, &lyp->lay_stateid,
-		    &lyp->lay_fh, lyp, lyp->lay_type, p);
+		    &lyp->lay_fh, lyp, &loclyp, lyp->lay_type, p);
 		nfsrv_freelayout(&loclyp, lyp);
 	}
 }
@@ -6635,7 +6638,8 @@ nfsrv_flexmirrordel(char *devid, NFSPROC_T *p)
  */
 static int
 nfsrv_recalllayout(nfsquad_t clid, nfsv4stateid_t *stateidp, fhandle_t *fhp,
-    struct nfslayout *lyp, int laytype, NFSPROC_T *p)
+    struct nfslayout *lyp, struct nfslayouthead *lyheadp, int laytype,
+    NFSPROC_T *p)
 {
 	struct nfsclient *clp;
 	int error;
@@ -6649,13 +6653,33 @@ nfsrv_recalllayout(nfsquad_t clid, nfsv4stateid_t *sta
 	if ((clp->lc_flags & LCL_NFSV41) != 0) {
 		error = nfsrv_docallback(clp, NFSV4OP_CBLAYOUTRECALL,
 		    stateidp, 0, fhp, NULL, NULL, laytype, p);
-		if (lyp != NULL && error == NFSERR_NOMATCHLAYOUT) {
+		/* If lyp != NULL, handle an error return here. */
+		if (error != 0 && lyp != NULL) {
 			NFSDRECALLLOCK();
-			if ((lyp->lay_flags & NFSLAY_RECALL) != 0) {
-				lyp->lay_flags |= NFSLAY_RETURNED;
-				wakeup(lyp);
-			}
-			NFSDRECALLUNLOCK();
+			if (error == NFSERR_NOMATCHLAYOUT) {
+				/*
+				 * Mark it returned, since there is no layout.
+				 */
+				if ((lyp->lay_flags & NFSLAY_RECALL) != 0) {
+					lyp->lay_flags |= NFSLAY_RETURNED;
+					wakeup(lyp);
+				}
+				NFSDRECALLUNLOCK();
+			} else if ((lyp->lay_flags & NFSLAY_RETURNED) == 0 &&
+			    lyp->lay_trycnt < 10) {
+				/*
+				 * Clear recall, so it can be tried again
+				 * and put it at the end of the list to
+				 * delay the retry a little longer.
+				 */
+				lyp->lay_flags &= ~NFSLAY_RECALL;
+				lyp->lay_trycnt++;
+				TAILQ_REMOVE(lyheadp, lyp, lay_list);
+				TAILQ_INSERT_TAIL(lyheadp, lyp, lay_list);
+				NFSDRECALLUNLOCK();
+				nfs_catnap(PVFS, 0, "nfsrclay");
+			} else
+				NFSDRECALLUNLOCK();
 		}
 	} else
 		printf("nfsrv_recalllayout: clp not NFSv4.1\n");
@@ -6673,7 +6697,7 @@ nfsrv_recalloldlayout(NFSPROC_T *p)
 	nfsquad_t clientid;
 	nfsv4stateid_t stateid;
 	fhandle_t fh;
-	int error, laytype;
+	int error, laytype, ret;
 
 	lhyp = &nfslayouthash[arc4random() % nfsrv_layouthashsize];
 	NFSLOCKLAYOUT(lhyp);
@@ -6695,26 +6719,43 @@ nfsrv_recalloldlayout(NFSPROC_T *p)
 	}
 	NFSUNLOCKLAYOUT(lhyp);
 	if (lyp != NULL) {
-		error = nfsrv_recalllayout(clientid, &stateid, &fh, NULL,
+		error = nfsrv_recalllayout(clientid, &stateid, &fh, NULL, NULL,
 		    laytype, p);
 		if (error != 0 && error != NFSERR_NOMATCHLAYOUT)
 			printf("recallold=%d\n", error);
-		if (error == NFSERR_NOMATCHLAYOUT) {
+		if (error != 0) {
+			NFSLOCKLAYOUT(lhyp);
 			/*
-			 * The client no longer knows this layout, so it can
-			 * be free'd now.
-			 * Since the hash list was unlocked, we need to find
-			 * it again.
+			 * Since the hash list was unlocked, we need to
+			 * find it again.
 			 */
-			NFSLOCKLAYOUT(lhyp);
-			error = nfsrv_findlayout(&clientid, &fh, laytype, p,
+			ret = nfsrv_findlayout(&clientid, &fh, laytype, p,
 			    &lyp);
-			if (error == 0 &&
+			if (ret == 0 &&
 			    (lyp->lay_flags & NFSLAY_CALLB) != 0 &&
 			    lyp->lay_stateid.other[0] == stateid.other[0] &&
 			    lyp->lay_stateid.other[1] == stateid.other[1] &&
-			    lyp->lay_stateid.other[2] == stateid.other[2])
-				nfsrv_freelayout(&lhyp->list, lyp);
+			    lyp->lay_stateid.other[2] == stateid.other[2]) {
+				/*
+				 * The client no longer knows this layout, so
+				 * it can be free'd now.
+				 */
+				if (error == NFSERR_NOMATCHLAYOUT)
+					nfsrv_freelayout(&lhyp->list, lyp);
+				else {
+					/*
+					 * Leave it to be tried later by
+					 * clearing NFSLAY_CALLB and moving
+					 * it to the head of the list, so it
+					 * won't be tried again for a while.
+					 */
+					lyp->lay_flags &= ~NFSLAY_CALLB;
+					TAILQ_REMOVE(&lhyp->list, lyp,
+					    lay_list);
+					TAILQ_INSERT_HEAD(&lhyp->list, lyp,
+					    lay_list);
+				}
+			}
 			NFSUNLOCKLAYOUT(lhyp);
 		}
 	}
@@ -7831,6 +7872,7 @@ nfsrv_copymr(vnode_t vp, vnode_t fvp, vnode_t dvp, str
 		    (lyp->lay_flags & NFSLAY_RW) != 0) {
 			TAILQ_REMOVE(&lhyp->list, lyp, lay_list);
 			TAILQ_INSERT_HEAD(&nfsrv_recalllisthead, lyp, lay_list);
+			lyp->lay_trycnt = 0;
 		}
 	}
 	NFSUNLOCKLAYOUT(lhyp);
@@ -7856,7 +7898,8 @@ tryagain:
 				lyp->lay_stateid.seqid = 1;
 			NFSDRECALLUNLOCK();
 			nfsrv_recalllayout(lyp->lay_clientid, &lyp->lay_stateid,
-			    &lyp->lay_fh, lyp, lyp->lay_type, p);
+			    &lyp->lay_fh, lyp, &nfsrv_recalllisthead,
+			    lyp->lay_type, p);
 			NFSD_DEBUG(4, "nfsrv_copymr: recalled layout\n");
 			goto tryagain;
 		}


More information about the svn-src-projects mailing list