Mercurial > illumos > illumos-gate
changeset 12895:5c6de9ad51b9
6962062 recurring bad pointer panic in autofs:unmount_subtree
author | Jan Kryl <Jan.Kryl@Sun.COM> |
---|---|
date | Wed, 21 Jul 2010 17:59:37 +0200 |
parents | 5213e1b8c605 |
children | 8ed2c2ace7da |
files | usr/src/uts/common/fs/autofs/auto_subr.c usr/src/uts/common/sys/fs/autofs.h |
diffstat | 2 files changed, 24 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/autofs/auto_subr.c Wed Jul 21 14:36:46 2010 +0100 +++ b/usr/src/uts/common/fs/autofs/auto_subr.c Wed Jul 21 17:59:37 2010 +0200 @@ -2359,6 +2359,28 @@ */ if (currfnp->fn_unmount_ref_time < timestamp) currfnp->fn_unmount_ref_time = timestamp; + + /* + * Don't descent below nodes, which are being unmounted/mounted. + * + * We need to hold both locks at once: fn_lock because we need + * to read MF_INPROG and fn_rwlock to prevent anybody from + * modifying fn_trigger until its used to traverse triggers + * below. + * + * Acquire fn_rwlock in non-blocking mode to avoid deadlock. + * If it can't be acquired, then acquire locks in correct + * order. + */ + if (!rw_tryenter(&currfnp->fn_rwlock, RW_READER)) { + mutex_exit(&currfnp->fn_lock); + rw_enter(&currfnp->fn_rwlock, RW_READER); + mutex_enter(&currfnp->fn_lock); + } + if (currfnp->fn_flags & MF_INPROG) { + rw_exit(&currfnp->fn_rwlock); + continue; + } mutex_exit(&currfnp->fn_lock); /* @@ -2366,7 +2388,6 @@ * mounts. */ - rw_enter(&currfnp->fn_rwlock, RW_READER); if ((nextfnp = currfnp->fn_trigger) != NULL) { VN_HOLD(fntovn(nextfnp)); rw_exit(&currfnp->fn_rwlock);
--- a/usr/src/uts/common/sys/fs/autofs.h Wed Jul 21 14:36:46 2010 +0100 +++ b/usr/src/uts/common/sys/fs/autofs.h Wed Jul 21 17:59:37 2010 +0200 @@ -107,6 +107,8 @@ * - Grab writers to add a new fnnode under fn_dirents and * to remove a node pointed to by fn_dirents or fn_next. * + * Lock ordering: + * fn_rwlock > fn_lock * * The flags: * MF_INPROG: