svn commit: r210739 - stable/8/sys/fs/nfsserver

Rick Macklem rmacklem at FreeBSD.org
Sun Aug 1 23:36:39 UTC 2010


Author: rmacklem
Date: Sun Aug  1 23:36:39 2010
New Revision: 210739
URL: http://svn.freebsd.org/changeset/base/210739

Log:
  MFC: r210178
  Patch the experimental NFSv4 server so that it acquires a reference
  count on nfsv4rootfs_lock when dumping state, since these functions
  are not called by nfsd threads. Without this reference count, it
  is possible for an nfsd thread to acquire an exclusive lock on
  nfsv4rootfs_lock while the dump is in progress and then change the
  lists, potentially causing a crash.

Modified:
  stable/8/sys/fs/nfsserver/nfs_nfsdstate.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- stable/8/sys/fs/nfsserver/nfs_nfsdstate.c	Sun Aug  1 22:39:07 2010	(r210738)
+++ stable/8/sys/fs/nfsserver/nfs_nfsdstate.c	Sun Aug  1 23:36:39 2010	(r210739)
@@ -600,6 +600,13 @@ nfsrv_dumpclients(struct nfsd_dumpclient
 	struct nfsclient *clp;
 	int i = 0, cnt = 0;
 
+	/*
+	 * First, get a reference on the nfsv4rootfs_lock so that an
+	 * exclusive lock cannot be acquired while dumping the clients.
+	 */
+	NFSLOCKV4ROOTMUTEX();
+	nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR);
+	NFSUNLOCKV4ROOTMUTEX();
 	NFSLOCKSTATE();
 	/*
 	 * Rattle through the client lists until done.
@@ -616,6 +623,9 @@ nfsrv_dumpclients(struct nfsd_dumpclient
 	if (cnt < maxcnt)
 	    dumpp[cnt].ndcl_clid.nclid_idlen = 0;
 	NFSUNLOCKSTATE();
+	NFSLOCKV4ROOTMUTEX();
+	nfsv4_relref(&nfsv4rootfs_lock);
+	NFSUNLOCKV4ROOTMUTEX();
 }
 
 /*
@@ -691,12 +701,22 @@ nfsrv_dumplocks(vnode_t vp, struct nfsd_
 	fhandle_t nfh;
 
 	ret = nfsrv_getlockfh(vp, 0, NULL, &nfh, p);
+	/*
+	 * First, get a reference on the nfsv4rootfs_lock so that an
+	 * exclusive lock on it cannot be acquired while dumping the locks.
+	 */
+	NFSLOCKV4ROOTMUTEX();
+	nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR);
+	NFSUNLOCKV4ROOTMUTEX();
 	NFSLOCKSTATE();
 	if (!ret)
 		ret = nfsrv_getlockfile(0, NULL, &lfp, &nfh, 0);
 	if (ret) {
 		ldumpp[0].ndlck_clid.nclid_idlen = 0;
 		NFSUNLOCKSTATE();
+		NFSLOCKV4ROOTMUTEX();
+		nfsv4_relref(&nfsv4rootfs_lock);
+		NFSUNLOCKV4ROOTMUTEX();
 		return;
 	}
 
@@ -797,6 +817,9 @@ nfsrv_dumplocks(vnode_t vp, struct nfsd_
 	if (cnt < maxcnt)
 		ldumpp[cnt].ndlck_clid.nclid_idlen = 0;
 	NFSUNLOCKSTATE();
+	NFSLOCKV4ROOTMUTEX();
+	nfsv4_relref(&nfsv4rootfs_lock);
+	NFSUNLOCKV4ROOTMUTEX();
 }
 
 /*


More information about the svn-src-stable-8 mailing list