diff options
author | Brian Behlendorf <[email protected]> | 2019-03-12 10:39:47 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2019-03-12 10:39:47 -0700 |
commit | dd785b5b86bbb7ebbfe1d22668f3dd27c5704994 (patch) | |
tree | d9508260a8382982db0f2a43f589ab5453eaedf1 /module/zfs | |
parent | 3d31aad83e6420d7a2f661ca077afdac13f50b77 (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
Diffstat (limited to 'module/zfs')
-rw-r--r-- | module/zfs/vdev_initialize.c | 6 |
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); } |