Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Jul 2018 20:03:05 +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: r336260 - head/sys/fs/nfsclient
Message-ID:  <201807132003.w6DK35MK095550@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Fri Jul 13 20:03:05 2018
New Revision: 336260
URL: https://svnweb.freebsd.org/changeset/base/336260

Log:
  Close down the TCP connection to a pNFS DS when it is disabled.
  
  So long as the TCP connection to a pNFS DS isn't shared with other DSs,
  it can be closed down when the DS is being disabled in the pNFS client.
  This causes any RPCs in progress to fail.
  This patch only affects the NFSv4.1 pNFS client when errors occur
  while doing I/O on a DS.
  
  MFC after:	2 weeks

Modified:
  head/sys/fs/nfsclient/nfs_clstate.c

Modified: head/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clstate.c	Fri Jul 13 19:54:22 2018	(r336259)
+++ head/sys/fs/nfsclient/nfs_clstate.c	Fri Jul 13 20:03:05 2018	(r336260)
@@ -125,6 +125,7 @@ static struct nfscldeleg *nfscl_finddeleg(struct nfscl
 static void nfscl_retoncloselayout(vnode_t, struct nfsclclient *, uint8_t *,
     int, struct nfsclrecalllayout **);
 static void nfscl_reldevinfo_locked(struct nfscldevinfo *);
+static void nfscl_cancelreqs(struct nfsclds *);
 static struct nfscllayout *nfscl_findlayout(struct nfsclclient *, u_int8_t *,
     int);
 static struct nfscldevinfo *nfscl_finddevinfo(struct nfsclclient *, uint8_t *);
@@ -4971,14 +4972,16 @@ nfscl_retoncloselayout(vnode_t vp, struct nfsclclient 
 
 /*
  * Mark the layout to be recalled and with an error.
+ * Also, disable the dsp from further use.
  */
 void
 nfscl_dserr(uint32_t op, uint32_t stat, struct nfscldevinfo *dp,
-    struct nfscllayout *lyp, __unused struct nfsclds *dsp)
+    struct nfscllayout *lyp, struct nfsclds *dsp)
 {
 	struct nfsclrecalllayout *recallp;
 	uint32_t iomode;
 
+	printf("DS being disabled, error=%d\n", stat);
 	/* Set up the return of the layout. */
 	recallp = malloc(sizeof(*recallp), M_NFSLAYRECALL, M_WAITOK);
 	iomode = 0;
@@ -4997,6 +5000,39 @@ nfscl_dserr(uint32_t op, uint32_t stat, struct nfsclde
 		NFSUNLOCKCLSTATE();
 		free(recallp, M_NFSLAYRECALL);
 	}
+
+	/* If the connection isn't used for other DSs, we can shut it down. */
+	if ((dsp->nfsclds_flags & NFSCLDS_SAMECONN) == 0)
+		nfscl_cancelreqs(dsp);
+}
+
+/*
+ * Cancel all RPCs for this "dsp" by closing the connection.
+ * Also, mark the session as defunct.
+ */
+static void
+nfscl_cancelreqs(struct nfsclds *dsp)
+{
+	struct __rpc_client *cl;
+	static int non_event;
+
+	NFSLOCKDS(dsp);
+	if ((dsp->nfsclds_flags & (NFSCLDS_CLOSED | NFSCLDS_SAMECONN)) == 0 &&
+	    dsp->nfsclds_sockp != NULL &&
+	    dsp->nfsclds_sockp->nr_client != NULL) {
+		dsp->nfsclds_flags |= NFSCLDS_CLOSED;
+		cl = dsp->nfsclds_sockp->nr_client;
+		dsp->nfsclds_sess.nfsess_defunct = 1;
+		NFSUNLOCKDS(dsp);
+		CLNT_CLOSE(cl);
+		/*
+		 * This 1sec sleep is done to reduce the number of reconnect
+		 * attempts made on the DS while it has failed.
+		 */
+		tsleep(&non_event, PVFS, "ndscls", hz);
+		return;
+	}
+	NFSUNLOCKDS(dsp);
 }
 
 /*



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