diff options
Diffstat (limited to 'cmd/zdb/zdb.c')
-rw-r--r-- | cmd/zdb/zdb.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 7768bb39a..7f5de16aa 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -2643,10 +2643,21 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb) if (!dump_opt['L']) { vdev_t *rvd = spa->spa_root_vdev; + + /* + * We are going to be changing the meaning of the metaslab's + * ms_tree. Ensure that the allocator doesn't try to + * use the tree. + */ + spa->spa_normal_class->mc_ops = &zdb_metaslab_ops; + spa->spa_log_class->mc_ops = &zdb_metaslab_ops; + for (c = 0; c < rvd->vdev_children; c++) { vdev_t *vd = rvd->vdev_child[c]; + metaslab_group_t *mg = vd->vdev_mg; for (m = 0; m < vd->vdev_ms_count; m++) { metaslab_t *msp = vd->vdev_ms[m]; + ASSERT3P(msp->ms_group, ==, mg); mutex_enter(&msp->ms_lock); metaslab_unload(msp); @@ -2667,8 +2678,6 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb) (longlong_t)m, (longlong_t)vd->vdev_ms_count); - msp->ms_ops = &zdb_metaslab_ops; - /* * We don't want to spend the CPU * manipulating the size-ordered @@ -2678,7 +2687,9 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb) msp->ms_tree->rt_ops = NULL; VERIFY0(space_map_load(msp->ms_sm, msp->ms_tree, SM_ALLOC)); - msp->ms_loaded = B_TRUE; + + if (!msp->ms_loaded) + msp->ms_loaded = B_TRUE; } mutex_exit(&msp->ms_lock); } @@ -2702,8 +2713,10 @@ zdb_leak_fini(spa_t *spa) vdev_t *rvd = spa->spa_root_vdev; for (c = 0; c < rvd->vdev_children; c++) { vdev_t *vd = rvd->vdev_child[c]; + metaslab_group_t *mg = vd->vdev_mg; for (m = 0; m < vd->vdev_ms_count; m++) { metaslab_t *msp = vd->vdev_ms[m]; + ASSERT3P(mg, ==, msp->ms_group); mutex_enter(&msp->ms_lock); /* @@ -2717,7 +2730,9 @@ zdb_leak_fini(spa_t *spa) * from the ms_tree. */ range_tree_vacate(msp->ms_tree, zdb_leak, vd); - msp->ms_loaded = B_FALSE; + + if (msp->ms_loaded) + msp->ms_loaded = B_FALSE; mutex_exit(&msp->ms_lock); } |