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>


 229             (u_longlong_t)shp->sh_bof);
 230         (void) printf("\t\teof = %llu\n",
 231             (u_longlong_t)shp->sh_eof);
 232         (void) printf("\t\trecords_lost = %llu\n",
 233             (u_longlong_t)shp->sh_records_lost);
 234 }
 235 
 236 static void
 237 zdb_nicenum(uint64_t num, char *buf)
 238 {
 239         if (dump_opt['P'])
 240                 (void) sprintf(buf, "%llu", (longlong_t)num);
 241         else
 242                 nicenum(num, buf);
 243 }
 244 
 245 const char histo_stars[] = "****************************************";
 246 const int histo_width = sizeof (histo_stars) - 1;
 247 
 248 static void
 249 dump_histogram(const uint64_t *histo, int size)
 250 {
 251         int i;
 252         int minidx = size - 1;
 253         int maxidx = 0;
 254         uint64_t max = 0;
 255 
 256         for (i = 0; i < size; i++) {
 257                 if (histo[i] > max)
 258                         max = histo[i];
 259                 if (histo[i] > 0 && i > maxidx)
 260                         maxidx = i;
 261                 if (histo[i] > 0 && i < minidx)
 262                         minidx = i;
 263         }
 264 
 265         if (max < histo_width)
 266                 max = histo_width;
 267 
 268         for (i = minidx; i <= maxidx; i++) {
 269                 (void) printf("\t\t\t%3u: %6llu %s\n",
 270                     i, (u_longlong_t)histo[i],
 271                     &histo_stars[(max - histo[i]) * histo_width / max]);
 272         }
 273 }
 274 
 275 static void
 276 dump_zap_stats(objset_t *os, uint64_t object)
 277 {
 278         int error;
 279         zap_stats_t zs;
 280 
 281         error = zap_get_stats(os, object, &zs);
 282         if (error)
 283                 return;
 284 
 285         if (zs.zs_ptrtbl_len == 0) {
 286                 ASSERT(zs.zs_num_blocks == 1);
 287                 (void) printf("\tmicrozap: %llu bytes, %llu entries\n",
 288                     (u_longlong_t)zs.zs_blocksize,
 289                     (u_longlong_t)zs.zs_num_entries);
 290                 return;


 303             (u_longlong_t)zs.zs_ptrtbl_zt_shift);
 304         (void) printf("\t\t\tzt_blks_copied: %llu\n",
 305             (u_longlong_t)zs.zs_ptrtbl_blks_copied);
 306         (void) printf("\t\t\tzt_nextblk: %llu\n",
 307             (u_longlong_t)zs.zs_ptrtbl_nextblk);
 308 
 309         (void) printf("\t\tZAP entries: %llu\n",
 310             (u_longlong_t)zs.zs_num_entries);
 311         (void) printf("\t\tLeaf blocks: %llu\n",
 312             (u_longlong_t)zs.zs_num_leafs);
 313         (void) printf("\t\tTotal blocks: %llu\n",
 314             (u_longlong_t)zs.zs_num_blocks);
 315         (void) printf("\t\tzap_block_type: 0x%llx\n",
 316             (u_longlong_t)zs.zs_block_type);
 317         (void) printf("\t\tzap_magic: 0x%llx\n",
 318             (u_longlong_t)zs.zs_magic);
 319         (void) printf("\t\tzap_salt: 0x%llx\n",
 320             (u_longlong_t)zs.zs_salt);
 321 
 322         (void) printf("\t\tLeafs with 2^n pointers:\n");
 323         dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE);
 324 
 325         (void) printf("\t\tBlocks with n*5 entries:\n");
 326         dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE);
 327 
 328         (void) printf("\t\tBlocks n/10 full:\n");
 329         dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE);
 330 
 331         (void) printf("\t\tEntries with n chunks:\n");
 332         dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE);
 333 
 334         (void) printf("\t\tBuckets with n entries:\n");
 335         dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE);
 336 }
 337 
 338 /*ARGSUSED*/
 339 static void
 340 dump_none(objset_t *os, uint64_t object, void *data, size_t size)
 341 {
 342 }
 343 
 344 /*ARGSUSED*/
 345 static void
 346 dump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
 347 {
 348         (void) printf("\tUNKNOWN OBJECT TYPE\n");
 349 }
 350 
 351 /*ARGSUSED*/
 352 void
 353 dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
 354 {
 355 }


 504                 /* 11 */ "11 (invalid)",
 505                 /* 12 */ "Socket",
 506                 /* 13 */ "Door",
 507                 /* 14 */ "Event Port",
 508                 /* 15 */ "15 (invalid)",
 509         };
 510 
 511         dump_zap_stats(os, object);
 512         (void) printf("\n");
 513 
 514         for (zap_cursor_init(&zc, os, object);
 515             zap_cursor_retrieve(&zc, &attr) == 0;
 516             zap_cursor_advance(&zc)) {
 517                 (void) printf("\t\t%s = %lld (type: %s)\n",
 518                     attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
 519                     typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
 520         }
 521         zap_cursor_fini(&zc);
 522 }
 523 

























































 524 static void
 525 dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
 526 {
 527         uint64_t alloc, offset, entry;
 528         uint8_t mapshift = sm->sm_shift;
 529         uint64_t mapstart = sm->sm_start;
 530         char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
 531                             "INVALID", "INVALID", "INVALID", "INVALID" };
 532 
 533         if (smo->smo_object == 0)
 534                 return;
 535 
 536         /*
 537          * Print out the freelist entries in both encoded and decoded form.
 538          */
 539         alloc = 0;
 540         for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
 541                 VERIFY3U(0, ==, dmu_read(os, smo->smo_object, offset,



 542                     sizeof (entry), &entry, DMU_READ_PREFETCH));
 543                 if (SM_DEBUG_DECODE(entry)) {

 544                         (void) printf("\t    [%6llu] %s: txg %llu, pass %llu\n",
 545                             (u_longlong_t)(offset / sizeof (entry)),
 546                             ddata[SM_DEBUG_ACTION_DECODE(entry)],
 547                             (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
 548                             (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
 549                 } else {
 550                         (void) printf("\t    [%6llu]    %c  range:"
 551                             " %010llx-%010llx  size: %06llx\n",
 552                             (u_longlong_t)(offset / sizeof (entry)),
 553                             SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
 554                             (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
 555                             mapshift) + mapstart),
 556                             (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
 557                             mapshift) + mapstart + (SM_RUN_DECODE(entry) <<
 558                             mapshift)),
 559                             (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
 560                         if (SM_TYPE_DECODE(entry) == SM_ALLOC)
 561                                 alloc += SM_RUN_DECODE(entry) << mapshift;
 562                         else
 563                                 alloc -= SM_RUN_DECODE(entry) << mapshift;
 564                 }
 565         }
 566         if (alloc != smo->smo_alloc) {
 567                 (void) printf("space_map_object alloc (%llu) INCONSISTENT "
 568                     "with space map summary (%llu)\n",
 569                     (u_longlong_t)smo->smo_alloc, (u_longlong_t)alloc);
 570         }
 571 }
 572 
 573 static void
 574 dump_metaslab_stats(metaslab_t *msp)
 575 {
 576         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;
 580 
 581         zdb_nicenum(space_map_maxsize(sm), maxbuf);
 582 
 583         (void) printf("\t %25s %10lu   %7s  %6s   %4s %4d%%\n",
 584             "segments", avl_numnodes(t), "maxsize", maxbuf,
 585             "freepct", free_pct);


 586 }
 587 
 588 static void
 589 dump_metaslab(metaslab_t *msp)
 590 {
 591         vdev_t *vd = msp->ms_group->mg_vd;
 592         spa_t *spa = vd->vdev_spa;
 593         space_map_t *sm = msp->ms_map;
 594         space_map_obj_t *smo = &msp->ms_smo;
 595         char freebuf[32];
 596 
 597         zdb_nicenum(sm->sm_size - smo->smo_alloc, freebuf);
 598 
 599         (void) printf(
 600             "\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);
 603 
 604         if (dump_opt['m'] > 1 && !dump_opt['L']) {
 605                 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);

 610                 dump_metaslab_stats(msp);
 611                 space_map_unload(sm);
 612                 mutex_exit(&msp->ms_lock);
 613         }
 614 
 615         if (dump_opt['d'] > 5 || dump_opt['m'] > 2) {
 616                 ASSERT(sm->sm_size == (1ULL << vd->vdev_ms_shift));









 617 



 618                 mutex_enter(&msp->ms_lock);
 619                 dump_spacemap(spa->spa_meta_objset, smo, sm);
 620                 mutex_exit(&msp->ms_lock);
 621         }
 622 }
 623 
 624 static void
 625 print_vdev_metaslab_header(vdev_t *vd)
 626 {
 627         (void) printf("\tvdev %10llu\n\t%-10s%5llu   %-19s   %-15s   %-10s\n",
 628             (u_longlong_t)vd->vdev_id,
 629             "metaslabs", (u_longlong_t)vd->vdev_ms_count,
 630             "offset", "spacemap", "free");
 631         (void) printf("\t%15s   %19s   %15s   %10s\n",
 632             "---------------", "-------------------",
 633             "---------------", "-------------");
 634 }
 635 
 636 static void
 637 dump_metaslabs(spa_t *spa)
 638 {
 639         vdev_t *vd, *rvd = spa->spa_root_vdev;


 786 
 787         ddt_get_dedup_stats(spa, &dds_total);
 788 
 789         if (dds_total.dds_blocks == 0) {
 790                 (void) printf("All DDTs are empty\n");
 791                 return;
 792         }
 793 
 794         (void) printf("\n");
 795 
 796         if (dump_opt['D'] > 1) {
 797                 (void) printf("DDT histogram (aggregated over all DDTs):\n");
 798                 ddt_get_dedup_histogram(spa, &ddh_total);
 799                 zpool_dump_ddt(&dds_total, &ddh_total);
 800         }
 801 
 802         dump_dedup_ratio(&dds_total);
 803 }
 804 
 805 static void
 806 dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size)
 807 {
 808         char *prefix = (void *)sm;
 809 
 810         (void) printf("%s [%llu,%llu) length %llu\n",
 811             prefix,
 812             (u_longlong_t)start,
 813             (u_longlong_t)(start + size),
 814             (u_longlong_t)(size));
 815 }
 816 
 817 static void
 818 dump_dtl(vdev_t *vd, int indent)
 819 {
 820         spa_t *spa = vd->vdev_spa;
 821         boolean_t required;
 822         char *name[DTL_TYPES] = { "missing", "partial", "scrub", "outage" };
 823         char prefix[256];
 824 
 825         spa_vdev_state_enter(spa, SCL_NONE);
 826         required = vdev_dtl_required(vd);
 827         (void) spa_vdev_state_exit(spa, NULL, 0);
 828 
 829         if (indent == 0)
 830                 (void) printf("\nDirty time logs:\n\n");
 831 
 832         (void) printf("\t%*s%s [%s]\n", indent, "",
 833             vd->vdev_path ? vd->vdev_path :
 834             vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
 835             required ? "DTL-required" : "DTL-expendable");
 836 
 837         for (int t = 0; t < DTL_TYPES; t++) {
 838                 space_map_t *sm = &vd->vdev_dtl[t];
 839                 if (sm->sm_space == 0)
 840                         continue;
 841                 (void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
 842                     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);
 846                 if (dump_opt['d'] > 5 && vd->vdev_children == 0)
 847                         dump_spacemap(spa->spa_meta_objset,
 848                             &vd->vdev_dtl_smo, sm);
 849         }
 850 
 851         for (int c = 0; c < vd->vdev_children; c++)
 852                 dump_dtl(vd->vdev_child[c], indent + 4);
 853 }
 854 
 855 static void
 856 dump_history(spa_t *spa)
 857 {
 858         nvlist_t **events = NULL;
 859         char buf[SPA_MAXBLOCKSIZE];
 860         uint64_t resid, len, off = 0;
 861         uint_t num = 0;
 862         int error;
 863         time_t tsec;
 864         struct tm t;
 865         char tbuf[30];
 866         char internalstr[MAXPATHLEN];
 867 
 868         do {


2204                     1 + bytes / (1 + ((now - zcb->zcb_start) / 1000 / 1000));
2205                 int sec_remaining =
2206                     (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec;
2207 
2208                 zfs_nicenum(bytes, buf, sizeof (buf));
2209                 (void) fprintf(stderr,
2210                     "\r%5s completed (%4dMB/s) "
2211                     "estimated time remaining: %uhr %02umin %02usec        ",
2212                     buf, kb_per_sec / 1024,
2213                     sec_remaining / 60 / 60,
2214                     sec_remaining / 60 % 60,
2215                     sec_remaining % 60);
2216 
2217                 zcb->zcb_lastprint = now;
2218         }
2219 
2220         return (0);
2221 }
2222 
2223 static void
2224 zdb_leak(space_map_t *sm, uint64_t start, uint64_t size)
2225 {
2226         vdev_t *vd = sm->sm_ppd;
2227 
2228         (void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
2229             (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
2230 }
2231 
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,
2253         NULL,   /* alloc */
2254         zdb_space_map_claim,
2255         NULL,   /* free */
2256         NULL    /* maxsize */
2257 };
2258 
2259 static void
2260 zdb_ddt_leak_init(spa_t *spa, zdb_cb_t *zcb)
2261 {
2262         ddt_bookmark_t ddb = { 0 };
2263         ddt_entry_t dde;
2264         int error;
2265 
2266         while ((error = ddt_walk(spa, &ddb, &dde)) == 0) {
2267                 blkptr_t blk;
2268                 ddt_phys_t *ddp = dde.dde_phys;
2269 
2270                 if (ddb.ddb_class == DDT_CLASS_UNIQUE)
2271                         return;
2272 
2273                 ASSERT(ddt_phys_total_refcnt(&dde) > 1);
2274 
2275                 for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
2276                         if (ddp->ddp_phys_birth == 0)


2291                         VERIFY(ddt_lookup(ddt, &blk, B_TRUE) != NULL);
2292                         ddt_exit(ddt);
2293                 }
2294         }
2295 
2296         ASSERT(error == ENOENT);
2297 }
2298 
2299 static void
2300 zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
2301 {
2302         zcb->zcb_spa = spa;
2303 
2304         if (!dump_opt['L']) {
2305                 vdev_t *rvd = spa->spa_root_vdev;
2306                 for (int c = 0; c < rvd->vdev_children; c++) {
2307                         vdev_t *vd = rvd->vdev_child[c];
2308                         for (int m = 0; m < vd->vdev_ms_count; m++) {
2309                                 metaslab_t *msp = vd->vdev_ms[m];
2310                                 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;










2316                                 mutex_exit(&msp->ms_lock);
2317                         }
2318                 }
2319         }
2320 
2321         spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
2322 
2323         zdb_ddt_leak_init(spa, zcb);
2324 
2325         spa_config_exit(spa, SCL_CONFIG, FTAG);
2326 }
2327 
2328 static void
2329 zdb_leak_fini(spa_t *spa)
2330 {
2331         if (!dump_opt['L']) {
2332                 vdev_t *rvd = spa->spa_root_vdev;
2333                 for (int c = 0; c < rvd->vdev_children; c++) {
2334                         vdev_t *vd = rvd->vdev_child[c];
2335                         for (int m = 0; m < vd->vdev_ms_count; m++) {
2336                                 metaslab_t *msp = vd->vdev_ms[m];
2337                                 mutex_enter(&msp->ms_lock);
2338                                 space_map_unload(msp->ms_map);













2339                                 mutex_exit(&msp->ms_lock);
2340                         }
2341                 }
2342         }
2343 }
2344 
2345 /* ARGSUSED */
2346 static int
2347 count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
2348 {
2349         zdb_cb_t *zcb = arg;
2350 
2351         if (dump_opt['b'] >= 5) {
2352                 char blkbuf[BP_SPRINTF_LEN];
2353                 sprintf_blkptr(blkbuf, bp);
2354                 (void) printf("[%s] %s\n",
2355                     "deferred free", blkbuf);
2356         }
2357         zdb_count_block(zcb, NULL, bp, ZDB_OT_DEFERRED);
2358         return (0);


2546                                     csize, lsize, psize, asize, avg,
2547                                     (double)zb->zb_lsize / zb->zb_psize,
2548                                     100.0 * zb->zb_asize / tzb->zb_asize);
2549 
2550                                 if (level == ZB_TOTAL)
2551                                         (void) printf("%s\n", typename);
2552                                 else
2553                                         (void) printf("    L%d %s\n",
2554                                             level, typename);
2555 
2556                                 if (dump_opt['b'] >= 3 && zb->zb_gangs > 0) {
2557                                         (void) printf("\t number of ganged "
2558                                             "blocks: %s\n", gang);
2559                                 }
2560 
2561                                 if (dump_opt['b'] >= 4) {
2562                                         (void) printf("psize "
2563                                             "(in 512-byte sectors): "
2564                                             "number of blocks\n");
2565                                         dump_histogram(zb->zb_psize_histogram,
2566                                             PSIZE_HISTO_SIZE);
2567                                 }
2568                         }
2569                 }
2570         }
2571 
2572         (void) printf("\n");
2573 
2574         if (leaks)
2575                 return (2);
2576 
2577         if (zcb.zcb_haderrors)
2578                 return (3);
2579 
2580         return (0);
2581 }
2582 
2583 typedef struct zdb_ddt_entry {
2584         ddt_key_t       zdde_key;
2585         uint64_t        zdde_ref_blocks;
2586         uint64_t        zdde_ref_lsize;


2716                             "Deferred frees", 0);
2717                         if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
2718                                 dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
2719                                     "Pool snapshot frees", 0);
2720                         }
2721 
2722                         if (spa_feature_is_active(spa,
2723                             &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
2724                                 dump_bptree(spa->spa_meta_objset,
2725                                     spa->spa_dsl_pool->dp_bptree_obj,
2726                                     "Pool dataset frees");
2727                         }
2728                         dump_dtl(spa->spa_root_vdev, 0);
2729                 }
2730                 (void) dmu_objset_find(spa_name(spa), dump_one_dir,
2731                     NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
2732         }
2733         if (dump_opt['b'] || dump_opt['c'])
2734                 rc = dump_block_stats(spa);
2735 



