summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/metaslab.c
diff options
context:
space:
mode:
authorGeorge Wilson <George.Wilson@Sun.COM>2009-09-21 10:38:24 -0700
committerGeorge Wilson <George.Wilson@Sun.COM>2009-09-21 10:38:24 -0700
commit88ecc943b4eb72f7c4fbbd8435997b85ef171fc3 (patch)
treeebceb7c59c849c35d63917995146dc8ad430fa31 /usr/src/uts/common/fs/zfs/metaslab.c
parent53520bfd0d8e6401efee237b91e682ab66f77eef (diff)
downloadillumos-joyent-88ecc943b4eb72f7c4fbbd8435997b85ef171fc3.tar.gz
6574286 removing a slog doesn't work
6856566 zpool import -F can cause panic 6863456 system panic by load_nvlist(spa, spa->spa_config_object, &nv) == 0 while running zfs test suite 6882947 dump_nvlist() should live in libnvpair
Diffstat (limited to 'usr/src/uts/common/fs/zfs/metaslab.c')
-rw-r--r--usr/src/uts/common/fs/zfs/metaslab.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/usr/src/uts/common/fs/zfs/metaslab.c b/usr/src/uts/common/fs/zfs/metaslab.c
index 77556ac5d7..3ebde10240 100644
--- a/usr/src/uts/common/fs/zfs/metaslab.c
+++ b/usr/src/uts/common/fs/zfs/metaslab.c
@@ -57,12 +57,13 @@ int metaslab_df_free_pct = 30;
* ==========================================================================
*/
metaslab_class_t *
-metaslab_class_create(space_map_ops_t *ops)
+metaslab_class_create(spa_t *spa, space_map_ops_t *ops)
{
metaslab_class_t *mc;
mc = kmem_zalloc(sizeof (metaslab_class_t), KM_SLEEP);
+ mc->mc_spa = spa;
mc->mc_rotor = NULL;
mc->mc_ops = ops;
@@ -126,6 +127,32 @@ metaslab_class_remove(metaslab_class_t *mc, metaslab_group_t *mg)
mg->mg_class = NULL;
}
+int
+metaslab_class_validate(metaslab_class_t *mc)
+{
+ metaslab_group_t *mg;
+ vdev_t *vd;
+
+ /*
+ * Must hold one of the spa_config locks.
+ */
+ ASSERT(spa_config_held(mc->mc_spa, SCL_ALL, RW_READER) ||
+ spa_config_held(mc->mc_spa, SCL_ALL, RW_WRITER));
+
+ if ((mg = mc->mc_rotor) == NULL)
+ return (0);
+
+ do {
+ vd = mg->mg_vd;
+ ASSERT(vd->vdev_mg != NULL);
+ ASSERT3P(vd->vdev_top, ==, vd);
+ ASSERT3P(mg->mg_class, ==, mc);
+ ASSERT3P(vd->vdev_ops, !=, &vdev_hole_ops);
+ } while ((mg = mg->mg_next) != mc->mc_rotor);
+
+ return (0);
+}
+
/*
* ==========================================================================
* Metaslab groups
@@ -634,6 +661,8 @@ metaslab_sync(metaslab_t *msp, uint64_t txg)
dmu_tx_t *tx;
int t;
+ ASSERT(!vd->vdev_ishole);
+
tx = dmu_tx_create_assigned(spa_get_dsl(spa), txg);
/*
@@ -721,6 +750,8 @@ metaslab_sync_done(metaslab_t *msp, uint64_t txg)
vdev_t *vd = mg->mg_vd;
int t;
+ ASSERT(!vd->vdev_ishole);
+
mutex_enter(&msp->ms_lock);
/*
@@ -932,10 +963,21 @@ metaslab_alloc_dva(spa_t *spa, metaslab_class_t *mc, uint64_t psize,
*/
if (hintdva) {
vd = vdev_lookup_top(spa, DVA_GET_VDEV(&hintdva[d]));
- if (flags & METASLAB_HINTBP_AVOID)
- mg = vd->vdev_mg->mg_next;
- else
+
+ /*
+ * It's possible the vdev we're using as the hint no
+ * longer exists (i.e. removed). Consult the rotor when
+ * all else fails.
+ */
+ if (vd != NULL && vd->vdev_mg != NULL) {
mg = vd->vdev_mg;
+
+ if (flags & METASLAB_HINTBP_AVOID &&
+ mg->mg_next != NULL)
+ mg = mg->mg_next;
+ } else {
+ mg = mc->mc_rotor;
+ }
} else if (d != 0) {
vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[d - 1]));
mg = vd->vdev_mg->mg_next;