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-stable-10
mailing list