diff options
| author | George Wilson <George.Wilson@Sun.COM> | 2009-09-21 10:38:24 -0700 |
|---|---|---|
| committer | George Wilson <George.Wilson@Sun.COM> | 2009-09-21 10:38:24 -0700 |
| commit | 88ecc943b4eb72f7c4fbbd8435997b85ef171fc3 (patch) | |
| tree | ebceb7c59c849c35d63917995146dc8ad430fa31 /usr/src/uts/common/fs/zfs/metaslab.c | |
| parent | 53520bfd0d8e6401efee237b91e682ab66f77eef (diff) | |
| download | illumos-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.c | 50 |
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; |
