Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Nov 2013 21:24:56 +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: r257901 - in head/sys/fs: nfs nfsclient
Message-ID:  <201311092124.rA9LOup4046654@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sat Nov  9 21:24:56 2013
New Revision: 257901
URL: http://svnweb.freebsd.org/changeset/base/257901

Log:
  Fix an NFSv4.1 client specific case where a forced dismount would hang.
  The hang occurred in nfsv4_setsequence() when it couldn't find an
  available session slot and is fixed by checking for a forced dismount
  in progress and just returning for this case.
  
  MFC after:	1 month

Modified:
  head/sys/fs/nfs/nfs_commonsubs.c
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfsclient/nfs_clcomsubs.c

Modified: head/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- head/sys/fs/nfs/nfs_commonsubs.c	Sat Nov  9 20:36:52 2013	(r257900)
+++ head/sys/fs/nfs/nfs_commonsubs.c	Sat Nov  9 21:24:56 2013	(r257901)
@@ -3693,8 +3693,8 @@ nfsv4_seqsess_cacherep(uint32_t slotid, 
  * Generate the xdr for an NFSv4.1 Sequence Operation.
  */
 APPLESTATIC void
-nfsv4_setsequence(struct nfsrv_descript *nd, struct nfsclsession *sep,
-    int dont_replycache)
+nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd,
+    struct nfsclsession *sep, int dont_replycache)
 {
 	uint32_t *tl, slotseq = 0;
 	int i, maxslot, slotpos;
@@ -3717,9 +3717,21 @@ nfsv4_setsequence(struct nfsrv_descript 
 			}
 			bitval <<= 1;
 		}
-		if (slotpos == -1)
+		if (slotpos == -1) {
+			/*
+			 * If a forced dismount is in progress, just return.
+			 * This RPC attempt will fail when it calls
+			 * newnfs_request().
+			 */
+			if ((nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF)
+			    != 0) {
+				mtx_unlock(&sep->nfsess_mtx);
+				return;
+			}
+			/* Wake up once/sec, to check for a forced dismount. */
 			(void)mtx_sleep(&sep->nfsess_slots, &sep->nfsess_mtx,
-			    PZERO, "nfsclseq", 0);
+			    PZERO, "nfsclseq", hz);
+		}
 	} while (slotpos == -1);
 	/* Now, find the highest slot in use. (nfsc_slots is 64bits) */
 	bitval = 1;

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h	Sat Nov  9 20:36:52 2013	(r257900)
+++ head/sys/fs/nfs/nfs_var.h	Sat Nov  9 21:24:56 2013	(r257901)
@@ -265,7 +265,8 @@ int nfsv4_getipaddr(struct nfsrv_descrip
 int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *,
     struct mbuf **, uint16_t);
 void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, struct mbuf *);
-void nfsv4_setsequence(struct nfsrv_descript *, struct nfsclsession *, int);
+void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *,
+    struct nfsclsession *, int);
 void nfsv4_freeslot(struct nfsclsession *, int);
 
 /* nfs_clcomsubs.c */

Modified: head/sys/fs/nfsclient/nfs_clcomsubs.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clcomsubs.c	Sat Nov  9 20:36:52 2013	(r257900)
+++ head/sys/fs/nfsclient/nfs_clcomsubs.c	Sat Nov  9 21:24:56 2013	(r257901)
@@ -203,10 +203,11 @@ nfscl_reqstart(struct nfsrv_descript *nd
 			NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
 			*tl = txdr_unsigned(NFSV4OP_SEQUENCE);
 			if (sep == NULL)
-				nfsv4_setsequence(nd, NFSMNT_MDSSESSION(nmp),
+				nfsv4_setsequence(nmp, nd,
+				    NFSMNT_MDSSESSION(nmp),
 				    nfs_bigreply[procnum]);
 			else
-				nfsv4_setsequence(nd, sep,
+				nfsv4_setsequence(nmp, nd, sep,
 				    nfs_bigreply[procnum]);
 		}
 		if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {



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