aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2019-03-12 10:39:47 -0700
committerGitHub <[email protected]>2019-03-12 10:39:47 -0700
commitdd785b5b86bbb7ebbfe1d22668f3dd27c5704994 (patch)
treed9508260a8382982db0f2a43f589ab5453eaedf1
parent3d31aad83e6420d7a2f661ca077afdac13f50b77 (diff)
Fix vdev_initialize_restart / removal race
Resolve a vdev_initialize crash uncovered by ztest. Similar to when starting a new initialization verify that a removal is not in progress. Additionally, do not restart when the thread already exists. This check is now congruent with the POOL_INITIALIZE_DO handling in spa_vdev_initialize_impl(). Reviewed-by: Tom Caputi <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #8477
-rw-r--r--module/zfs/vdev_initialize.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/module/zfs/vdev_initialize.c b/module/zfs/vdev_initialize.c
index bec89a28e..bca2db7a4 100644
--- a/module/zfs/vdev_initialize.c
+++ b/module/zfs/vdev_initialize.c
@@ -68,7 +68,7 @@ vdev_initialize_zap_update_sync(void *arg, dmu_tx_t *tx)
* We pass in the guid instead of the vdev_t since the vdev may
* have been freed prior to the sync task being processed. This
* happens when a vdev is detached as we call spa_config_vdev_exit(),
- * stop the intializing thread, schedule the sync task, and free
+ * stop the initializing thread, schedule the sync task, and free
* the vdev. Later when the scheduled sync task is invoked, it would
* find that the vdev has been freed.
*/
@@ -838,7 +838,9 @@ vdev_initialize_restart(vdev_t *vd)
/* load progress for reporting, but don't resume */
VERIFY0(vdev_initialize_load(vd));
} else if (vd->vdev_initialize_state ==
- VDEV_INITIALIZE_ACTIVE && vdev_writeable(vd)) {
+ VDEV_INITIALIZE_ACTIVE && vdev_writeable(vd) &&
+ !vd->vdev_top->vdev_removing &&
+ vd->vdev_initialize_thread == NULL) {
vdev_initialize(vd);
}