Print this page
4101 metaslab_debug should allow for fine-grained control
4102 space_maps should store more information about themselves
4103 space map object blocksize should be increased
4104 ::spa_space no longer works
4105 removing a mirrored log device results in a leaked object
4106 asynchronously load metaslab
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Sebastien Roy <seb@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/zdb/zdb.c
          +++ new/usr/src/cmd/zdb/zdb.c
↓ open down ↓ 238 lines elided ↑ open up ↑
 239  239          if (dump_opt['P'])
 240  240                  (void) sprintf(buf, "%llu", (longlong_t)num);
 241  241          else
 242  242                  nicenum(num, buf);
 243  243  }
 244  244  
 245  245  const char histo_stars[] = "****************************************";
 246  246  const int histo_width = sizeof (histo_stars) - 1;
 247  247  
 248  248  static void
 249      -dump_histogram(const uint64_t *histo, int size)
      249 +dump_histogram(const uint64_t *histo, int size, int offset)
 250  250  {
 251  251          int i;
 252  252          int minidx = size - 1;
 253  253          int maxidx = 0;
 254  254          uint64_t max = 0;
 255  255  
 256  256          for (i = 0; i < size; i++) {
 257  257                  if (histo[i] > max)
 258  258                          max = histo[i];
 259  259                  if (histo[i] > 0 && i > maxidx)
 260  260                          maxidx = i;
 261  261                  if (histo[i] > 0 && i < minidx)
 262  262                          minidx = i;
 263  263          }
 264  264  
 265  265          if (max < histo_width)
 266  266                  max = histo_width;
 267  267  
 268  268          for (i = minidx; i <= maxidx; i++) {
 269  269                  (void) printf("\t\t\t%3u: %6llu %s\n",
 270      -                    i, (u_longlong_t)histo[i],
      270 +                    i + offset, (u_longlong_t)histo[i],
 271  271                      &histo_stars[(max - histo[i]) * histo_width / max]);
 272  272          }
 273  273  }
 274  274  
 275  275  static void
 276  276  dump_zap_stats(objset_t *os, uint64_t object)
 277  277  {
 278  278          int error;
 279  279          zap_stats_t zs;
 280  280  
↓ open down ↓ 32 lines elided ↑ open up ↑
 313  313          (void) printf("\t\tTotal blocks: %llu\n",
 314  314              (u_longlong_t)zs.zs_num_blocks);
 315  315          (void) printf("\t\tzap_block_type: 0x%llx\n",
 316  316              (u_longlong_t)zs.zs_block_type);
 317  317          (void) printf("\t\tzap_magic: 0x%llx\n",
 318  318              (u_longlong_t)zs.zs_magic);
 319  319          (void) printf("\t\tzap_salt: 0x%llx\n",
 320  320              (u_longlong_t)zs.zs_salt);
 321  321  
 322  322          (void) printf("\t\tLeafs with 2^n pointers:\n");
 323      -        dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE);
      323 +        dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE, 0);
 324  324  
 325  325          (void) printf("\t\tBlocks with n*5 entries:\n");
 326      -        dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE);
      326 +        dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE, 0);
 327  327  
 328  328          (void) printf("\t\tBlocks n/10 full:\n");
 329      -        dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE);
      329 +        dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE, 0);
 330  330  
 331  331          (void) printf("\t\tEntries with n chunks:\n");
 332      -        dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE);
      332 +        dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE, 0);
 333  333  
 334  334          (void) printf("\t\tBuckets with n entries:\n");
 335      -        dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE);
      335 +        dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE, 0);
 336  336  }
 337  337  
 338  338  /*ARGSUSED*/
 339  339  static void
 340  340  dump_none(objset_t *os, uint64_t object, void *data, size_t size)
 341  341  {
 342  342  }
 343  343  
 344  344  /*ARGSUSED*/
 345  345  static void
