aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerapheim Dimitropoulos <[email protected]>2018-05-15 10:43:25 -0700
committerBrian Behlendorf <[email protected]>2018-10-19 12:05:03 -0700
commitee900344f2f81cd3cc8dda95e8e8e41497d58001 (patch)
tree8f69fcc15ef3d774d5784cdf05fbfd080743561d
parentd637db98e17e05c86afbf2e91793c12daffbf421 (diff)
OpenZFS 9690 - metaslab of vdev with no space maps was flushed during removal
Authored by: Serapheim Dimitropoulos <[email protected]> Reviewed by: Matt Ahrens <[email protected]> Reviewed by: Brad Lewis <[email protected]> Reviewed by: George Melikov <[email protected]> Approved by: Robert Mustacchi <[email protected]> Ported-by: Brian Behlendorf <[email protected]> OpenZFS-issue: https://www.illumos.org/issues/9690 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/4e75ba6826 Closes #8039
-rw-r--r--module/zfs/vdev.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c
index 1521acc40..9a7f5e011 100644
--- a/module/zfs/vdev.c
+++ b/module/zfs/vdev.c
@@ -3129,11 +3129,11 @@ vdev_destroy_spacemaps(vdev_t *vd, dmu_tx_t *tx)
}
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;
- dmu_tx_t *tx;
+ ASSERT(vd->vdev_islog);
ASSERT(vd == vd->vdev_top);
ASSERT3U(txg, ==, spa_syncing_txg(spa));
@@ -3178,13 +3178,14 @@ vdev_remove_empty(vdev_t *vd, uint64_t txg)
ASSERT0(mg->mg_histogram[i]);
}
- tx = dmu_tx_create_assigned(spa_get_dsl(spa), txg);
- vdev_destroy_spacemaps(vd, tx);
+ dmu_tx_t *tx = dmu_tx_create_assigned(spa_get_dsl(spa), txg);
- 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);
vd->vdev_top_zap = 0;
}
+
dmu_tx_commit(tx);
}
@@ -3255,14 +3256,11 @@ vdev_sync(vdev_t *vd, uint64_t txg)
vdev_dtl_sync(lvd, txg);
/*
- * Remove the metadata associated with this vdev once it's empty.
- * Note that this is typically used for log/cache device removal;
- * we don't empty toplevel vdevs when removing them. But if
- * a toplevel happens to be emptied, this is not harmful.
+ * If this is an empty log device being removed, destroy the
+ * metadata associated with it.
*/
- if (vd->vdev_stat.vs_alloc == 0 && vd->vdev_removing) {
- vdev_remove_empty(vd, txg);
- }
+ if (vd->vdev_islog && vd->vdev_stat.vs_alloc == 0 && vd->vdev_removing)
+ vdev_remove_empty_log(vd, txg);
(void) txg_list_add(&spa->spa_vdev_txg_list, vd, TXG_CLEAN(txg));
}