From 6be2e73284dbe7b2fffebbfc119ae3aae4e82cbb Mon Sep 17 00:00:00 2001 From: Olaf Faaland Date: Thu, 8 Mar 2018 15:21:54 -0800 Subject: [PATCH 1/2] Handle zio_resume and mmp => off When multihost is disabled on a pool, and the pool is resumed via zpool clear, within a single cycle of the mmp thread's loop (e.g. while it's in the cv_timedwait call), both mmp_last_write and mmp_delay should be updated. The original code mistakenly treated the two cases as if they could not occur at the same time. Signed-off-by: Olaf Faaland --- module/zfs/mmp.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c index cb0aa53d6a48..420b8441c3f7 100644 --- a/module/zfs/mmp.c +++ b/module/zfs/mmp.c @@ -474,16 +474,22 @@ mmp_thread(void *arg) } /* - * When MMP goes off => on, or spa goes suspended => - * !suspended, we know no writes occurred recently. We - * update mmp_last_write to give us some time to try. + * MMP off => on, or suspended => !suspended: + * No writes occurred recently. Update mmp_last_write to give + * us some time to try. */ if ((!last_spa_multihost && multihost) || (last_spa_suspended && !suspended)) { mutex_enter(&mmp->mmp_io_lock); mmp->mmp_last_write = gethrtime(); mutex_exit(&mmp->mmp_io_lock); - } else if (last_spa_multihost && !multihost) { + } + + /* + * MMP on => off: + * mmp_delay == 0 tells importing node to skip activity check. + */ + if (last_spa_multihost && !multihost) { mutex_enter(&mmp->mmp_io_lock); mmp->mmp_delay = 0; mutex_exit(&mmp->mmp_io_lock); From d9d3f93402c9aea7b14458c310983696caf8fa90 Mon Sep 17 00:00:00 2001 From: Olaf Faaland Date: Thu, 8 Mar 2018 15:39:07 -0800 Subject: [PATCH 2/2] Hold SCL_VDEV when counting leaves A config lock should be held while vdev_count_leaves() walks the tree, otherwise the pointers reference may become invalid during the walk. SCL_VDEV is a minimal lock provided for such uses cases. Signed-off-by: Olaf Faaland --- module/zfs/vdev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index c73b2e7f2ddd..172485f6e495 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -209,7 +209,13 @@ vdev_count_leaves_impl(vdev_t *vd) int vdev_count_leaves(spa_t *spa) { - return (vdev_count_leaves_impl(spa->spa_root_vdev)); + int rc; + + spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER); + rc = vdev_count_leaves_impl(spa->spa_root_vdev); + spa_config_exit(spa, SCL_VDEV, FTAG); + + return (rc); } void