↓ open down ↓ 168 lines elided ↑ open up ↑
 514  514          for (zap_cursor_init(&zc, os, object);
 515  515              zap_cursor_retrieve(&zc, &attr) == 0;
 516  516              zap_cursor_advance(&zc)) {
 517  517                  (void) printf("\t\t%s = %lld (type: %s)\n",
 518  518                      attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
 519  519                      typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
 520  520          }
 521  521          zap_cursor_fini(&zc);
 522  522  }
 523  523  
      524 +int
      525 +get_dtl_refcount(vdev_t *vd)
      526 +{
      527 +        int refcount = 0;
      528 +
      529 +        if (vd->vdev_ops->vdev_op_leaf) {
      530 +                space_map_t *sm = vd->vdev_dtl_sm;
      531 +
      532 +                if (sm != NULL &&
      533 +                    sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
      534 +                        return (1);
      535 +                return (0);
      536 +        }
      537 +
      538 +        for (int c = 0; c < vd->vdev_children; c++)
      539 +                refcount += get_dtl_refcount(vd->vdev_child[c]);
      540 +        return (refcount);
      541 +}
      542 +
      543 +int
      544 +get_metaslab_refcount(vdev_t *vd)
      545 +{
      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 +
 524  581  static void
 525      -dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
      582 +dump_spacemap(objset_t *os, space_map_t *sm)
 526  583  {
 527  584          uint64_t alloc, offset, entry;
 528      -        uint8_t mapshift = sm->sm_shift;
 529      -        uint64_t mapstart = sm->sm_start;
 530  585          char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
 531  586                              "INVALID", "INVALID", "INVALID", "INVALID" };
 532  587  
 533      -        if (smo->smo_object == 0)
      588 +        if (sm == NULL)
 534  589                  return;
 535  590  
 536  591          /*
 537  592           * Print out the freelist entries in both encoded and decoded form.
 538  593           */
 539  594          alloc = 0;
 540      -        for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
 541      -                VERIFY3U(0, ==, dmu_read(os, smo->smo_object, offset,
      595 +        for (offset = 0; offset < space_map_length(sm);
      596 +            offset += sizeof (entry)) {
      597 +                uint8_t mapshift = sm->sm_shift;
      598 +
      599 +                VERIFY0(dmu_read(os, space_map_object(sm), offset,
 542  600                      sizeof (entry), &entry, DMU_READ_PREFETCH));
 543  601                  if (SM_DEBUG_DECODE(entry)) {
      602 +
 544  603                          (void) printf("\t    [%6llu] %s: txg %llu, pass %llu\n",
 545  604                              (u_longlong_t)(offset / sizeof (entry)),
 546  605                              ddata[SM_DEBUG_ACTION_DECODE(entry)],
 547  606                              (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
 548  607                              (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
 549  608                  } else {
 550  609                          (void) printf("\t    [%6llu]    %c  range:"
 551  610                              " %010llx-%010llx  size: %06llx\n",
 552  611                              (u_longlong_t)(offset / sizeof (entry)),
 553  612                              SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
 554  613                              (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
 555      -                            mapshift) + mapstart),
      614 +                            mapshift) + sm->sm_start),
 556  615                              (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
 557      -                            mapshift) + mapstart + (SM_RUN_DECODE(entry) <<
 558      -                            mapshift)),
      616 +                            mapshift) + sm->sm_start +
      617 +                            (SM_RUN_DECODE(entry) << mapshift)),
 559  618                              (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
 560  619                          if (SM_TYPE_DECODE(entry) == SM_ALLOC)
 561  620                                  alloc += SM_RUN_DECODE(entry) << mapshift;
 562  621                          else
 563  622                                  alloc -= SM_RUN_DECODE(entry) << mapshift;
 564  623                  }
 565  624          }
 566      -        if (alloc != smo->smo_alloc) {
      625 +        if (alloc != space_map_allocated(sm)) {
 567  626                  (void) printf("space_map_object alloc (%llu) INCONSISTENT "
 568  627                      "with space map summary (%llu)\n",
 569      -                    (u_longlong_t)smo->smo_alloc, (u_longlong_t)alloc);
      628 +                    (u_longlong_t)space_map_allocated(sm), (u_longlong_t)alloc);
 570  629          }
 571  630  }
 572  631  
 573  632  static void
 574  633  dump_metaslab_stats(metaslab_t *msp)
 575  634  {
 576  635          char maxbuf[32];
 577      -        space_map_t *sm = msp->ms_map;
 578      -        avl_tree_t *t = sm->sm_pp_root;
 579      -        int free_pct = sm->sm_space * 100 / sm->sm_size;
      636 +        range_tree_t *rt = msp->ms_tree;
      637 +        avl_tree_t *t = &msp->ms_size_tree;
      638 +        int free_pct = range_tree_space(rt) * 100 / msp->ms_size;
 580  639  
 581      -        zdb_nicenum(space_map_maxsize(sm), maxbuf);
      640 +        zdb_nicenum(metaslab_block_maxsize(msp), maxbuf);
 582  641  
 583  642          (void) printf("\t %25s %10lu   %7s  %6s   %4s %4d%%\n",
 584  643              "segments", avl_numnodes(t), "maxsize", maxbuf,
 585  644              "freepct", free_pct);
      645 +        (void) printf("\tIn-memory histogram:\n");
      646 +        dump_histogram(rt->rt_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
 586  647  }
 587  648  
 588  649  static void
 589  650  dump_metaslab(metaslab_t *msp)
 590  651  {
 591  652          vdev_t *vd = msp->ms_group->mg_vd;
 592  653          spa_t *spa = vd->vdev_spa;
 593      -        space_map_t *sm = msp->ms_map;
 594      -        space_map_obj_t *smo = &msp->ms_smo;
      654 +        space_map_t *sm = msp->ms_sm;
 595  655          char freebuf[32];
 596  656  
 597      -        zdb_nicenum(sm->sm_size - smo->smo_alloc, freebuf);
      657 +        zdb_nicenum(msp->ms_size - space_map_allocated(sm), freebuf);
 598  658  
 599  659          (void) printf(
 600  660              "\tmetaslab %6llu   offset %12llx   spacemap %6llu   free    %5s\n",
 601      -            (u_longlong_t)(sm->sm_start / sm->sm_size),
 602      -            (u_longlong_t)sm->sm_start, (u_longlong_t)smo->smo_object, freebuf);
      661 +            (u_longlong_t)msp->ms_id, (u_longlong_t)msp->ms_start,
      662 +            (u_longlong_t)space_map_object(sm), freebuf);
 603  663  
 604      -        if (dump_opt['m'] > 1 && !dump_opt['L']) {
      664 +        if (dump_opt['m'] > 2 && !dump_opt['L']) {
 605  665                  mutex_enter(&msp->ms_lock);
 606      -                space_map_load_wait(sm);
 607      -                if (!sm->sm_loaded)
 608      -                        VERIFY(space_map_load(sm, zfs_metaslab_ops,
 609      -                            SM_FREE, smo, spa->spa_meta_objset) == 0);
      666 +                metaslab_load_wait(msp);
      667 +                if (!msp->ms_loaded) {
      668 +                        VERIFY0(metaslab_load(msp));
      669 +                        range_tree_stat_verify(msp->ms_tree);
      670 +                }
 610  671                  dump_metaslab_stats(msp);
 611      -                space_map_unload(sm);
      672 +                metaslab_unload(msp);
 612  673                  mutex_exit(&msp->ms_lock);
 613  674          }
 614  675  
 615      -        if (dump_opt['d'] > 5 || dump_opt['m'] > 2) {
 616      -                ASSERT(sm->sm_size == (1ULL << vd->vdev_ms_shift));
      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 +        }
 617  687  
      688 +        if (dump_opt['d'] > 5 || dump_opt['m'] > 3) {
      689 +                ASSERT(msp->ms_size == (1ULL << vd->vdev_ms_shift));
      690 +
 618  691                  mutex_enter(&msp->ms_lock);
 619      -                dump_spacemap(spa->spa_meta_objset, smo, sm);
      692 +                dump_spacemap(spa->spa_meta_objset, msp->ms_sm);
 620  693                  mutex_exit(&msp->ms_lock);
 621  694          }
 622  695  }
 623  696  
 624  697  static void
 625  698  print_vdev_metaslab_header(vdev_t *vd)
 626  699  {
 627  700          (void) printf("\tvdev %10llu\n\t%-10s%5llu   %-19s   %-15s   %-10s\n",
 628  701              (u_longlong_t)vd->vdev_id,
 629  702              "metaslabs", (u_longlong_t)vd->vdev_ms_count,
↓ open down ↓ 166 lines elided ↑ open up ↑
 796  869          if (dump_opt['D'] > 1) {
 797  870                  (void) printf("DDT histogram (aggregated over all DDTs):\n");
 798  871                  ddt_get_dedup_histogram(spa, &ddh_total);
 799  872                  zpool_dump_ddt(&dds_total, &ddh_total);
 800  873          }
 801  874  
 802  875          dump_dedup_ratio(&dds_total);
 803  876  }
 804  877  
 805  878  static void
 806      -dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size)
      879 +dump_dtl_seg(void *arg, uint64_t start, uint64_t size)
 807  880  {
 808      -        char *prefix = (void *)sm;
      881 +        char *prefix = arg;
 809  882  
 810  883          (void) printf("%s [%llu,%llu) length %llu\n",
 811  884              prefix,
 812  885              (u_longlong_t)start,
 813  886              (u_longlong_t)(start + size),
 814  887              (u_longlong_t)(size));
 815  888  }
 816  889  
 817  890  static void
 818  891  dump_dtl(vdev_t *vd, int indent)
↓ open down ↓ 9 lines elided ↑ open up ↑
 828  901  
 829  902          if (indent == 0)
 830  903                  (void) printf("\nDirty time logs:\n\n");
 831  904  
 832  905          (void) printf("\t%*s%s [%s]\n", indent, "",
 833  906              vd->vdev_path ? vd->vdev_path :
 834  907              vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
 835  908              required ? "DTL-required" : "DTL-expendable");
 836  909  
 837  910          for (int t = 0; t < DTL_TYPES; t++) {
 838      -                space_map_t *sm = &vd->vdev_dtl[t];
 839      -                if (sm->sm_space == 0)
      911 +                range_tree_t *rt = vd->vdev_dtl[t];
      912 +                if (range_tree_space(rt) == 0)
 840  913                          continue;
 841  914                  (void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
 842  915                      indent + 2, "", name[t]);
 843      -                mutex_enter(sm->sm_lock);
 844      -                space_map_walk(sm, dump_dtl_seg, (void *)prefix);
 845      -                mutex_exit(sm->sm_lock);
      916 +                mutex_enter(rt->rt_lock);
      917 +                range_tree_walk(rt, dump_dtl_seg, prefix);
      918 +                mutex_exit(rt->rt_lock);
 846  919                  if (dump_opt['d'] > 5 && vd->vdev_children == 0)
 847      -                        dump_spacemap(spa->spa_meta_objset,
 848      -                            &vd->vdev_dtl_smo, sm);
      920 +                        dump_spacemap(spa->spa_meta_objset, vd->vdev_dtl_sm);
 849  921          }
 850  922  
 851  923          for (int c = 0; c < vd->vdev_children; c++)
 852  924                  dump_dtl(vd->vdev_child[c], indent + 4);
 853  925  }
 854  926  
 855  927  static void
 856  928  dump_history(spa_t *spa)
 857  929  {
 858  930          nvlist_t **events = NULL;
↓ open down ↓ 1355 lines elided ↑ open up ↑
2214 2286                      sec_remaining / 60 % 60,
2215 2287                      sec_remaining % 60);
2216 2288  
2217 2289                  zcb->zcb_lastprint = now;
2218 2290          }
2219 2291  
2220 2292          return (0);
2221 2293  }
2222 2294  
2223 2295  static void
2224      -zdb_leak(space_map_t *sm, uint64_t start, uint64_t size)
     2296 +zdb_leak(void *arg, uint64_t start, uint64_t size)
