Mercurial > illumos > illumos-gate
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