]> git.proxmox.com Git - mirror_zfs.git/commitdiff
OpenZFS 9690 - metaslab of vdev with no space maps was flushed during removal
authorSerapheim Dimitropoulos <serapheim@delphix.com>
Tue, 15 May 2018 17:43:25 +0000 (10:43 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 19 Oct 2018 19:05:03 +0000 (12:05 -0700)
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

module/zfs/vdev.c

index 1521acc40552568f4f676a6c92cdc232a735e169..9a7f5e0116fac9a7c249a74a0df97c0be6b0c422 100644 (file)
@@ -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));
 }