summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
diff options
context:
space:
mode:
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.c31
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
OpenPOWER on IntegriCloud