summaryrefslogtreecommitdiffstats
path: root/module/zfs/vdev.c
diff options
context:
space:
mode:
authorGeorge Wilson <[email protected]>2014-07-19 12:19:24 -0800
committerBrian Behlendorf <[email protected]>2014-08-18 08:40:49 -0700
commitf3a7f6610f2df0217ba3b99099019417a954b673 (patch)
tree720f77d117032a585761dd5bb80e5a5694915111 /module/zfs/vdev.c
parentf67d709080f3d4a247191f0d25cbedc5da103f78 (diff)
Illumos 4976-4984 - metaslab improvements
4976 zfs should only avoid writing to a failing non-redundant top-level vdev 4978 ztest fails in get_metaslab_refcount() 4979 extend free space histogram to device and pool 4980 metaslabs should have a fragmentation metric 4981 remove fragmented ops vector from block allocator 4982 space_map object should proactively upgrade when feature is enabled 4983 need to collect metaslab information via mdb 4984 device selection should use fragmentation metric Reviewed by: Matthew Ahrens <[email protected]> Reviewed by: Adam Leventhal <[email protected]> Reviewed by: Christopher Siden <[email protected]> Approved by: Garrett D'Amore <[email protected]> References: https://www.illumos.org/issues/4976 https://www.illumos.org/issues/4978 https://www.illumos.org/issues/4979 https://www.illumos.org/issues/4980 https://www.illumos.org/issues/4981 https://www.illumos.org/issues/4982 https://www.illumos.org/issues/4983 https://www.illumos.org/issues/4984 https://github.com/illumos/illumos-gate/commit/2e4c998 Notes: The "zdb -M" option has been re-tasked to display the new metaslab fragmentation metric and the new "zdb -I" option is used to control the maximum number of in-flight I/Os. The new fragmentation metric is derived from the space map histogram which has been rolled up to the vdev and pool level and is presented to the user via "zpool list". Add a number of module parameters related to the new metaslab weighting logic. Ported by: Tim Chase <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #2595
Diffstat (limited to 'module/zfs/vdev.c')
-rw-r--r--module/zfs/vdev.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c
index 89df3674e..0303edada 100644
--- a/module/zfs/vdev.c
+++ b/module/zfs/vdev.c
@@ -2151,11 +2151,16 @@ vdev_remove(vdev_t *vd, uint64_t txg)
spa_t *spa = vd->vdev_spa;
objset_t *mos = spa->spa_meta_objset;
dmu_tx_t *tx;
- int m;
+ int m, i;
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 (m = 0; m < vd->vdev_ms_count; m++) {
metaslab_t *msp = vd->vdev_ms[m];
@@ -2163,12 +2168,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 (i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++)
+ ASSERT0(mg->mg_histogram[i]);
+
}
if (vd->vdev_ms_array) {
@@ -2621,9 +2641,12 @@ 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;
int c, t;
+ ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0);
+
mutex_enter(&vd->vdev_stat_lock);
bcopy(&vd->vdev_stat, vs, sizeof (*vs));
vs->vs_timestamp = gethrtime() - vs->vs_timestamp;
@@ -2632,7 +2655,8 @@ vdev_get_stats(vdev_t *vd, vdev_stat_t *vs)
if (vd->vdev_ops->vdev_op_leaf)
vs->vs_rsize += VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
vs->vs_esize = vd->vdev_max_asize - vd->vdev_asize;
- 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
@@ -2643,15 +2667,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 (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