546 int refcount = 0;
547
548 if (vd->vdev_top == vd) {
549 for (int m = 0; m < vd->vdev_ms_count; m++) {
550 space_map_t *sm = vd->vdev_ms[m]->ms_sm;
551
552 if (sm != NULL &&
553 sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
554 refcount++;
555 }
556 }
557 for (int c = 0; c < vd->vdev_children; c++)
558 refcount += get_metaslab_refcount(vd->vdev_child[c]);
559
560 return (refcount);
561 }
562
563 static int
564 verify_spacemap_refcounts(spa_t *spa)
565 {
566 int expected_refcount, actual_refcount;
567
568 expected_refcount = spa_feature_get_refcount(spa,
569 &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM]);
570 actual_refcount = get_dtl_refcount(spa->spa_root_vdev);
571 actual_refcount += get_metaslab_refcount(spa->spa_root_vdev);
572
573 if (expected_refcount != actual_refcount) {
574 (void) printf("space map refcount mismatch: expected %d != "
575 "actual %d\n", expected_refcount, actual_refcount);
576 return (2);
577 }
578 return (0);
579 }
580
581 static void
582 dump_spacemap(objset_t *os, space_map_t *sm)
583 {
584 uint64_t alloc, offset, entry;
585 char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
586 "INVALID", "INVALID", "INVALID", "INVALID" };
587
588 if (sm == NULL)
589 return;
590
591 /*
592 * Print out the freelist entries in both encoded and decoded form.
593 */
594 alloc = 0;
595 for (offset = 0; offset < space_map_length(sm);
657 zdb_nicenum(msp->ms_size - space_map_allocated(sm), freebuf);
658
659 (void) printf(
660 "\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n",
661 (u_longlong_t)msp->ms_id, (u_longlong_t)msp->ms_start,
662 (u_longlong_t)space_map_object(sm), freebuf);
663
664 if (dump_opt['m'] > 2 && !dump_opt['L']) {
665 mutex_enter(&msp->ms_lock);
666 metaslab_load_wait(msp);
667 if (!msp->ms_loaded) {
668 VERIFY0(metaslab_load(msp));
669 range_tree_stat_verify(msp->ms_tree);
670 }
671 dump_metaslab_stats(msp);
672 metaslab_unload(msp);
673 mutex_exit(&msp->ms_lock);
674 }
675
676 if (dump_opt['m'] > 1 && sm != NULL &&
677 spa_feature_is_active(spa,
678 &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM])) {
679 /*
680 * The space map histogram represents free space in chunks
681 * of sm_shift (i.e. bucket 0 refers to 2^sm_shift).
682 */
683 (void) printf("\tOn-disk histogram:\n");
684 dump_histogram(sm->sm_phys->smp_histogram,
685 SPACE_MAP_HISTOGRAM_SIZE(sm), sm->sm_shift);
686 }
687
688 if (dump_opt['d'] > 5 || dump_opt['m'] > 3) {
689 ASSERT(msp->ms_size == (1ULL << vd->vdev_ms_shift));
690
691 mutex_enter(&msp->ms_lock);
692 dump_spacemap(spa->spa_meta_objset, msp->ms_sm);
693 mutex_exit(&msp->ms_lock);
694 }
695 }
696
697 static void
698 print_vdev_metaslab_header(vdev_t *vd)
2449
2450 /*
2451 * Load all space maps as SM_ALLOC maps, then traverse the pool
2452 * claiming each block we discover. If the pool is perfectly
2453 * consistent, the space maps will be empty when we're done.
2454 * Anything left over is a leak; any block we can't claim (because
2455 * it's not part of any space map) is a double allocation,
2456 * reference to a freed block, or an unclaimed log block.
2457 */
2458 zdb_leak_init(spa, &zcb);
2459
2460 /*
2461 * If there's a deferred-free bplist, process that first.
2462 */
2463 (void) bpobj_iterate_nofree(&spa->spa_deferred_bpobj,
2464 count_block_cb, &zcb, NULL);
2465 if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
2466 (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj,
2467 count_block_cb, &zcb, NULL);
2468 }
2469 if (spa_feature_is_active(spa,
2470 &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
2471 VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset,
2472 spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb,
2473 &zcb, NULL));
2474 }
2475
2476 if (dump_opt['c'] > 1)
2477 flags |= TRAVERSE_PREFETCH_DATA;
2478
2479 zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa));
2480 zcb.zcb_start = zcb.zcb_lastprint = gethrtime();
2481 zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
2482
2483 /*
2484 * If we've traversed the data blocks then we need to wait for those
2485 * I/Os to complete. We leverage "The Godfather" zio to wait on
2486 * all async I/Os to complete.
2487 */
2488 if (dump_opt['c']) {
2489 (void) zio_wait(spa->spa_async_zio_root);
2490 spa->spa_async_zio_root = zio_root(spa, NULL, NULL,
2776 if (dump_opt['u'])
2777 dump_uberblock(&spa->spa_uberblock, "\nUberblock:\n", "\n");
2778
2779 if (dump_opt['D'])
2780 dump_all_ddts(spa);
2781
2782 if (dump_opt['d'] > 2 || dump_opt['m'])
2783 dump_metaslabs(spa);
2784
2785 if (dump_opt['d'] || dump_opt['i']) {
2786 dump_dir(dp->dp_meta_objset);
2787 if (dump_opt['d'] >= 3) {
2788 dump_bpobj(&spa->spa_deferred_bpobj,
2789 "Deferred frees", 0);
2790 if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
2791 dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
2792 "Pool snapshot frees", 0);
2793 }
2794
2795 if (spa_feature_is_active(spa,
2796 &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
2797 dump_bptree(spa->spa_meta_objset,
2798 spa->spa_dsl_pool->dp_bptree_obj,
2799 "Pool dataset frees");
2800 }
2801 dump_dtl(spa->spa_root_vdev, 0);
2802 }
2803 (void) dmu_objset_find(spa_name(spa), dump_one_dir,
2804 NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
2805 }
2806 if (dump_opt['b'] || dump_opt['c'])
2807 rc = dump_block_stats(spa);
2808
2809 if (rc == 0)
2810 rc = verify_spacemap_refcounts(spa);
2811
2812 if (dump_opt['s'])
2813 show_pool_stats(spa);
2814
2815 if (dump_opt['h'])
2816 dump_history(spa);
|
546 int refcount = 0;
547
548 if (vd->vdev_top == vd) {
549 for (int m = 0; m < vd->vdev_ms_count; m++) {
550 space_map_t *sm = vd->vdev_ms[m]->ms_sm;
551
552 if (sm != NULL &&
553 sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
554 refcount++;
555 }
556 }
557 for (int c = 0; c < vd->vdev_children; c++)
558 refcount += get_metaslab_refcount(vd->vdev_child[c]);
559
560 return (refcount);
561 }
562
563 static int
564 verify_spacemap_refcounts(spa_t *spa)
565 {
566 uint64_t expected_refcount = 0;
567 uint64_t actual_refcount;
568
569 (void) feature_get_refcount(spa,
570 &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM],
571 &expected_refcount);
572 actual_refcount = get_dtl_refcount(spa->spa_root_vdev);
573 actual_refcount += get_metaslab_refcount(spa->spa_root_vdev);
574
575 if (expected_refcount != actual_refcount) {
576 (void) printf("space map refcount mismatch: expected %lld != "
577 "actual %lld\n",
578 (longlong_t)expected_refcount,
579 (longlong_t)actual_refcount);
580 return (2);
581 }
582 return (0);
583 }
584
585 static void
586 dump_spacemap(objset_t *os, space_map_t *sm)
587 {
588 uint64_t alloc, offset, entry;
589 char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
590 "INVALID", "INVALID", "INVALID", "INVALID" };
591
592 if (sm == NULL)
593 return;
594
595 /*
596 * Print out the freelist entries in both encoded and decoded form.
597 */
598 alloc = 0;
599 for (offset = 0; offset < space_map_length(sm);
661 zdb_nicenum(msp->ms_size - space_map_allocated(sm), freebuf);
662
663 (void) printf(
664 "\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n",
665 (u_longlong_t)msp->ms_id, (u_longlong_t)msp->ms_start,
666 (u_longlong_t)space_map_object(sm), freebuf);
667
668 if (dump_opt['m'] > 2 && !dump_opt['L']) {
669 mutex_enter(&msp->ms_lock);
670 metaslab_load_wait(msp);
671 if (!msp->ms_loaded) {
672 VERIFY0(metaslab_load(msp));
673 range_tree_stat_verify(msp->ms_tree);
674 }
675 dump_metaslab_stats(msp);
676 metaslab_unload(msp);
677 mutex_exit(&msp->ms_lock);
678 }
679
680 if (dump_opt['m'] > 1 && sm != NULL &&
681 spa_feature_is_active(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM)) {
682 /*
683 * The space map histogram represents free space in chunks
684 * of sm_shift (i.e. bucket 0 refers to 2^sm_shift).
685 */
686 (void) printf("\tOn-disk histogram:\n");
687 dump_histogram(sm->sm_phys->smp_histogram,
688 SPACE_MAP_HISTOGRAM_SIZE(sm), sm->sm_shift);
689 }
690
691 if (dump_opt['d'] > 5 || dump_opt['m'] > 3) {
692 ASSERT(msp->ms_size == (1ULL << vd->vdev_ms_shift));
693
694 mutex_enter(&msp->ms_lock);
695 dump_spacemap(spa->spa_meta_objset, msp->ms_sm);
696 mutex_exit(&msp->ms_lock);
697 }
698 }
699
700 static void
701 print_vdev_metaslab_header(vdev_t *vd)
2452
2453 /*
2454 * Load all space maps as SM_ALLOC maps, then traverse the pool
2455 * claiming each block we discover. If the pool is perfectly
2456 * consistent, the space maps will be empty when we're done.
2457 * Anything left over is a leak; any block we can't claim (because
2458 * it's not part of any space map) is a double allocation,
2459 * reference to a freed block, or an unclaimed log block.
2460 */
2461 zdb_leak_init(spa, &zcb);
2462
2463 /*
2464 * If there's a deferred-free bplist, process that first.
2465 */
2466 (void) bpobj_iterate_nofree(&spa->spa_deferred_bpobj,
2467 count_block_cb, &zcb, NULL);
2468 if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
2469 (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj,
2470 count_block_cb, &zcb, NULL);
2471 }
2472 if (spa_feature_is_active(spa, SPA_FEATURE_ASYNC_DESTROY)) {
2473 VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset,
2474 spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb,
2475 &zcb, NULL));
2476 }
2477
2478 if (dump_opt['c'] > 1)
2479 flags |= TRAVERSE_PREFETCH_DATA;
2480
2481 zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa));
2482 zcb.zcb_start = zcb.zcb_lastprint = gethrtime();
2483 zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
2484
2485 /*
2486 * If we've traversed the data blocks then we need to wait for those
2487 * I/Os to complete. We leverage "The Godfather" zio to wait on
2488 * all async I/Os to complete.
2489 */
2490 if (dump_opt['c']) {
2491 (void) zio_wait(spa->spa_async_zio_root);
2492 spa->spa_async_zio_root = zio_root(spa, NULL, NULL,
2778 if (dump_opt['u'])
2779 dump_uberblock(&spa->spa_uberblock, "\nUberblock:\n", "\n");
2780
2781 if (dump_opt['D'])
2782 dump_all_ddts(spa);
2783
2784 if (dump_opt['d'] > 2 || dump_opt['m'])
2785 dump_metaslabs(spa);
2786
2787 if (dump_opt['d'] || dump_opt['i']) {
2788 dump_dir(dp->dp_meta_objset);
2789 if (dump_opt['d'] >= 3) {
2790 dump_bpobj(&spa->spa_deferred_bpobj,
2791 "Deferred frees", 0);
2792 if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
2793 dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
2794 "Pool snapshot frees", 0);
2795 }
2796
2797 if (spa_feature_is_active(spa,
2798 SPA_FEATURE_ASYNC_DESTROY)) {
2799 dump_bptree(spa->spa_meta_objset,
2800 spa->spa_dsl_pool->dp_bptree_obj,
2801 "Pool dataset frees");
2802 }
2803 dump_dtl(spa->spa_root_vdev, 0);
2804 }
2805 (void) dmu_objset_find(spa_name(spa), dump_one_dir,
2806 NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
2807 }
2808 if (dump_opt['b'] || dump_opt['c'])
2809 rc = dump_block_stats(spa);
2810
2811 if (rc == 0)
2812 rc = verify_spacemap_refcounts(spa);
2813
2814 if (dump_opt['s'])
2815 show_pool_stats(spa);
2816
2817 if (dump_opt['h'])
2818 dump_history(spa);
|