From 4d04273f2ee96d881d072f95c50570e17dc3a635 Mon Sep 17 00:00:00 2001 From: Eric Taylor Date: Mon, 20 Oct 2008 08:51:30 -0600 Subject: 6752810 deadlock when trying to online missing boot drive --- usr/src/uts/common/fs/zfs/vdev.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'usr/src/uts/common/fs/zfs/vdev.c') diff --git a/usr/src/uts/common/fs/zfs/vdev.c b/usr/src/uts/common/fs/zfs/vdev.c index 2b0ad52561..240f955ea2 100644 --- a/usr/src/uts/common/fs/zfs/vdev.c +++ b/usr/src/uts/common/fs/zfs/vdev.c @@ -1642,7 +1642,7 @@ vdev_fault(spa_t *spa, uint64_t guid) vdev_set_state(vd, B_FALSE, VDEV_STATE_FAULTED, VDEV_AUX_ERR_EXCEEDED); /* - * If marking the vdev as faulted cause the top-level vdev to become + * If marking the vdev as faulted causes the top-level vdev to become * unavailable, then back off and simply mark the vdev as degraded * instead. */ @@ -1708,6 +1708,27 @@ vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *newstate) { vdev_t *vd; + if (spa_is_root(spa)) { + /* + * if we're trying to online a device that's part of + * the root pool, trigger an attach (if any) with only + * the SCL_STATE lock held in order to avoid a deadlock + * where modload tries to read from the disk + */ + spa_config_enter(spa, SCL_STATE, FTAG, RW_WRITER); + if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) { + spa_config_exit(spa, SCL_STATE, FTAG); + return (ENODEV); + } + if (!vd->vdev_ops->vdev_op_leaf) { + spa_config_exit(spa, SCL_STATE, FTAG); + return (ENOTSUP); + } + vdev_close(vd); + vdev_open(vd); + spa_config_exit(spa, SCL_STATE, FTAG); + } + spa_vdev_state_enter(spa); if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) -- cgit v1.2.3