changeset 264:a6f0352ce83a

6266836 panic: recursive mutex acquisition in nfs_mi_zonelist_remove()
author thurlow
date Fri, 29 Jul 2005 16:17:08 -0700
parents 7d7b54507975
children a968e4ece133
files usr/src/uts/common/fs/nfs/nfs4_client.c usr/src/uts/common/fs/nfs/nfs_client.c usr/src/uts/common/nfs/nfs4_clnt.h usr/src/uts/common/nfs/nfs_clnt.h
diffstat 4 files changed, 47 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/nfs/nfs4_client.c	Fri Jul 29 13:37:38 2005 -0700
+++ b/usr/src/uts/common/fs/nfs/nfs4_client.c	Fri Jul 29 16:17:08 2005 -0700
@@ -2785,11 +2785,24 @@
 	NFS4_DEBUG(nfs4_client_zone_debug, (CE_NOTE,
 	    "nfs4_mi_shutdown zone %d\n", zoneid));
 	ASSERT(mig != NULL);
+again:
 	mutex_enter(&mig->mig_lock);
 	for (mi = list_head(&mig->mig_list); mi != NULL;
 	    mi = list_next(&mig->mig_list, mi)) {
+		/*
+		 * If we've done the shutdown work for this FS, skip.
+		 * Once we go off the end of the list, we're done.
+		 */
+		if (mi->mi_flags & MI4_DEAD)
+			continue;
+
+		/*
+		 * We will do work, so not done.  Get a hold on the FS.
+		 */
 		NFS4_DEBUG(nfs4_client_zone_debug, (CE_NOTE,
 		    "nfs4_mi_shutdown stopping vfs %p\n", (void *)mi->mi_vfsp));
+		VFS_HOLD(mi->mi_vfsp);
+
 		/*
 		 * purge the DNLC for this filesystem
 		 */
@@ -2815,6 +2828,14 @@
 		 */
 		cv_broadcast(&mi->mi_async_reqs_cv);
 		mutex_exit(&mi->mi_async_lock);
+
+		/*
+		 * Drop lock and release FS, which may change list, then repeat.
+		 * We're done when every mi has been done or the list is empty.
+		 */
+		mutex_exit(&mig->mig_lock);
+		VFS_RELE(mi->mi_vfsp);
+		goto again;
 	}
 	mutex_exit(&mig->mig_lock);
 	/*
--- a/usr/src/uts/common/fs/nfs/nfs_client.c	Fri Jul 29 13:37:38 2005 -0700
+++ b/usr/src/uts/common/fs/nfs/nfs_client.c	Fri Jul 29 16:17:08 2005 -0700
@@ -2518,9 +2518,23 @@
 	mntinfo_t *mi;
 
 	ASSERT(mig != NULL);
+again:
 	mutex_enter(&mig->mig_lock);
 	for (mi = list_head(&mig->mig_list); mi != NULL;
 	    mi = list_next(&mig->mig_list, mi)) {
+
+		/*
+		 * If we've done the shutdown work for this FS, skip.
+		 * Once we go off the end of the list, we're done.
+		 */
+		if (mi->mi_flags & MI_DEAD)
+			continue;
+
+		/*
+		 * We will do work, so not done.  Get a hold on the FS.
+		 */
+		VFS_HOLD(mi->mi_vfsp);
+
 		/*
 		 * purge the DNLC for this filesystem
 		 */
@@ -2535,15 +2549,24 @@
 		/*
 		 * Set MI_ASYNC_MGR_STOP so the async manager thread starts
 		 * getting ready to exit when it's done with its current work.
+		 * Also set MI_DEAD to note we've acted on this FS.
 		 */
 		mutex_enter(&mi->mi_lock);
-		mi->mi_flags |= MI_ASYNC_MGR_STOP;
+		mi->mi_flags |= (MI_ASYNC_MGR_STOP|MI_DEAD);
 		mutex_exit(&mi->mi_lock);
 		/*
 		 * Wake up the async manager thread.
 		 */
 		cv_broadcast(&mi->mi_async_reqs_cv);
 		mutex_exit(&mi->mi_async_lock);
+
+		/*
+		 * Drop lock and release FS, which may change list, then repeat.
+		 * We're done when every mi has been done or the list is empty.
+		 */
+		mutex_exit(&mig->mig_lock);
+		VFS_RELE(mi->mi_vfsp);
+		goto again;
 	}
 	mutex_exit(&mig->mig_lock);
 }
--- a/usr/src/uts/common/nfs/nfs4_clnt.h	Fri Jul 29 13:37:38 2005 -0700
+++ b/usr/src/uts/common/nfs/nfs4_clnt.h	Fri Jul 29 16:17:08 2005 -0700
@@ -1038,7 +1038,7 @@
  *	MI4_MOUNTING		 mount in progress, don't failover
  *	MI4_POSIX_LOCK		 if server is using POSIX locking
  *	MI4_LOCK_DEBUG		 cmn_err'd posix lock err msg
- *	MI4_DEAD		 last VFS_RELE() called on mount
+ *	MI4_DEAD		 mount has been terminated
  *	MI4_INACTIVE_IDLE	 inactive thread idle
  *	MI4_BADOWNER_DEBUG	 badowner error msg per mount
  *	MI4_ASYNC_MGR_STOP	 tell async manager to die
--- a/usr/src/uts/common/nfs/nfs_clnt.h	Fri Jul 29 13:37:38 2005 -0700
+++ b/usr/src/uts/common/nfs/nfs_clnt.h	Fri Jul 29 16:17:08 2005 -0700
@@ -423,6 +423,7 @@
 #define	MI_DIRECTIO	0x40000		/* do direct I/O */
 #define	MI_EXTATTR	0x80000		/* server supports extended attrs */
 #define	MI_ASYNC_MGR_STOP	0x100000	/* tell async mgr to die */
+#define	MI_DEAD		0x200000	/* mount has been terminated */
 
 /*
  * Read-only mntinfo statistics