svn commit: r299222 - in stable/10/sys/fs: nfs nfsserver

Rick Macklem rmacklem at FreeBSD.org
Sat May 7 20:09:17 UTC 2016


Author: rmacklem
Date: Sat May  7 20:09:15 2016
New Revision: 299222
URL: https://svnweb.freebsd.org/changeset/base/299222

Log:
  MFC: r298495
  Fix a LOR in the NFSv4.1 server.
  
  The ordering of acquisition of the state and session mutexes was
  reversed in two cases executed when an NFSv4.1 client created/freed
  a session. Since clients will typically do this only when mounting
  and dismounting, the likelyhood of causing a deadlock was low but possible.
  This can only occur for NFSv4.1 mounts, since the others do not
  use sessions.
  This was detected while testing the pNFS server/client where the
  client crashed during dismounting.
  The patch also reorders the unlocks, although that isn't necessary
  for correct operation.

Modified:
  stable/10/sys/fs/nfs/nfsrvstate.h
  stable/10/sys/fs/nfsserver/nfs_nfsdstate.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/fs/nfs/nfsrvstate.h
==============================================================================
--- stable/10/sys/fs/nfs/nfsrvstate.h	Sat May  7 19:05:39 2016	(r299221)
+++ stable/10/sys/fs/nfs/nfsrvstate.h	Sat May  7 20:09:15 2016	(r299222)
@@ -113,7 +113,7 @@ struct nfsclient {
  * Structure for an NFSv4.1 session.
  * Locking rules for this structure.
  * To add/delete one of these structures from the lists, you must lock
- * both: NFSLOCKSESSION(session hashhead) and NFSLOCKSTATE() in that order.
+ * both: NFSLOCKSTATE() and NFSLOCKSESSION(session hashhead) in that order.
  * To traverse the lists looking for one of these, you must hold one
  * of these two locks.
  * The exception is if the thread holds the exclusive root sleep lock.

Modified: stable/10/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- stable/10/sys/fs/nfsserver/nfs_nfsdstate.c	Sat May  7 19:05:39 2016	(r299221)
+++ stable/10/sys/fs/nfsserver/nfs_nfsdstate.c	Sat May  7 20:09:15 2016	(r299222)
@@ -629,13 +629,13 @@ nfsrv_getclient(nfsquad_t clientid, int 
 			NFSBCOPY(sessid, nsep->sess_cbsess.nfsess_sessionid,
 			    NFSX_V4SESSIONID);
 			shp = NFSSESSIONHASH(nsep->sess_sessionid);
+			NFSLOCKSTATE();
 			NFSLOCKSESSION(shp);
 			LIST_INSERT_HEAD(&shp->list, nsep, sess_hash);
-			NFSLOCKSTATE();
 			LIST_INSERT_HEAD(&clp->lc_session, nsep, sess_list);
 			nsep->sess_clp = clp;
-			NFSUNLOCKSTATE();
 			NFSUNLOCKSESSION(shp);
+			NFSUNLOCKSTATE();
 		    }
 		}
 	} else if (clp->lc_flags & LCL_NEEDSCONFIRM) {
@@ -5915,6 +5915,7 @@ nfsrv_freesession(struct nfsdsession *se
 	struct nfssessionhash *shp;
 	int i;
 
+	NFSLOCKSTATE();
 	if (sep == NULL) {
 		shp = NFSSESSIONHASH(sessionid);
 		NFSLOCKSESSION(shp);
@@ -5924,18 +5925,17 @@ nfsrv_freesession(struct nfsdsession *se
 		NFSLOCKSESSION(shp);
 	}
 	if (sep != NULL) {
-		NFSLOCKSTATE();
 		sep->sess_refcnt--;
 		if (sep->sess_refcnt > 0) {
-			NFSUNLOCKSTATE();
 			NFSUNLOCKSESSION(shp);
+			NFSUNLOCKSTATE();
 			return (0);
 		}
 		LIST_REMOVE(sep, sess_hash);
 		LIST_REMOVE(sep, sess_list);
-		NFSUNLOCKSTATE();
 	}
 	NFSUNLOCKSESSION(shp);
+	NFSUNLOCKSTATE();
 	if (sep == NULL)
 		return (NFSERR_BADSESSION);
 	for (i = 0; i < NFSV4_SLOTS; i++)


More information about the svn-src-all mailing list