svn commit: r210178 - head/sys/fs/nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Fri Jul 16 23:17:05 UTC 2010
Author: rmacklem
Date: Fri Jul 16 23:17:05 2010
New Revision: 210178
URL: http://svn.freebsd.org/changeset/base/210178
Log:
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.
Reported by: zack.kirsch at isilon.com
MFC after: 2 weeks
Modified:
head/sys/fs/nfsserver/nfs_nfsdstate.c
Modified: head/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdstate.c Fri Jul 16 22:58:13 2010 (r210177)
+++ head/sys/fs/nfsserver/nfs_nfsdstate.c Fri Jul 16 23:17:05 2010 (r210178)
@@ -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-head
mailing list