2736         if (dump_opt['s'])
2737                 show_pool_stats(spa);
2738 
2739         if (dump_opt['h'])
2740                 dump_history(spa);
2741 
2742         if (rc != 0)
2743                 exit(rc);
2744 }
2745 
2746 #define ZDB_FLAG_CHECKSUM       0x0001
2747 #define ZDB_FLAG_DECOMPRESS     0x0002
2748 #define ZDB_FLAG_BSWAP          0x0004
2749 #define ZDB_FLAG_GBH            0x0008
2750 #define ZDB_FLAG_INDIRECT       0x0010
2751 #define ZDB_FLAG_PHYS           0x0020
2752 #define ZDB_FLAG_RAW            0x0040
2753 #define ZDB_FLAG_PRINT_BLKPTR   0x0080
2754 
2755 int flagbits[256];




 229             (u_longlong_t)shp->sh_bof);
 230         (void) printf("\t\teof = %llu\n",
 231             (u_longlong_t)shp->sh_eof);
 232         (void) printf("\t\trecords_lost = %llu\n",
 233             (u_longlong_t)shp->sh_records_lost);
 234 }
 235 
 236 static void
 237 zdb_nicenum(uint64_t num, char *buf)
 238 {
 239         if (dump_opt['P'])
 240                 (void) sprintf(buf, "%llu", (longlong_t)num);
 241         else
 242                 nicenum(num, buf);
 243 }
 244 
 245 const char histo_stars[] = "****************************************";
 246 const int histo_width = sizeof (histo_stars) - 1;
 247 
 248 static void
 249 dump_histogram(const uint64_t *histo, int size, int offset)
 250 {
 251         int i;
 252         int minidx = size - 1;
 253         int maxidx = 0;
 254         uint64_t max = 0;
 255 
 256         for (i = 0; i < size; i++) {
 257                 if (histo[i] > max)
 258                         max = histo[i];
 259                 if (histo[i] > 0 && i > maxidx)
 260                         maxidx = i;
 261                 if (histo[i] > 0 && i < minidx)
 262                         minidx = i;
 263         }
 264 
 265         if (max < histo_width)
 266                 max = histo_width;
 267 
 268         for (i = minidx; i <= maxidx; i++) {
 269                 (void) printf("\t\t\t%3u: %6llu %s\n",
 270                     i + offset, (u_longlong_t)histo[i],
 271                     &histo_stars[(max - histo[i]) * histo_width / max]);
 272         }
 273 }
 274 
 275 static void
 276 dump_zap_stats(objset_t *os, uint64_t object)
 277 {
 278         int error;
 279         zap_stats_t zs;
 280 
 281         error = zap_get_stats(os, object, &zs);
 282         if (error)
 283                 return;
 284 
 285         if (zs.zs_ptrtbl_len == 0) {
 286                 ASSERT(zs.zs_num_blocks == 1);
 287                 (void) printf("\tmicrozap: %llu bytes, %llu entries\n",
 288                     (u_longlong_t)zs.zs_blocksize,
 289                     (u_longlong_t)zs.zs_num_entries);
 290                 return;


 303             (u_longlong_t)zs.zs_ptrtbl_zt_shift);
 304         (void) printf("\t\t\tzt_blks_copied: %llu\n",
 305             (u_longlong_t)zs.zs_ptrtbl_blks_copied);
 306         (void) printf("\t\t\tzt_nextblk: %llu\n",
 307             (u_longlong_t)zs.zs_ptrtbl_nextblk);
 308 
 309         (void) printf("\t\tZAP entries: %llu\n",
 310             (u_longlong_t)zs.zs_num_entries);
 311         (void) printf("\t\tLeaf blocks: %llu\n",
 312             (u_longlong_t)zs.zs_num_leafs);
 313         (void) printf("\t\tTotal blocks: %llu\n",
 314             (u_longlong_t)zs.zs_num_blocks);
 315         (void) printf("\t\tzap_block_type: 0x%llx\n",
 316             (u_longlong_t)zs.zs_block_type);
 317         (void) printf("\t\tzap_magic: 0x%llx\n",
 318             (u_longlong_t)zs.zs_magic);
 319         (void) printf("\t\tzap_salt: 0x%llx\n",
 320             (u_longlong_t)zs.zs_salt);
 321 
 322         (void) printf("\t\tLeafs with 2^n pointers:\n");
 323         dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE, 0);
 324 
 325         (void) printf("\t\tBlocks with n*5 entries:\n");
 326         dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE, 0);
 327 
 328         (void) printf("\t\tBlocks n/10 full:\n");
 329         dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE, 0);
 330 
 331         (void) printf("\t\tEntries with n chunks:\n");
 332         dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE, 0);
 333 
 334         (void) printf("\t\tBuckets with n entries:\n");
 335         dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE, 0);
 336 }
 337 
 338 /*ARGSUSED*/
 339 static void
 340 dump_none(objset_t *os, uint64_t object, void *data, size_t size)
 341 {
 342 }
 343 
 344 /*ARGSUSED*/
 345 static void
 346 dump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
 347 {
 348         (void) printf("\tUNKNOWN OBJECT TYPE\n");
 349 }
 350 
 351 /*ARGSUSED*/
 352 void
 353 dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
 354 {
 355 }


 504                 /* 11 */ "11 (invalid)",
 505                 /* 12 */ "Socket",
 506                 /* 13 */ "Door",
 507                 /* 14 */ "Event Port",
 508                 /* 15 */ "15 (invalid)",
 509         };
 510 
 511         dump_zap_stats(os, object);
 512         (void) printf("\n");
 513 
 514         for (zap_cursor_init(&zc, os, object);
 515             zap_cursor_retrieve(&zc, &attr) == 0;
 516             zap_cursor_advance(&zc)) {
 517                 (void) printf("\t\t%s = %lld (type: %s)\n",
 518                     attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
 519                     typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
 520         }
 521         zap_cursor_fini(&zc);
 522 }
 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 
 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);
 596             offset += sizeof (entry)) {
 597                 uint8_t mapshift = sm->sm_shift;
 598 
 599                 VERIFY0(dmu_read(os, space_map_object(sm), offset,
 600                     sizeof (entry), &entry, DMU_READ_PREFETCH));
 601                 if (SM_DEBUG_DECODE(entry)) {
 602 
 603                         (void) printf("\t    [%6llu] %s: txg %llu, pass %llu\n",
 604                             (u_longlong_t)(offset / sizeof (entry)),
 605                             ddata[SM_DEBUG_ACTION_DECODE(entry)],
 606                             (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
 607                             (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
 608                 } else {
 609                         (void) printf("\t    [%6llu]    %c  range:"
 610                             " %010llx-%010llx  size: %06llx\n",
 611                             (u_longlong_t)(offset / sizeof (entry)),
 612                             SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
 613                             (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
 614                             mapshift) + sm->sm_start),
 615                             (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
 616                             mapshift) + sm->sm_start +
 617                             (SM_RUN_DECODE(entry) << mapshift)),
 618                             (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
 619                         if (SM_TYPE_DECODE(entry) == SM_ALLOC)
 620                                 alloc += SM_RUN_DECODE(entry) << mapshift;
 621                         else
 622                                 alloc -= SM_RUN_DECODE(entry) << mapshift;
 623                 }
 624         }
 625         if (alloc != space_map_allocated(sm)) {
 626                 (void) printf("space_map_object alloc (%llu) INCONSISTENT "
 627                     "with space map summary (%llu)\n",
 628                     (u_longlong_t)space_map_allocated(sm), (u_longlong_t)alloc);
 629         }
 630 }
 631 
 632 static void
 633 dump_metaslab_stats(metaslab_t *msp)
 634 {
 635         char maxbuf[32];
 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;
 639 
 640         zdb_nicenum(metaslab_block_maxsize(msp), maxbuf);
 641 
 642         (void) printf("\t %25s %10lu   %7s  %6s   %4s %4d%%\n",
 643             "segments", avl_numnodes(t), "maxsize", maxbuf,
 644             "freepct", free_pct);
 645         (void) printf("\tIn-memory histogram:\n");
 646         dump_histogram(rt->rt_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
 647 }
 648 
 649 static void
 650 dump_metaslab(metaslab_t *msp)
 651 {
 652         vdev_t *vd = msp->ms_group->mg_vd;
 653         spa_t *spa = vd->vdev_spa;
 654         space_map_t *sm = msp->ms_sm;

 655         char freebuf[32];
 656 
 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)
 699 {
 700         (void) printf("\tvdev %10llu\n\t%-10s%5llu   %-19s   %-15s   %-10s\n",
 701             (u_longlong_t)vd->vdev_id,
 702             "metaslabs", (u_longlong_t)vd->vdev_ms_count,
 703             "offset", "spacemap", "free");
 704         (void) printf("\t%15s   %19s   %15s   %10s\n",
 705             "---------------", "-------------------",
 706             "---------------", "-------------");
 707 }
 708 
 709 static void
 710 dump_metaslabs(spa_t *spa)
 711 {
 712         vdev_t *vd, *rvd = spa->spa_root_vdev;


 859 
 860         ddt_get_dedup_stats(spa, &dds_total);
 861 
 862         if (dds_total.dds_blocks == 0) {
 863                 (void) printf("All DDTs are empty\n");
 864                 return;
 865         }
 866 
 867         (void) printf("\n");
 868 
 869         if (dump_opt['D'] > 1) {
 870                 (void) printf("DDT histogram (aggregated over all DDTs):\n");
 871                 ddt_get_dedup_histogram(spa, &ddh_total);
 872                 zpool_dump_ddt(&dds_total, &ddh_total);
 873         }
 874 
 875         dump_dedup_ratio(&dds_total);
 876 }
 877 
 878 static void
 879 dump_dtl_seg(void *arg, uint64_t start, uint64_t size)
 880 {
 881         char *prefix = arg;
 882 
 883         (void) printf("%s [%llu,%llu) length %llu\n",
 884             prefix,
 885             (u_longlong_t)start,
 886             (u_longlong_t)(start + size),
 887             (u_longlong_t)(size));
 888 }
 889 
 890 static void
 891 dump_dtl(vdev_t *vd, int indent)
 892 {
 893         spa_t *spa = vd->vdev_spa;
 894         boolean_t required;
 895         char *name[DTL_TYPES] = { "missing", "partial", "scrub", "outage" };
 896         char prefix[256];
 897 
 898         spa_vdev_state_enter(spa, SCL_NONE);
 899         required = vdev_dtl_required(vd);
 900         (void) spa_vdev_state_exit(spa, NULL, 0);
 901 
 902         if (indent == 0)
 903                 (void) printf("\nDirty time logs:\n\n");
 904 
 905         (void) printf("\t%*s%s [%s]\n", indent, "",
 906             vd->vdev_path ? vd->vdev_path :
 907             vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
 908             required ? "DTL-required" : "DTL-expendable");
 909 
 910         for (int t = 0; t < DTL_TYPES; t++) {
 911                 range_tree_t *rt = vd->vdev_dtl[t];
 912                 if (range_tree_space(rt) == 0)
 913                         continue;
 914                 (void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
 915                     indent + 2, "", name[t]);
 916                 mutex_enter(rt->rt_lock);
 917                 range_tree_walk(rt, dump_dtl_seg, prefix);
 918                 mutex_exit(rt->rt_lock);
 919                 if (dump_opt['d'] > 5 && vd->vdev_children == 0)
 920                         dump_spacemap(spa->spa_meta_objset, vd->vdev_dtl_sm);

 921         }
 922 
 923         for (int c = 0; c < vd->vdev_children; c++)
 924                 dump_dtl(vd->vdev_child[c], indent + 4);
 925 }
 926 
 927 static void
 928 dump_history(spa_t *spa)
 929 {
 930         nvlist_t **events = NULL;
 931         char buf[SPA_MAXBLOCKSIZE];
 932         uint64_t resid, len, off = 0;
 933         uint_t num = 0;
 934         int error;
 935         time_t tsec;
 936         struct tm t;
 937         char tbuf[30];
 938         char internalstr[MAXPATHLEN];
 939 
 940         do {


2276                     1 + bytes / (1 + ((now - zcb->zcb_start) / 1000 / 1000));
2277                 int sec_remaining =
2278                     (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec;
2279 
2280                 zfs_nicenum(bytes, buf, sizeof (buf));
2281                 (void) fprintf(stderr,
2282                     "\r%5s completed (%4dMB/s) "
2283                     "estimated time remaining: %uhr %02umin %02usec        ",
2284                     buf, kb_per_sec / 1024,
2285                     sec_remaining / 60 / 60,
2286                     sec_remaining / 60 % 60,
2287                     sec_remaining % 60);
2288 
2289                 zcb->zcb_lastprint = now;
2290         }
2291 
2292         return (0);
2293 }
2294 
2295 static void
2296 zdb_leak(void *arg, uint64_t start, uint64_t size)
2297 {
2298         vdev_t *vd = arg;
2299 
2300         (void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
2301             (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
2302 }
2303 
2304 static metaslab_ops_t zdb_metaslab_ops = {




















2305         NULL,   /* alloc */
2306         NULL    /* fragmented */


2307 };
2308 
2309 static void
2310 zdb_ddt_leak_init(spa_t *spa, zdb_cb_t *zcb)
2311 {
2312         ddt_bookmark_t ddb = { 0 };
2313         ddt_entry_t dde;
2314         int error;
2315 
2316         while ((error = ddt_walk(spa, &ddb, &dde)) == 0) {
2317                 blkptr_t blk;
2318                 ddt_phys_t *ddp = dde.dde_phys;
2319 
2320                 if (ddb.ddb_class == DDT_CLASS_UNIQUE)
2321                         return;
2322 
2323                 ASSERT(ddt_phys_total_refcnt(&dde) > 1);
2324 
2325                 for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
2326                         if (ddp->ddp_phys_birth == 0)


2341                         VERIFY(ddt_lookup(ddt, &blk, B_TRUE) != NULL);
2342                         ddt_exit(ddt);
2343                 }
2344         }
2345 
2346         ASSERT(error == ENOENT);
2347 }
2348 
2349 static void
2350 zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
2351 {
2352         zcb->zcb_spa = spa;
2353 
2354         if (!dump_opt['L']) {
2355                 vdev_t *rvd = spa->spa_root_vdev;
2356                 for (int c = 0; c < rvd->vdev_children; c++) {
2357                         vdev_t *vd = rvd->vdev_child[c];
2358                         for (int m = 0; m < vd->vdev_ms_count; m++) {
2359                                 metaslab_t *msp = vd->vdev_ms[m];
2360                                 mutex_enter(&msp->ms_lock);
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                                 }
2376                                 mutex_exit(&msp->ms_lock);
2377                         }
2378                 }
2379         }
2380 
2381         spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
2382 
2383         zdb_ddt_leak_init(spa, zcb);
2384 
2385         spa_config_exit(spa, SCL_CONFIG, FTAG);
2386 }
2387 
2388 static void
2389 zdb_leak_fini(spa_t *spa)
2390 {
2391         if (!dump_opt['L']) {
2392                 vdev_t *rvd = spa->spa_root_vdev;
2393                 for (int c = 0; c < rvd->vdev_children; c++) {
2394                         vdev_t *vd = rvd->vdev_child[c];
2395                         for (int m = 0; m < vd->vdev_ms_count; m++) {
2396                                 metaslab_t *msp = vd->vdev_ms[m];
2397                                 mutex_enter(&msp->ms_lock);
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 
2412                                 mutex_exit(&msp->ms_lock);
2413                         }
2414                 }
2415         }
2416 }
2417 
2418 /* ARGSUSED */
2419 static int
2420 count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
2421 {
2422         zdb_cb_t *zcb = arg;
2423 
2424         if (dump_opt['b'] >= 5) {
2425                 char blkbuf[BP_SPRINTF_LEN];
2426                 sprintf_blkptr(blkbuf, bp);
2427                 (void) printf("[%s] %s\n",
2428                     "deferred free", blkbuf);
2429         }
2430         zdb_count_block(zcb, NULL, bp, ZDB_OT_DEFERRED);
2431         return (0);


2619                                     csize, lsize, psize, asize, avg,
2620                                     (double)zb->zb_lsize / zb->zb_psize,
2621                                     100.0 * zb->zb_asize / tzb->zb_asize);
2622 
2623                                 if (level == ZB_TOTAL)
2624                                         (void) printf("%s\n", typename);
2625                                 else
2626                                         (void) printf("    L%d %s\n",
2627                                             level, typename);
2628 
2629                                 if (dump_opt['b'] >= 3 && zb->zb_gangs > 0) {
2630                                         (void) printf("\t number of ganged "
2631                                             "blocks: %s\n", gang);
2632                                 }
2633 
2634                                 if (dump_opt['b'] >= 4) {
2635                                         (void) printf("psize "
2636                                             "(in 512-byte sectors): "
2637                                             "number of blocks\n");
2638                                         dump_histogram(zb->zb_psize_histogram,
2639                                             PSIZE_HISTO_SIZE, 0);
2640                                 }
2641                         }
2642                 }
2643         }
2644 
2645         (void) printf("\n");
2646 
2647         if (leaks)
2648                 return (2);
2649 
2650         if (zcb.zcb_haderrors)
2651                 return (3);
2652 
2653         return (0);
2654 }
2655 
2656 typedef struct zdb_ddt_entry {
2657         ddt_key_t       zdde_key;
2658         uint64_t        zdde_ref_blocks;
2659         uint64_t        zdde_ref_lsize;


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);
2817 
2818         if (rc != 0)
2819                 exit(rc);
2820 }
2821 
2822 #define ZDB_FLAG_CHECKSUM       0x0001
2823 #define ZDB_FLAG_DECOMPRESS     0x0002
2824 #define ZDB_FLAG_BSWAP          0x0004
2825 #define ZDB_FLAG_GBH            0x0008
2826 #define ZDB_FLAG_INDIRECT       0x0010
2827 #define ZDB_FLAG_PHYS           0x0020
2828 #define ZDB_FLAG_RAW            0x0040
2829 #define ZDB_FLAG_PRINT_BLKPTR   0x0080
2830 
2831 int flagbits[256];