diff options
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c index 9c26d2c..885c432 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c @@ -2257,6 +2257,11 @@ vdev_remove(vdev_t *vd, uint64_t txg) tx = dmu_tx_create_assigned(spa_get_dsl(spa), txg); if (vd->vdev_ms != NULL) { + metaslab_group_t *mg = vd->vdev_mg; + + metaslab_group_histogram_verify(mg); + metaslab_class_histogram_verify(mg->mg_class); + for (int m = 0; m < vd->vdev_ms_count; m++) { metaslab_t *msp = vd->vdev_ms[m]; @@ -2264,12 +2269,27 @@ vdev_remove(vdev_t *vd, uint64_t txg) continue; mutex_enter(&msp->ms_lock); + /* + * If the metaslab was not loaded when the vdev + * was removed then the histogram accounting may + * not be accurate. Update the histogram information + * here so that we ensure that the metaslab group + * and metaslab class are up-to-date. + */ + metaslab_group_histogram_remove(mg, msp); + VERIFY0(space_map_allocated(msp->ms_sm)); space_map_free(msp->ms_sm, tx); space_map_close(msp->ms_sm); msp->ms_sm = NULL; mutex_exit(&msp->ms_lock); } + + metaslab_group_histogram_verify(mg); + metaslab_class_histogram_verify(mg->mg_class); + for (int i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++) + ASSERT0(mg->mg_histogram[i]); + } if (vd->vdev_ms_array) { @@ -2729,7 +2749,10 @@ vdev_accessible(vdev_t *vd, zio_t *zio) void vdev_get_stats(vdev_t *vd, vdev_stat_t *vs) { - vdev_t *rvd = vd->vdev_spa->spa_root_vdev; + spa_t *spa = vd->vdev_spa; + vdev_t *rvd = spa->spa_root_vdev; + + ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0); mutex_enter(&vd->vdev_stat_lock); bcopy(&vd->vdev_stat, vs, sizeof (*vs)); @@ -2743,7 +2766,8 @@ vdev_get_stats(vdev_t *vd, vdev_stat_t *vs) ? vd->vdev_top->vdev_ashift : vd->vdev_ashift; vs->vs_logical_ashift = vd->vdev_logical_ashift; vs->vs_physical_ashift = vd->vdev_physical_ashift; - mutex_exit(&vd->vdev_stat_lock); + if (vd->vdev_aux == NULL && vd == vd->vdev_top) + vs->vs_fragmentation = vd->vdev_mg->mg_fragmentation; /* * If we're getting stats on the root vdev, aggregate the I/O counts @@ -2754,15 +2778,14 @@ vdev_get_stats(vdev_t *vd, vdev_stat_t *vs) vdev_t *cvd = rvd->vdev_child[c]; vdev_stat_t *cvs = &cvd->vdev_stat; - mutex_enter(&vd->vdev_stat_lock); for (int t = 0; t < ZIO_TYPES; t++) { vs->vs_ops[t] += cvs->vs_ops[t]; vs->vs_bytes[t] += cvs->vs_bytes[t]; } cvs->vs_scan_removing = cvd->vdev_removing; - mutex_exit(&vd->vdev_stat_lock); } } + mutex_exit(&vd->vdev_stat_lock); } void |