summaryrefslogtreecommitdiff
path: root/usr/src/cmd/zdb/zdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/zdb/zdb.c')
-rw-r--r--usr/src/cmd/zdb/zdb.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/usr/src/cmd/zdb/zdb.c b/usr/src/cmd/zdb/zdb.c
index c05d20643f..2ca0460605 100644
--- a/usr/src/cmd/zdb/zdb.c
+++ b/usr/src/cmd/zdb/zdb.c
@@ -94,14 +94,15 @@ static void
usage(void)
{
(void) fprintf(stderr,
- "Usage: %s [-CumdibcsvhL] [-S user:cksumalg] "
+ "Usage: %s [-CumdibcsvhL] "
"poolname [object...]\n"
" %s [-div] dataset [object...]\n"
" %s -m [-L] poolname [vdev [metaslab...]]\n"
" %s -R poolname vdev:offset:size[:flags]\n"
+ " %s -S poolname\n"
" %s -l device\n"
" %s -C\n\n",
- cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
+ cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
(void) fprintf(stderr, " Dataset name must include at least one "
"separator character '/' or '@'\n");
@@ -549,7 +550,7 @@ dump_dde(const ddt_t *ddt, const ddt_entry_t *dde, uint64_t index)
for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
if (ddp->ddp_phys_birth == 0)
continue;
- ddt_bp_create(ddt, ddk, ddp, &blk);
+ ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
sprintf_blkptr(blkbuf, &blk);
(void) printf("index %llx refcnt %llu %s %s\n",
(u_longlong_t)index, (u_longlong_t)ddp->ddp_refcnt,
@@ -686,7 +687,7 @@ dump_ddt(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
(void) printf("%s contents:\n\n", name);
- while ((error = ddt_object_walk(ddt, type, class, &dde, &walk)) == 0)
+ while ((error = ddt_object_walk(ddt, type, class, &walk, &dde)) == 0)
dump_dde(ddt, &dde, walk);
ASSERT(error == ENOENT);
@@ -1344,7 +1345,8 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header)
nicenum(doi.doi_physical_blocks_512 << 9, asize);
nicenum(doi.doi_bonus_size, bonus_size);
(void) sprintf(fill, "%6.2f", 100.0 * doi.doi_fill_count *
- doi.doi_data_block_size / doi.doi_max_offset);
+ doi.doi_data_block_size / (object == 0 ? DNODES_PER_BLOCK : 1) /
+ doi.doi_max_offset);
aux[0] = '\0';
@@ -1865,26 +1867,28 @@ static space_map_ops_t zdb_space_map_ops = {
};
static void
-zdb_ddt_leak_init(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
- zdb_cb_t *zcb)
+zdb_ddt_leak_init(spa_t *spa, zdb_cb_t *zcb)
{
- uint64_t walk = 0;
+ ddt_bookmark_t ddb = { 0 };
ddt_entry_t dde;
int error;
- if (class == DDT_CLASS_UNIQUE || !ddt_object_exists(ddt, type, class))
- return;
-
- while ((error = ddt_object_walk(ddt, type, class, &dde, &walk)) == 0) {
+ while ((error = ddt_walk(spa, &ddb, &dde)) == 0) {
blkptr_t blk;
ddt_phys_t *ddp = dde.dde_phys;
+
+ if (ddb.ddb_class == DDT_CLASS_UNIQUE)
+ return;
+
ASSERT(ddt_phys_total_refcnt(&dde) > 1);
+
for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
if (ddp->ddp_phys_birth == 0)
continue;
- ddt_bp_create(ddt, &dde.dde_key, ddp, &blk);
+ ddt_bp_create(ddb.ddb_checksum,
+ &dde.dde_key, ddp, &blk);
if (p == DDT_PHYS_DITTO) {
- zdb_count_block(ddt->ddt_spa, NULL, zcb, &blk,
+ zdb_count_block(spa, NULL, zcb, &blk,
ZDB_OT_DITTO);
} else {
zcb->zcb_dedup_asize +=
@@ -1893,6 +1897,7 @@ zdb_ddt_leak_init(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
}
}
if (!dump_opt['L']) {
+ ddt_t *ddt = spa->spa_ddt[ddb.ddb_checksum];
ddt_enter(ddt);
VERIFY(ddt_lookup(ddt, &blk, B_TRUE) != NULL);
ddt_exit(ddt);
@@ -1924,12 +1929,7 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
- for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++)
- for (enum ddt_type type = 0; type < DDT_TYPES; type++)
- for (enum ddt_class class = 0; class < DDT_CLASSES;
- class++)
- zdb_ddt_leak_init(spa->spa_ddt[c],
- type, class, zcb);
+ zdb_ddt_leak_init(spa, zcb);
spa_config_exit(spa, SCL_CONFIG, FTAG);
}
@@ -1957,6 +1957,7 @@ dump_block_stats(spa_t *spa)
zdb_cb_t zcb = { 0 };
zdb_blkstats_t *zb, *tzb;
uint64_t norm_alloc, norm_space, total_alloc, total_found;
+ int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA;
int leaks = 0;
(void) printf("\nTraversing all blocks %s%s%s%s%s...\n",
@@ -2000,7 +2001,10 @@ dump_block_stats(spa_t *spa)
bplist_close(bpl);
}
- zcb.zcb_haderrors |= traverse_pool(spa, zdb_blkptr_cb, &zcb, 0);
+ if (dump_opt['c'] > 1)
+ flags |= TRAVERSE_PREFETCH_DATA;
+
+ zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
if (zcb.zcb_haderrors) {
(void) printf("\nError counts:\n\n");
@@ -2170,7 +2174,8 @@ zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
avl_numnodes(t));
}
- if (BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata)
+ if (BP_IS_HOLE(bp) || BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_OFF ||
+ BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata)
return (0);
ddt_key_fill(&zdde_search.zdde_key, bp);
@@ -2205,7 +2210,8 @@ dump_simulated_ddt(spa_t *spa)
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
- (void) traverse_pool(spa, zdb_ddt_add_cb, &t, 0);
+ (void) traverse_pool(spa, 0, TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA,
+ zdb_ddt_add_cb, &t);
spa_config_exit(spa, SCL_CONFIG, FTAG);