OpenZFS 9690 - metaslab of vdev with no space maps was flushed during removal

Authored by: Serapheim Dimitropoulos <serapheim@delphix.com>
Reviewed by: Matt Ahrens <matt@delphix.com>
Reviewed by: Brad Lewis <brad.lewis@delphix.com>
Reviewed by: George Melikov <mail@gmelikov.ru>
Approved by: Robert Mustacchi <rm@joyent.com>
Ported-by: Brian Behlendorf <behlendorf1@llnl.gov>

OpenZFS-issue: https://www.illumos.org/issues/9690
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/4e75ba6826
Closes #8039
This commit is contained in:
Serapheim Dimitropoulos 2018-05-15 10:43:25 -07:00 committed by Brian Behlendorf
parent d637db98e1
commit ee900344f2

View File

@ -3129,11 +3129,11 @@ vdev_destroy_spacemaps(vdev_t *vd, dmu_tx_t *tx)
} }
static void static void
vdev_remove_empty(vdev_t *vd, uint64_t txg) vdev_remove_empty_log(vdev_t *vd, uint64_t txg)
{ {
spa_t *spa = vd->vdev_spa; spa_t *spa = vd->vdev_spa;
dmu_tx_t *tx;
ASSERT(vd->vdev_islog);
ASSERT(vd == vd->vdev_top); ASSERT(vd == vd->vdev_top);
ASSERT3U(txg, ==, spa_syncing_txg(spa)); ASSERT3U(txg, ==, spa_syncing_txg(spa));
@ -3178,13 +3178,14 @@ vdev_remove_empty(vdev_t *vd, uint64_t txg)
ASSERT0(mg->mg_histogram[i]); ASSERT0(mg->mg_histogram[i]);
} }
tx = dmu_tx_create_assigned(spa_get_dsl(spa), txg); dmu_tx_t *tx = dmu_tx_create_assigned(spa_get_dsl(spa), txg);
vdev_destroy_spacemaps(vd, tx);
if (vd->vdev_islog && vd->vdev_top_zap != 0) { vdev_destroy_spacemaps(vd, tx);
if (vd->vdev_top_zap != 0) {
vdev_destroy_unlink_zap(vd, vd->vdev_top_zap, tx); vdev_destroy_unlink_zap(vd, vd->vdev_top_zap, tx);
vd->vdev_top_zap = 0; vd->vdev_top_zap = 0;
} }
dmu_tx_commit(tx); dmu_tx_commit(tx);
} }
@ -3255,14 +3256,11 @@ vdev_sync(vdev_t *vd, uint64_t txg)
vdev_dtl_sync(lvd, txg); vdev_dtl_sync(lvd, txg);
/* /*
* Remove the metadata associated with this vdev once it's empty. * If this is an empty log device being removed, destroy the
* Note that this is typically used for log/cache device removal; * metadata associated with it.
* we don't empty toplevel vdevs when removing them. But if
* a toplevel happens to be emptied, this is not harmful.
*/ */
if (vd->vdev_stat.vs_alloc == 0 && vd->vdev_removing) { if (vd->vdev_islog && vd->vdev_stat.vs_alloc == 0 && vd->vdev_removing)
vdev_remove_empty(vd, txg); vdev_remove_empty_log(vd, txg);
}
(void) txg_list_add(&spa->spa_vdev_txg_list, vd, TXG_CLEAN(txg)); (void) txg_list_add(&spa->spa_vdev_txg_list, vd, TXG_CLEAN(txg));
} }