2225 2297  {
2226      -        vdev_t *vd = sm->sm_ppd;
     2298 +        vdev_t *vd = arg;
2227 2299  
2228 2300          (void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
2229 2301              (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
2230 2302  }
2231 2303  
2232      -/* ARGSUSED */
2233      -static void
2234      -zdb_space_map_load(space_map_t *sm)
2235      -{
2236      -}
2237      -
2238      -static void
2239      -zdb_space_map_unload(space_map_t *sm)
2240      -{
2241      -        space_map_vacate(sm, zdb_leak, sm);
2242      -}
2243      -
2244      -/* ARGSUSED */
2245      -static void
2246      -zdb_space_map_claim(space_map_t *sm, uint64_t start, uint64_t size)
2247      -{
2248      -}
2249      -
2250      -static space_map_ops_t zdb_space_map_ops = {
2251      -        zdb_space_map_load,
2252      -        zdb_space_map_unload,
     2304 +static metaslab_ops_t zdb_metaslab_ops = {
2253 2305          NULL,   /* alloc */
2254      -        zdb_space_map_claim,
2255      -        NULL,   /* free */
2256      -        NULL    /* maxsize */
     2306 +        NULL    /* fragmented */
2257 2307  };
2258 2308  
2259 2309  static void
2260 2310  zdb_ddt_leak_init(spa_t *spa, zdb_cb_t *zcb)
2261 2311  {
2262 2312          ddt_bookmark_t ddb = { 0 };
2263 2313          ddt_entry_t dde;
2264 2314          int error;
2265 2315  
2266 2316          while ((error = ddt_walk(spa, &ddb, &dde)) == 0) {
↓ open down ↓ 34 lines elided ↑ open up ↑
2301 2351  {
2302 2352          zcb->zcb_spa = spa;
2303 2353  
2304 2354          if (!dump_opt['L']) {
2305 2355                  vdev_t *rvd = spa->spa_root_vdev;
2306 2356                  for (int c = 0; c < rvd->vdev_children; c++) {
2307 2357                          vdev_t *vd = rvd->vdev_child[c];
2308 2358                          for (int m = 0; m < vd->vdev_ms_count; m++) {
2309 2359                                  metaslab_t *msp = vd->vdev_ms[m];
2310 2360                                  mutex_enter(&msp->ms_lock);
2311      -                                space_map_unload(msp->ms_map);
2312      -                                VERIFY(space_map_load(msp->ms_map,
2313      -                                    &zdb_space_map_ops, SM_ALLOC, &msp->ms_smo,
2314      -                                    spa->spa_meta_objset) == 0);
2315      -                                msp->ms_map->sm_ppd = vd;
     2361 +                                metaslab_unload(msp);
     2362 +
     2363 +                                /*
     2364 +                                 * For leak detection, we overload the metaslab
     2365 +                                 * ms_tree to contain allocated segments
     2366 +                                 * instead of free segments. As a result,
     2367 +                                 * we can't use the normal metaslab_load/unload
     2368 +                                 * interfaces.
     2369 +                                 */
     2370 +                                if (msp->ms_sm != NULL) {
     2371 +                                        msp->ms_ops = &zdb_metaslab_ops;
     2372 +                                        VERIFY0(space_map_load(msp->ms_sm,
     2373 +                                            msp->ms_tree, SM_ALLOC));
     2374 +                                        msp->ms_loaded = B_TRUE;
     2375 +                                }
2316 2376                                  mutex_exit(&msp->ms_lock);
2317 2377                          }
2318 2378                  }
2319 2379          }
2320 2380  
2321 2381          spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
2322 2382  
2323 2383          zdb_ddt_leak_init(spa, zcb);
2324 2384  
2325 2385          spa_config_exit(spa, SCL_CONFIG, FTAG);
↓ open down ↓ 2 lines elided ↑ open up ↑
2328 2388  static void
2329 2389  zdb_leak_fini(spa_t *spa)
2330 2390  {
2331 2391          if (!dump_opt['L']) {
2332 2392                  vdev_t *rvd = spa->spa_root_vdev;
2333 2393                  for (int c = 0; c < rvd->vdev_children; c++) {
2334 2394                          vdev_t *vd = rvd->vdev_child[c];
2335 2395                          for (int m = 0; m < vd->vdev_ms_count; m++) {
2336 2396                                  metaslab_t *msp = vd->vdev_ms[m];
2337 2397                                  mutex_enter(&msp->ms_lock);
2338      -                                space_map_unload(msp->ms_map);
     2398 +
     2399 +                                /*
     2400 +                                 * The ms_tree has been overloaded to
     2401 +                                 * contain allocated segments. Now that we
     2402 +                                 * finished traversing all blocks, any
     2403 +                                 * block that remains in the ms_tree
     2404 +                                 * represents an allocated block that we
     2405 +                                 * did not claim during the traversal.
     2406 +                                 * Claimed blocks would have been removed
     2407 +                                 * from the ms_tree.
     2408 +                                 */
     2409 +                                range_tree_vacate(msp->ms_tree, zdb_leak, vd);
     2410 +                                msp->ms_loaded = B_FALSE;
     2411 +
2339 2412                                  mutex_exit(&msp->ms_lock);
2340 2413                          }
2341 2414                  }
2342 2415          }
2343 2416  }
2344 2417  
2345 2418  /* ARGSUSED */
2346 2419  static int
2347 2420  count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
2348 2421  {
↓ open down ↓ 207 lines elided ↑ open up ↑
2556 2629                                  if (dump_opt['b'] >= 3 && zb->zb_gangs > 0) {
2557 2630                                          (void) printf("\t number of ganged "
2558 2631                                              "blocks: %s\n", gang);
2559 2632                                  }
2560 2633  
2561 2634                                  if (dump_opt['b'] >= 4) {
2562 2635                                          (void) printf("psize "
2563 2636                                              "(in 512-byte sectors): "
2564 2637                                              "number of blocks\n");
2565 2638                                          dump_histogram(zb->zb_psize_histogram,
2566      -                                            PSIZE_HISTO_SIZE);
     2639 +                                            PSIZE_HISTO_SIZE, 0);
2567 2640                                  }
2568 2641                          }
2569 2642                  }
2570 2643          }
2571 2644  
2572 2645          (void) printf("\n");
2573 2646  
2574 2647          if (leaks)
2575 2648                  return (2);
2576 2649  
↓ open down ↓ 149 lines elided ↑ open up ↑
2726 2799                                      "Pool dataset frees");
2727 2800                          }
2728 2801                          dump_dtl(spa->spa_root_vdev, 0);
2729 2802                  }
2730 2803                  (void) dmu_objset_find(spa_name(spa), dump_one_dir,
2731 2804                      NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
2732 2805          }
2733 2806          if (dump_opt['b'] || dump_opt['c'])
2734 2807                  rc = dump_block_stats(spa);
2735 2808  
     2809 +        if (rc == 0)
     2810 +                rc = verify_spacemap_refcounts(spa);
     2811 +
2736 2812          if (dump_opt['s'])
2737 2813                  show_pool_stats(spa);
2738 2814  
2739 2815          if (dump_opt['h'])
2740 2816                  dump_history(spa);
2741 2817  
2742 2818          if (rc != 0)
2743 2819                  exit(rc);
2744 2820  }
2745 2821  
↓ open down ↓ 678 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX