]> granicus.if.org Git - zfs/commitdiff
Fix vdev removal finishing race
authorTom Caputi <tcaputi@datto.com>
Wed, 7 Nov 2018 23:38:10 +0000 (18:38 -0500)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 7 Nov 2018 23:38:10 +0000 (15:38 -0800)
This patch fixes a race condition where the end of
vdev_remove_replace_with_indirect(), which holds
svr_lock, would race against spa_vdev_removal_destroy(),
which destroys the same lock and is called asynchronously
via dsl_sync_task_nowait().

Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Issue #6900
Closes #8083

module/zfs/vdev_removal.c

index 4e4a6c4f5a250d0554e411860cf3fc7efd853dbd..c259b5a1b45cb2a74d71bb19b36a65433f72b2a8 100644 (file)
@@ -1115,19 +1115,16 @@ vdev_remove_replace_with_indirect(vdev_t *vd, uint64_t txg)
 
        ASSERT(!list_link_active(&vd->vdev_state_dirty_node));
 
-       tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
-       dsl_sync_task_nowait(spa->spa_dsl_pool, vdev_remove_complete_sync, svr,
-           0, ZFS_SPACE_CHECK_NONE, tx);
-       dmu_tx_commit(tx);
-
-       /*
-        * Indicate that this thread has exited.
-        * After this, we can not use svr.
-        */
        mutex_enter(&svr->svr_lock);
        svr->svr_thread = NULL;
        cv_broadcast(&svr->svr_cv);
        mutex_exit(&svr->svr_lock);
+
+       /* After this, we can not use svr. */
+       tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
+       dsl_sync_task_nowait(spa->spa_dsl_pool, vdev_remove_complete_sync, svr,
+           0, ZFS_SPACE_CHECK_NONE, tx);
+       dmu_tx_commit(tx);
 }
 
 /*