]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Fix vdev_initialize_restart / removal race
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 12 Mar 2019 17:39:47 +0000 (10:39 -0700)
committerGitHub <noreply@github.com>
Tue, 12 Mar 2019 17:39:47 +0000 (10:39 -0700)
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 <tcaputi@datto.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #8477

module/zfs/vdev_initialize.c

index bec89a28eefb9a6088a078a15d92c6715601e12c..bca2db7a4838d8bcc20dde5ca250e8656eff768f 100644 (file)
@@ -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);
                }