512 zap_cursor_fini(&zc);
513 }
514
515 static void
516 dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
517 {
518 uint64_t alloc, offset, entry;
519 uint8_t mapshift = sm->sm_shift;
520 uint64_t mapstart = sm->sm_start;
521 char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
522 "INVALID", "INVALID", "INVALID", "INVALID" };
523
524 if (smo->smo_object == 0)
525 return;
526
527 /*
528 * Print out the freelist entries in both encoded and decoded form.
529 */
530 alloc = 0;
531 for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
532 VERIFY3U(0, ==, dmu_read(os, smo->smo_object, offset,
533 sizeof (entry), &entry, DMU_READ_PREFETCH));
534 if (SM_DEBUG_DECODE(entry)) {
535 (void) printf("\t [%6llu] %s: txg %llu, pass %llu\n",
536 (u_longlong_t)(offset / sizeof (entry)),
537 ddata[SM_DEBUG_ACTION_DECODE(entry)],
538 (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
539 (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
540 } else {
541 (void) printf("\t [%6llu] %c range:"
542 " %010llx-%010llx size: %06llx\n",
543 (u_longlong_t)(offset / sizeof (entry)),
544 SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
545 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
546 mapshift) + mapstart),
547 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
548 mapshift) + mapstart + (SM_RUN_DECODE(entry) <<
549 mapshift)),
550 (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
551 if (SM_TYPE_DECODE(entry) == SM_ALLOC)
552 alloc += SM_RUN_DECODE(entry) << mapshift;
1171 {
1172 char blkbuf[BP_SPRINTF_LEN];
1173
1174 if (bp->blk_birth != 0) {
1175 sprintf_blkptr(blkbuf, bp);
1176 (void) printf("\t%s\n", blkbuf);
1177 }
1178 return (0);
1179 }
1180
1181 static void
1182 dump_bptree(objset_t *os, uint64_t obj, char *name)
1183 {
1184 char bytes[32];
1185 bptree_phys_t *bt;
1186 dmu_buf_t *db;
1187
1188 if (dump_opt['d'] < 3)
1189 return;
1190
1191 VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
1192 bt = db->db_data;
1193 zdb_nicenum(bt->bt_bytes, bytes);
1194 (void) printf("\n %s: %llu datasets, %s\n",
1195 name, (unsigned long long)(bt->bt_end - bt->bt_begin), bytes);
1196 dmu_buf_rele(db, FTAG);
1197
1198 if (dump_opt['d'] < 5)
1199 return;
1200
1201 (void) printf("\n");
1202
1203 (void) bptree_iterate(os, obj, B_FALSE, dump_bptree_cb, NULL, NULL);
1204 }
1205
1206 /* ARGSUSED */
1207 static int
1208 dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
1209 {
1210 char blkbuf[BP_SPRINTF_LEN];
1211
2256
2257 /*
2258 * Load all space maps as SM_ALLOC maps, then traverse the pool
2259 * claiming each block we discover. If the pool is perfectly
2260 * consistent, the space maps will be empty when we're done.
2261 * Anything left over is a leak; any block we can't claim (because
2262 * it's not part of any space map) is a double allocation,
2263 * reference to a freed block, or an unclaimed log block.
2264 */
2265 zdb_leak_init(spa, &zcb);
2266
2267 /*
2268 * If there's a deferred-free bplist, process that first.
2269 */
2270 (void) bpobj_iterate_nofree(&spa->spa_deferred_bpobj,
2271 count_block_cb, &zcb, NULL);
2272 (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj,
2273 count_block_cb, &zcb, NULL);
2274 if (spa_feature_is_active(spa,
2275 &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
2276 VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset,
2277 spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb,
2278 &zcb, NULL));
2279 }
2280
2281 if (dump_opt['c'] > 1)
2282 flags |= TRAVERSE_PREFETCH_DATA;
2283
2284 zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
2285
2286 if (zcb.zcb_haderrors) {
2287 (void) printf("\nError counts:\n\n");
2288 (void) printf("\t%5s %s\n", "errno", "count");
2289 for (int e = 0; e < 256; e++) {
2290 if (zcb.zcb_errors[e] != 0) {
2291 (void) printf("\t%5d %llu\n",
2292 e, (u_longlong_t)zcb.zcb_errors[e]);
2293 }
2294 }
2295 }
2296
|
512 zap_cursor_fini(&zc);
513 }
514
515 static void
516 dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
517 {
518 uint64_t alloc, offset, entry;
519 uint8_t mapshift = sm->sm_shift;
520 uint64_t mapstart = sm->sm_start;
521 char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
522 "INVALID", "INVALID", "INVALID", "INVALID" };
523
524 if (smo->smo_object == 0)
525 return;
526
527 /*
528 * Print out the freelist entries in both encoded and decoded form.
529 */
530 alloc = 0;
531 for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
532 VERIFY0(dmu_read(os, smo->smo_object, offset,
533 sizeof (entry), &entry, DMU_READ_PREFETCH));
534 if (SM_DEBUG_DECODE(entry)) {
535 (void) printf("\t [%6llu] %s: txg %llu, pass %llu\n",
536 (u_longlong_t)(offset / sizeof (entry)),
537 ddata[SM_DEBUG_ACTION_DECODE(entry)],
538 (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
539 (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
540 } else {
541 (void) printf("\t [%6llu] %c range:"
542 " %010llx-%010llx size: %06llx\n",
543 (u_longlong_t)(offset / sizeof (entry)),
544 SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
545 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
546 mapshift) + mapstart),
547 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
548 mapshift) + mapstart + (SM_RUN_DECODE(entry) <<
549 mapshift)),
550 (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
551 if (SM_TYPE_DECODE(entry) == SM_ALLOC)
552 alloc += SM_RUN_DECODE(entry) << mapshift;
1171 {
1172 char blkbuf[BP_SPRINTF_LEN];
1173
1174 if (bp->blk_birth != 0) {
1175 sprintf_blkptr(blkbuf, bp);
1176 (void) printf("\t%s\n", blkbuf);
1177 }
1178 return (0);
1179 }
1180
1181 static void
1182 dump_bptree(objset_t *os, uint64_t obj, char *name)
1183 {
1184 char bytes[32];
1185 bptree_phys_t *bt;
1186 dmu_buf_t *db;
1187
1188 if (dump_opt['d'] < 3)
1189 return;
1190
1191 VERIFY0(dmu_bonus_hold(os, obj, FTAG, &db));
1192 bt = db->db_data;
1193 zdb_nicenum(bt->bt_bytes, bytes);
1194 (void) printf("\n %s: %llu datasets, %s\n",
1195 name, (unsigned long long)(bt->bt_end - bt->bt_begin), bytes);
1196 dmu_buf_rele(db, FTAG);
1197
1198 if (dump_opt['d'] < 5)
1199 return;
1200
1201 (void) printf("\n");
1202
1203 (void) bptree_iterate(os, obj, B_FALSE, dump_bptree_cb, NULL, NULL);
1204 }
1205
1206 /* ARGSUSED */
1207 static int
1208 dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
1209 {
1210 char blkbuf[BP_SPRINTF_LEN];
1211
2256
2257 /*
2258 * Load all space maps as SM_ALLOC maps, then traverse the pool
2259 * claiming each block we discover. If the pool is perfectly
2260 * consistent, the space maps will be empty when we're done.
2261 * Anything left over is a leak; any block we can't claim (because
2262 * it's not part of any space map) is a double allocation,
2263 * reference to a freed block, or an unclaimed log block.
2264 */
2265 zdb_leak_init(spa, &zcb);
2266
2267 /*
2268 * If there's a deferred-free bplist, process that first.
2269 */
2270 (void) bpobj_iterate_nofree(&spa->spa_deferred_bpobj,
2271 count_block_cb, &zcb, NULL);
2272 (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj,
2273 count_block_cb, &zcb, NULL);
2274 if (spa_feature_is_active(spa,
2275 &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
2276 VERIFY0(bptree_iterate(spa->spa_meta_objset,
2277 spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb,
2278 &zcb, NULL));
2279 }
2280
2281 if (dump_opt['c'] > 1)
2282 flags |= TRAVERSE_PREFETCH_DATA;
2283
2284 zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
2285
2286 if (zcb.zcb_haderrors) {
2287 (void) printf("\nError counts:\n\n");
2288 (void) printf("\t%5s %s\n", "errno", "count");
2289 for (int e = 0; e < 256; e++) {
2290 if (zcb.zcb_errors[e] != 0) {
2291 (void) printf("\t%5d %llu\n",
2292 e, (u_longlong_t)zcb.zcb_errors[e]);
2293 }
2294 }
2295 }
2296
|