Date: Sat, 7 May 2016 20:09:15 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r299222 - in stable/10/sys/fs: nfs nfsserver Message-ID: <201605072009.u47K9FJv032273@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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++)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605072009.u47K9FJv032273>