1fa9e406ahrens/*
2fa9e406ahrens * CDDL HEADER START
3fa9e406ahrens *
4fa9e406ahrens * The contents of this file are subject to the terms of the
5ea8dc4beschrock * Common Development and Distribution License (the "License").
6ea8dc4beschrock * You may not use this file except in compliance with the License.
7fa9e406ahrens *
8fa9e406ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e406ahrens * or http://www.opensolaris.org/os/licensing.
10fa9e406ahrens * See the License for the specific language governing permissions
11fa9e406ahrens * and limitations under the License.
12fa9e406ahrens *
13fa9e406ahrens * When distributing Covered Code, include this CDDL HEADER in each
14fa9e406ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e406ahrens * If applicable, add the following below this CDDL HEADER, with the
16fa9e406ahrens * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e406ahrens * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e406ahrens *
19fa9e406ahrens * CDDL HEADER END
20fa9e406ahrens */
21ad135b5Christopher Siden
22fa9e406ahrens/*
238f2529dMark Shellenbaum * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24663207aDon Brady * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
25c3d26abMatthew Ahrens * Copyright (c) 2014 Integros [integros.com]
26ed61ec1Yuri Pankov * Copyright 2017 Nexenta Systems, Inc.
27e0f1c0aOlaf Faaland * Copyright (c) 2017, 2018 Lawrence Livermore National Security, LLC.
28f06dce2Andrew Stormont * Copyright 2017 RackTop Systems.
29fa9e406ahrens */
30fa9e406ahrens
31fa9e406ahrens#include <stdio.h>
32490d05bMatthew Ahrens#include <unistd.h>
33004388ecasper#include <stdio_ext.h>
34fa9e406ahrens#include <stdlib.h>
3544cd46cbillm#include <ctype.h>
36fa9e406ahrens#include <sys/zfs_context.h>
37fa9e406ahrens#include <sys/spa.h>
38fa9e406ahrens#include <sys/spa_impl.h>
39fa9e406ahrens#include <sys/dmu.h>
40fa9e406ahrens#include <sys/zap.h>
41fa9e406ahrens#include <sys/fs/zfs.h>
42fa9e406ahrens#include <sys/zfs_znode.h>
430a586ceMark Shellenbaum#include <sys/zfs_sa.h>
440a586ceMark Shellenbaum#include <sys/sa.h>
450a586ceMark Shellenbaum#include <sys/sa_impl.h>
46fa9e406ahrens#include <sys/vdev.h>
47fa9e406ahrens#include <sys/vdev_impl.h>
48fa9e406ahrens#include <sys/metaslab_impl.h>
49fa9e406ahrens#include <sys/dmu_objset.h>
50fa9e406ahrens#include <sys/dsl_dir.h>
51fa9e406ahrens#include <sys/dsl_dataset.h>
52fa9e406ahrens#include <sys/dsl_pool.h>
53fa9e406ahrens#include <sys/dbuf.h>
54fa9e406ahrens#include <sys/zil.h>
55fa9e406ahrens#include <sys/zil_impl.h>
56fa9e406ahrens#include <sys/stat.h>
57fa9e406ahrens#include <sys/resource.h>
58fa9e406ahrens#include <sys/dmu_traverse.h>
59fa9e406ahrens#include <sys/zio_checksum.h>
60fa9e406ahrens#include <sys/zio_compress.h>
61e0d35c4marks#include <sys/zfs_fuid.h>
6288b7b0fMatthew Ahrens#include <sys/arc.h>
63b24ab67Jeff Bonwick#include <sys/ddt.h>
64ad135b5Christopher Siden#include <sys/zfeature.h>
65770499eDan Kimmel#include <sys/abd.h>
664923c69Matthew Ahrens#include <sys/blkptr.h>
6717fb938Matthew Ahrens#include <sys/dsl_scan.h>
68eb63303Tom Caputi#include <sys/dsl_crypt.h>
694445fffMatthew Ahrens#include <zfs_comutil.h>
700a05512Jason King#include <libcmdutils.h>
71de6628fck#undef verify
72de6628fck#include <libzfs.h>
73fa9e406ahrens
743f7978dAlan Somers#include "zdb.h"
753f7978dAlan Somers
76e690fb2Christopher Siden#define	ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ?	\
77e690fb2Christopher Siden	zio_compress_table[(idx)].ci_name : "UNKNOWN")
78e690fb2Christopher Siden#define	ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ?	\
79e690fb2Christopher Siden	zio_checksum_table[(idx)].ci_name : "UNKNOWN")
80e690fb2Christopher Siden#define	ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ?	\
81e690fb2Christopher Siden	dmu_ot[(idx)].ot_name : DMU_OT_IS_VALID(idx) ?	\
82e690fb2Christopher Siden	dmu_ot_byteswap[DMU_OT_BYTESWAP(idx)].ob_name : "UNKNOWN")
83e690fb2Christopher Siden#define	ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) :		\
845cabbc6Prashanth Sreenivasa	(idx) == DMU_OTN_ZAP_DATA || (idx) == DMU_OTN_ZAP_METADATA ?	\
855cabbc6Prashanth Sreenivasa	DMU_OT_ZAP_OTHER : \
865cabbc6Prashanth Sreenivasa	(idx) == DMU_OTN_UINT64_DATA || (idx) == DMU_OTN_UINT64_METADATA ? \
875cabbc6Prashanth Sreenivasa	DMU_OT_UINT64_OTHER : DMU_OT_NUMTYPES)
886de8f41Victor Latushkin
89feef89cVictor Latushkin#ifndef lint
904dd77f9Matthew Ahrensextern int reference_tracking_enable;
917fd05acMatthew Ahrensextern boolean_t zfs_recover;
9206be980Matthew Ahrensextern uint64_t zfs_arc_max, zfs_arc_meta_limit;
93f7950bfMatthew Ahrensextern int zfs_vdev_async_read_max_active;
94f06dce2Andrew Stormontextern int aok;
95e144c4ePavel Zakharovextern boolean_t spa_load_verify_dryrun;
96feef89cVictor Latushkin#else
974dd77f9Matthew Ahrensint reference_tracking_enable;
987fd05acMatthew Ahrensboolean_t zfs_recover;
9906be980Matthew Ahrensuint64_t zfs_arc_max, zfs_arc_meta_limit;
100f7950bfMatthew Ahrensint zfs_vdev_async_read_max_active;
101f06dce2Andrew Stormontint aok;
102e144c4ePavel Zakharovboolean_t spa_load_verify_dryrun;
103feef89cVictor Latushkin#endif
104feef89cVictor Latushkin
1053f7978dAlan Somersstatic const char cmdname[] = "zdb";
106fa9e406ahrensuint8_t dump_opt[256];
107fa9e406ahrens
108fa9e406ahrenstypedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
109fa9e406ahrens
110fa9e406ahrensuint64_t *zopt_object = NULL;
1113f7978dAlan Somersstatic unsigned zopt_objects = 0;
112de6628fcklibzfs_handle_t *g_zfs;
11306be980Matthew Ahrensuint64_t max_inflight = 1000;
11420b5dafPaul Dagneliestatic int leaked_objects = 0;
115fa9e406ahrens
116732885fMatthew Ahrensstatic void snprintf_blkptr_compact(char *, size_t, const blkptr_t *);
11717fb938Matthew Ahrensstatic void mos_obj_refd(uint64_t);
118732885fMatthew Ahrens
119fa9e406ahrens/*
120fa9e406ahrens * These libumem hooks provide a reasonable set of defaults for the allocator's
121fa9e406ahrens * debugging facilities.
122fa9e406ahrens */
123fa9e406ahrensconst char *
124fa9e406ahrens_umem_debug_init()
125fa9e406ahrens{
126fa9e406ahrens	return ("default,verbose"); /* $UMEM_DEBUG setting */
127fa9e406ahrens}
128fa9e406ahrens
129fa9e406ahrensconst char *
130fa9e406ahrens_umem_logging_init(void)
131fa9e406ahrens{
132fa9e406ahrens	return ("fail,contents"); /* $UMEM_LOGGING setting */
133fa9e406ahrens}
134fa9e406ahrens
135fa9e406ahrensstatic void
136fa9e406ahrensusage(void)
137fa9e406ahrens{
138fa9e406ahrens	(void) fprintf(stderr,
1398671400Serapheim Dimitropoulos	    "Usage:\t%s [-AbcdDFGhikLMPsvX] [-e [-V] [-p <path> ...]] "
140ed61ec1Yuri Pankov	    "[-I <inflight I/Os>]\n"
141ed61ec1Yuri Pankov	    "\t\t[-o <var>=<value>]... [-t <txg>] [-U <cache>] [-x <dumpdir>]\n"
142ed61ec1Yuri Pankov	    "\t\t[<poolname> [<object> ...]]\n"
143dfd5965Richard Yao	    "\t%s [-AdiPv] [-e [-V] [-p <path> ...]] [-U <cache>] <dataset> "
144ed61ec1Yuri Pankov	    "[<object> ...]\n"
145ed61ec1Yuri Pankov	    "\t%s -C [-A] [-U <cache>]\n"
146ed61ec1Yuri Pankov	    "\t%s -l [-Aqu] <device>\n"
147dfd5965Richard Yao	    "\t%s -m [-AFLPX] [-e [-V] [-p <path> ...]] [-t <txg>] "
148dfd5965Richard Yao	    "[-U <cache>]\n\t\t<poolname> [<vdev> [<metaslab> ...]]\n"
149ed61ec1Yuri Pankov	    "\t%s -O <dataset> <path>\n"
150dfd5965Richard Yao	    "\t%s -R [-A] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
151ed61ec1Yuri Pankov	    "\t\t<poolname> <vdev>:<offset>:<size>[:<flags>]\n"
1524923c69Matthew Ahrens	    "\t%s -E [-A] word0:word1:...:word15\n"
153dfd5965Richard Yao	    "\t%s -S [-AP] [-e [-V] [-p <path> ...]] [-U <cache>] "
154dfd5965Richard Yao	    "<poolname>\n\n",
155ed61ec1Yuri Pankov	    cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname,
1564923c69Matthew Ahrens	    cmdname, cmdname);
1573ad6c7fVictor Latushkin
1583ad6c7fVictor Latushkin	(void) fprintf(stderr, "    Dataset name must include at least one "
1593ad6c7fVictor Latushkin	    "separator character '/' or '@'\n");
1603ad6c7fVictor Latushkin	(void) fprintf(stderr, "    If dataset name is specified, only that "
1613ad6c7fVictor Latushkin	    "dataset is dumped\n");
1623ad6c7fVictor Latushkin	(void) fprintf(stderr, "    If object numbers are specified, only "
1633ad6c7fVictor Latushkin	    "those objects are dumped\n\n");
1643ad6c7fVictor Latushkin	(void) fprintf(stderr, "    Options to control amount of output:\n");
1653ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -b block statistics\n");
1663ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -c checksum all metadata (twice for "
1676365109Victor Latushkin	    "all data) blocks\n");
168ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -C config (or cachefile if alone)\n");
169ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -d dataset(s)\n");
170f0ba89bJeff Bonwick	(void) fprintf(stderr, "        -D dedup statistics\n");
1714923c69Matthew Ahrens	(void) fprintf(stderr, "        -E decode and display block from an "
1724923c69Matthew Ahrens	    "embedded block pointer\n");
173ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -h pool history\n");
174ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -i intent logs\n");
17564723e3Yuri Pankov	(void) fprintf(stderr, "        -l read label contents\n");
1768671400Serapheim Dimitropoulos	(void) fprintf(stderr, "        -k examine the checkpointed state "
1778671400Serapheim Dimitropoulos	    "of the pool\n");
17882a0a98Victor Latushkin	(void) fprintf(stderr, "        -L disable leak tracking (do not "
17982a0a98Victor Latushkin	    "load spacemaps)\n");
180ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -m metaslabs\n");
181ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -M metaslab groups\n");
182ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -O perform object lookups by path\n");
183d41e764ek	(void) fprintf(stderr, "        -R read and display block from a "
184ed61ec1Yuri Pankov	    "device\n");
185ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -s report stats on zdb's I/O\n");
186ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -S simulate dedup to measure effect\n");
187ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -v verbose (applies to all "
188ed61ec1Yuri Pankov	    "others)\n\n");
1893ad6c7fVictor Latushkin	(void) fprintf(stderr, "    Below options are intended for use "
190df15e41Matthew Ahrens	    "with other options:\n");
191feef89cVictor Latushkin	(void) fprintf(stderr, "        -A ignore assertions (-A), enable "
192feef89cVictor Latushkin	    "panic recovery (-AA) or both (-AAA)\n");
1933ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -e pool is exported/destroyed/"
1943ad6c7fVictor Latushkin	    "has altroot/not in a cachefile\n");
195ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -F attempt automatic rewind within "
196ed61ec1Yuri Pankov	    "safe range of transaction groups\n");
197ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -G dump zfs_dbgmsg buffer before "
198ed61ec1Yuri Pankov	    "exiting\n");
1992e4c998George Wilson	(void) fprintf(stderr, "        -I <number of inflight I/Os> -- "
200df15e41Matthew Ahrens	    "specify the maximum number of "
201df15e41Matthew Ahrens	    "checksumming I/Os [default is 200]\n");
2020e60744Pavel Zakharov	(void) fprintf(stderr, "        -o <variable>=<value> set global "
2030e60744Pavel Zakharov	    "variable to an unsigned 32-bit integer value\n");
204ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -p <path> -- use one or more with "
205ed61ec1Yuri Pankov	    "-e to specify path to vdev dir\n");
206ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -P print numbers in parseable form\n");
20764723e3Yuri Pankov	(void) fprintf(stderr, "        -q don't print label contents\n");
208ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -t <txg> -- highest txg to use when "
209ed61ec1Yuri Pankov	    "searching for uberblocks\n");
21064723e3Yuri Pankov	(void) fprintf(stderr, "        -u uberblock\n");
211ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -U <cachefile_path> -- use alternate "
212ed61ec1Yuri Pankov	    "cachefile\n");
213dfd5965Richard Yao	(void) fprintf(stderr, "        -V do verbatim import\n");
214ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -x <dumpdir> -- "
215ed61ec1Yuri Pankov	    "dump all read blocks into specified directory\n");
216ed61ec1Yuri Pankov	(void) fprintf(stderr, "        -X attempt extreme rewind (does not "
217ed61ec1Yuri Pankov	    "work with dataset)\n\n");
218fa9e406ahrens	(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
219fa9e406ahrens	    "to make only that option verbose\n");
220fa9e406ahrens	(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
221fa9e406ahrens	exit(1);
222fa9e406ahrens}
223fa9e406ahrens
22429bdd2fPavel Zakharovstatic void
22529bdd2fPavel Zakharovdump_debug_buffer()
22629bdd2fPavel Zakharov{
22729bdd2fPavel Zakharov	if (dump_opt['G']) {
22829bdd2fPavel Zakharov		(void) printf("\n");
22929bdd2fPavel Zakharov		zfs_dbgmsg_print("zdb");
23029bdd2fPavel Zakharov	}
23129bdd2fPavel Zakharov}
23229bdd2fPavel Zakharov
233ccba080Rich Morris/*
234ccba080Rich Morris * Called for usage errors that are discovered after a call to spa_open(),
235ccba080Rich Morris * dmu_bonus_hold(), or pool_match().  abort() is called for other errors.
236ccba080Rich Morris */
237ccba080Rich Morris
238fa9e406ahrensstatic void
239fa9e406ahrensfatal(const char *fmt, ...)
240fa9e406ahrens{
241fa9e406ahrens	va_list ap;
242fa9e406ahrens
243fa9e406ahrens	va_start(ap, fmt);
244fa9e406ahrens	(void) fprintf(stderr, "%s: ", cmdname);
245fa9e406ahrens	(void) vfprintf(stderr, fmt, ap);
246fa9e406ahrens	va_end(ap);
247fa9e406ahrens	(void) fprintf(stderr, "\n");
248fa9e406ahrens
24929bdd2fPavel Zakharov	dump_debug_buffer();
25029bdd2fPavel Zakharov
251ccba080Rich Morris	exit(1);
252fa9e406ahrens}
253fa9e406ahrens
254fa9e406ahrens/* ARGSUSED */
255fa9e406ahrensstatic void
256fa9e406ahrensdump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
257fa9e406ahrens{
258fa9e406ahrens	nvlist_t *nv;
259fa9e406ahrens	size_t nvsize = *(uint64_t *)data;
260fa9e406ahrens	char *packed = umem_alloc(nvsize, UMEM_NOFAIL);
261fa9e406ahrens
2627bfdf01Neil Perrin	VERIFY(0 == dmu_read(os, object, 0, nvsize, packed, DMU_READ_PREFETCH));
263fa9e406ahrens
264fa9e406ahrens	VERIFY(nvlist_unpack(packed, nvsize, &nv, 0) == 0);
265fa9e406ahrens
266fa9e406ahrens	umem_free(packed, nvsize);
267fa9e406ahrens
268fa9e406ahrens	dump_nvlist(nv, 8);
269fa9e406ahrens
270fa9e406ahrens	nvlist_free(nv);
271fa9e406ahrens}
272fa9e406ahrens
2734445fffMatthew Ahrens/* ARGSUSED */
2744445fffMatthew Ahrensstatic void
2754445fffMatthew Ahrensdump_history_offsets(objset_t *os, uint64_t object, void *data, size_t size)
2764445fffMatthew Ahrens{
2774445fffMatthew Ahrens	spa_history_phys_t *shp = data;
2784445fffMatthew Ahrens
2794445fffMatthew Ahrens	if (shp == NULL)
2804445fffMatthew Ahrens		return;
2814445fffMatthew Ahrens
2824445fffMatthew Ahrens	(void) printf("\t\tpool_create_len = %llu\n",
2834445fffMatthew Ahrens	    (u_longlong_t)shp->sh_pool_create_len);
2844445fffMatthew Ahrens	(void) printf("\t\tphys_max_off = %llu\n",
2854445fffMatthew Ahrens	    (u_longlong_t)shp->sh_phys_max_off);
2864445fffMatthew Ahrens	(void) printf("\t\tbof = %llu\n",
2874445fffMatthew Ahrens	    (u_longlong_t)shp->sh_bof);
2884445fffMatthew Ahrens	(void) printf("\t\teof = %llu\n",
2894445fffMatthew Ahrens	    (u_longlong_t)shp->sh_eof);
2904445fffMatthew Ahrens	(void) printf("\t\trecords_lost = %llu\n",
2914445fffMatthew Ahrens	    (u_longlong_t)shp->sh_records_lost);
2924445fffMatthew Ahrens}
2934445fffMatthew Ahrens
2943f9d6adLin Lingstatic void
2950a05512Jason Kingzdb_nicenum(uint64_t num, char *buf, size_t buflen)
2963f9d6adLin Ling{
2973f9d6adLin Ling	if (dump_opt['P'])
2980a05512Jason King		(void) snprintf(buf, buflen, "%llu", (longlong_t)num);
2993f9d6adLin Ling	else
3000a05512Jason King		nicenum(num, buf, sizeof (buf));
3013f9d6adLin Ling}
3023f9d6adLin Ling
3033f7978dAlan Somersstatic const char histo_stars[] = "****************************************";
3043f7978dAlan Somersstatic const uint64_t histo_width = sizeof (histo_stars) - 1;
305fa9e406ahrens
306fa9e406ahrensstatic void
3070713e23George Wilsondump_histogram(const uint64_t *histo, int size, int offset)
308fa9e406ahrens{
309fa9e406ahrens	int i;
310490d05bMatthew Ahrens	int minidx = size - 1;
311fa9e406ahrens	int maxidx = 0;
312fa9e406ahrens	uint64_t max = 0;
313fa9e406ahrens
314490d05bMatthew Ahrens	for (i = 0; i < size; i++) {
315fa9e406ahrens		if (histo[i] > max)
316fa9e406ahrens			max = histo[i];
317fa9e406ahrens		if (histo[i] > 0 && i > maxidx)
318fa9e406ahrens			maxidx = i;
319fa9e406ahrens		if (histo[i] > 0 && i < minidx)
320fa9e406ahrens			minidx = i;
321fa9e406ahrens	}
322fa9e406ahrens
323490d05bMatthew Ahrens	if (max < histo_width)
324490d05bMatthew Ahrens		max = histo_width;
325fa9e406ahrens
326490d05bMatthew Ahrens	for (i = minidx; i <= maxidx; i++) {
327490d05bMatthew Ahrens		(void) printf("\t\t\t%3u: %6llu %s\n",
3280713e23George Wilson		    i + offset, (u_longlong_t)histo[i],
329490d05bMatthew Ahrens		    &histo_stars[(max - histo[i]) * histo_width / max]);
330490d05bMatthew Ahrens	}
331fa9e406ahrens}
332fa9e406ahrens
333fa9e406ahrensstatic void
334fa9e406ahrensdump_zap_stats(objset_t *os, uint64_t object)
335fa9e406ahrens{
336fa9e406ahrens	int error;
337fa9e406ahrens	zap_stats_t zs;
338fa9e406ahrens
339fa9e406ahrens	error = zap_get_stats(os, object, &zs);
340fa9e406ahrens	if (error)
341fa9e406ahrens		return;
342fa9e406ahrens
343fa9e406ahrens	if (zs.zs_ptrtbl_len == 0) {
344fa9e406ahrens		ASSERT(zs.zs_num_blocks == 1);
345fa9e406ahrens		(void) printf("\tmicrozap: %llu bytes, %llu entries\n",
346fa9e406ahrens		    (u_longlong_t)zs.zs_blocksize,
347fa9e406ahrens		    (u_longlong_t)zs.zs_num_entries);
348fa9e406ahrens		return;
349fa9e406ahrens	}
350fa9e406ahrens
351fa9e406ahrens	(void) printf("\tFat ZAP stats:\n");
3528248818nd
3538248818nd	(void) printf("\t\tPointer table:\n");
3548248818nd	(void) printf("\t\t\t%llu elements\n",
355fa9e406ahrens	    (u_longlong_t)zs.zs_ptrtbl_len);
3568248818nd	(void) printf("\t\t\tzt_blk: %llu\n",
3578248818nd	    (u_longlong_t)zs.zs_ptrtbl_zt_blk);
3588248818nd	(void) printf("\t\t\tzt_numblks: %llu\n",
3598248818nd	    (u_longlong_t)zs.zs_ptrtbl_zt_numblks);
3608248818nd	(void) printf("\t\t\tzt_shift: %llu\n",
3618248818nd	    (u_longlong_t)zs.zs_ptrtbl_zt_shift);
3628248818nd	(void) printf("\t\t\tzt_blks_copied: %llu\n",
3638248818nd	    (u_longlong_t)zs.zs_ptrtbl_blks_copied);
3648248818nd	(void) printf("\t\t\tzt_nextblk: %llu\n",
3658248818nd	    (u_longlong_t)zs.zs_ptrtbl_nextblk);
3668248818nd
367fa9e406ahrens	(void) printf("\t\tZAP entries: %llu\n",
368fa9e406ahrens	    (u_longlong_t)zs.zs_num_entries);
369fa9e406ahrens	(void) printf("\t\tLeaf blocks: %llu\n",
370fa9e406ahrens	    (u_longlong_t)zs.zs_num_leafs);
371fa9e406ahrens	(void) printf("\t\tTotal blocks: %llu\n",
372fa9e406ahrens	    (u_longlong_t)zs.zs_num_blocks);
3738248818nd	(void) printf("\t\tzap_block_type: 0x%llx\n",
3748248818nd	    (u_longlong_t)zs.zs_block_type);
3758248818nd	(void) printf("\t\tzap_magic: 0x%llx\n",
3768248818nd	    (u_longlong_t)zs.zs_magic);
3778248818nd	(void) printf("\t\tzap_salt: 0x%llx\n",
3788248818nd	    (u_longlong_t)zs.zs_salt);
379fa9e406ahrens
380fa9e406ahrens	(void) printf("\t\tLeafs with 2^n pointers:\n");
3810713e23George Wilson	dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE, 0);
382fa9e406ahrens
383fa9e406ahrens	(void) printf("\t\tBlocks with n*5 entries:\n");
3840713e23George Wilson	dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE, 0);
385fa9e406ahrens
386fa9e406ahrens	(void) printf("\t\tBlocks n/10 full:\n");
3870713e23George Wilson	dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE, 0);
388fa9e406ahrens
389fa9e406ahrens	(void) printf("\t\tEntries with n chunks:\n");
3900713e23George Wilson	dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE, 0);
391fa9e406ahrens
392fa9e406ahrens	(void) printf("\t\tBuckets with n entries:\n");
3930713e23George Wilson	dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE, 0);
394fa9e406ahrens}
395fa9e406ahrens
396fa9e406ahrens/*ARGSUSED*/
397fa9e406ahrensstatic void
398fa9e406ahrensdump_none(objset_t *os, uint64_t object, void *data, size_t size)
399fa9e406ahrens{
400fa9e406ahrens}
401fa9e406ahrens
402fa9e406ahrens/*ARGSUSED*/
4036de8f41Victor Latushkinstatic void
4046de8f41Victor Latushkindump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
4056de8f41Victor Latushkin{
4066de8f41Victor Latushkin	(void) printf("\tUNKNOWN OBJECT TYPE\n");
4076de8f41Victor Latushkin}
4086de8f41Victor Latushkin
4096de8f41Victor Latushkin/*ARGSUSED*/
4103f7978dAlan Somersstatic void
411fa9e406ahrensdump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
412fa9e406ahrens{
413fa9e406ahrens}
414fa9e406ahrens
415fa9e406ahrens/*ARGSUSED*/
416fa9e406ahrensstatic void
417fa9e406ahrensdump_uint64(objset_t *os, uint64_t object, void *data, size_t size)
418fa9e406ahrens{
419fa9e406ahrens}
420fa9e406ahrens
421fa9e406ahrens/*ARGSUSED*/
422fa9e406ahrensstatic void
423fa9e406ahrensdump_zap(objset_t *os, uint64_t object, void *data, size_t size)
424fa9e406ahrens{
425fa9e406ahrens	zap_cursor_t zc;
426fa9e406ahrens	zap_attribute_t attr;
427fa9e406ahrens	void *prop;
4283f7978dAlan Somers	unsigned i;
429fa9e406ahrens
430fa9e406ahrens	dump_zap_stats(os, object);
431fa9e406ahrens	(void) printf("\n");
432fa9e406ahrens
433fa9e406ahrens	for (zap_cursor_init(&zc, os, object);
434fa9e406ahrens	    zap_cursor_retrieve(&zc, &attr) == 0;
435fa9e406ahrens	    zap_cursor_advance(&zc)) {
436fa9e406ahrens		(void) printf("\t\t%s = ", attr.za_name);
437fa9e406ahrens		if (attr.za_num_integers == 0) {
438fa9e406ahrens			(void) printf("\n");
439fa9e406ahrens			continue;
440fa9e406ahrens		}
441fa9e406ahrens		prop = umem_zalloc(attr.za_num_integers *
442fa9e406ahrens		    attr.za_integer_length, UMEM_NOFAIL);
443fa9e406ahrens		(void) zap_lookup(os, object, attr.za_name,
444fa9e406ahrens		    attr.za_integer_length, attr.za_num_integers, prop);
445fa9e406ahrens		if (attr.za_integer_length == 1) {
446fa9e406ahrens			(void) printf("%s", (char *)prop);
447fa9e406ahrens		} else {
448fa9e406ahrens			for (i = 0; i < attr.za_num_integers; i++) {
449fa9e406ahrens				switch (attr.za_integer_length) {
450fa9e406ahrens				case 2:
451fa9e406ahrens					(void) printf("%u ",
452fa9e406ahrens					    ((uint16_t *)prop)[i]);
453fa9e406ahrens					break;
454fa9e406ahrens				case 4:
455fa9e406ahrens					(void) printf("%u ",
456fa9e406ahrens					    ((uint32_t *)prop)[i]);
457fa9e406ahrens					break;
458fa9e406ahrens				case 8:
459fa9e406ahrens					(void) printf("%lld ",
460fa9e406ahrens					    (u_longlong_t)((int64_t *)prop)[i]);
461fa9e406ahrens					break;
462fa9e406ahrens				}
463fa9e406ahrens			}
464fa9e406ahrens		}
465fa9e406ahrens		(void) printf("\n");
466fa9e406ahrens		umem_free(prop, attr.za_num_integers * attr.za_integer_length);
467fa9e406ahrens	}
46887e5029ahrens	zap_cursor_fini(&zc);
469fa9e406ahrens}
470fa9e406ahrens
471732885fMatthew Ahrensstatic void
472732885fMatthew Ahrensdump_bpobj(objset_t *os, uint64_t object, void *data, size_t size)
473732885fMatthew Ahrens{
474732885fMatthew Ahrens	bpobj_phys_t *bpop = data;
475732885fMatthew Ahrens	char bytes[32], comp[32], uncomp[32];
476732885fMatthew Ahrens
4770a05512Jason King	/* make sure the output won't get truncated */
4780a05512Jason King	CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ);
4790a05512Jason King	CTASSERT(sizeof (comp) >= NN_NUMBUF_SZ);
4800a05512Jason King	CTASSERT(sizeof (uncomp) >= NN_NUMBUF_SZ);
4810a05512Jason King
482732885fMatthew Ahrens	if (bpop == NULL)
483732885fMatthew Ahrens		return;
484732885fMatthew Ahrens
4850a05512Jason King	zdb_nicenum(bpop->bpo_bytes, bytes, sizeof (bytes));
4860a05512Jason King	zdb_nicenum(bpop->bpo_comp, comp, sizeof (comp));
4870a05512Jason King	zdb_nicenum(bpop->bpo_uncomp, uncomp, sizeof (uncomp));
488732885fMatthew Ahrens
489732885fMatthew Ahrens	(void) printf("\t\tnum_blkptrs = %llu\n",
490732885fMatthew Ahrens	    (u_longlong_t)bpop->bpo_num_blkptrs);
491732885fMatthew Ahrens	(void) printf("\t\tbytes = %s\n", bytes);
492732885fMatthew Ahrens	if (size >= BPOBJ_SIZE_V1) {
493732885fMatthew Ahrens		(void) printf("\t\tcomp = %s\n", comp);
494732885fMatthew Ahrens		(void) printf("\t\tuncomp = %s\n", uncomp);
495732885fMatthew Ahrens	}
496732885fMatthew Ahrens	if (size >= sizeof (*bpop)) {
497732885fMatthew Ahrens		(void) printf("\t\tsubobjs = %llu\n",
498732885fMatthew Ahrens		    (u_longlong_t)bpop->bpo_subobjs);
499732885fMatthew Ahrens		(void) printf("\t\tnum_subobjs = %llu\n",
500732885fMatthew Ahrens		    (u_longlong_t)bpop->bpo_num_subobjs);
501732885fMatthew Ahrens	}
502732885fMatthew Ahrens
503732885fMatthew Ahrens	if (dump_opt['d'] < 5)
504732885fMatthew Ahrens		return;
505732885fMatthew Ahrens
506732885fMatthew Ahrens	for (uint64_t i = 0; i < bpop->bpo_num_blkptrs; i++) {
507732885fMatthew Ahrens		char blkbuf[BP_SPRINTF_LEN];
508732885fMatthew Ahrens		blkptr_t bp;
509732885fMatthew Ahrens
510732885fMatthew Ahrens		int err = dmu_read(os, object,
511732885fMatthew Ahrens		    i * sizeof (bp), sizeof (bp), &bp, 0);
512732885fMatthew Ahrens		if (err != 0) {
513732885fMatthew Ahrens			(void) printf("got error %u from dmu_read\n", err);
514732885fMatthew Ahrens			break;
515732885fMatthew Ahrens		}
516732885fMatthew Ahrens		snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), &bp);
517732885fMatthew Ahrens		(void) printf("\t%s\n", blkbuf);
518732885fMatthew Ahrens	}
519732885fMatthew Ahrens}
520732885fMatthew Ahrens
521732885fMatthew Ahrens/* ARGSUSED */
522732885fMatthew Ahrensstatic void
523732885fMatthew Ahrensdump_bpobj_subobjs(objset_t *os, uint64_t object, void *data, size_t size)
524732885fMatthew Ahrens{
525732885fMatthew Ahrens	dmu_object_info_t doi;
526732885fMatthew Ahrens
527732885fMatthew Ahrens	VERIFY0(dmu_object_info(os, object, &doi));
528732885fMatthew Ahrens	uint64_t *subobjs = kmem_alloc(doi.doi_max_offset, KM_SLEEP);
529732885fMatthew Ahrens
530732885fMatthew Ahrens	int err = dmu_read(os, object, 0, doi.doi_max_offset, subobjs, 0);
531732885fMatthew Ahrens	if (err != 0) {
532732885fMatthew Ahrens		(void) printf("got error %u from dmu_read\n", err);
533732885fMatthew Ahrens		kmem_free(subobjs, doi.doi_max_offset);
534732885fMatthew Ahrens		return;
535732885fMatthew Ahrens	}
536732885fMatthew Ahrens
537732885fMatthew Ahrens	int64_t last_nonzero = -1;
538732885fMatthew Ahrens	for (uint64_t i = 0; i < doi.doi_max_offset / 8; i++) {
539732885fMatthew Ahrens		if (subobjs[i] != 0)
540732885fMatthew Ahrens			last_nonzero = i;
541732885fMatthew Ahrens	}
542732885fMatthew Ahrens
543732885fMatthew Ahrens	for (int64_t i = 0; i <= last_nonzero; i++) {
544732885fMatthew Ahrens		(void) printf("\t%llu\n", (longlong_t)subobjs[i]);
545732885fMatthew Ahrens	}
546732885fMatthew Ahrens	kmem_free(subobjs, doi.doi_max_offset);
547732885fMatthew Ahrens}
548732885fMatthew Ahrens
549e743726ahrens/*ARGSUSED*/
550e743726ahrensstatic void
551486ae71Matthew Ahrensdump_ddt_zap(objset_t *os, uint64_t object, void *data, size_t size)
552486ae71Matthew Ahrens{
553486ae71Matthew Ahrens	dump_zap_stats(os, object);
554486ae71Matthew Ahrens	/* contents are printed elsewhere, properly decoded */
555486ae71Matthew Ahrens}
556486ae71Matthew Ahrens
557486ae71Matthew Ahrens/*ARGSUSED*/
558486ae71Matthew Ahrensstatic void
5590a586ceMark Shellenbaumdump_sa_attrs(objset_t *os, uint64_t object, void *data, size_t size)
5600a586ceMark Shellenbaum{
5610a586ceMark Shellenbaum	zap_cursor_t zc;
5620a586ceMark Shellenbaum	zap_attribute_t attr;
5630a586ceMark Shellenbaum
5640a586ceMark Shellenbaum	dump_zap_stats(os, object);
5650a586ceMark Shellenbaum	(void) printf("\n");
5660a586ceMark Shellenbaum
5670a586ceMark Shellenbaum	for (zap_cursor_init(&zc, os, object);
5680a586ceMark Shellenbaum	    zap_cursor_retrieve(&zc, &attr) == 0;
5690a586ceMark Shellenbaum	    zap_cursor_advance(&zc)) {
5700a586ceMark Shellenbaum		(void) printf("\t\t%s = ", attr.za_name);
5710a586ceMark Shellenbaum		if (attr.za_num_integers == 0) {
5720a586ceMark Shellenbaum			(void) printf("\n");
5730a586ceMark Shellenbaum			continue;
5740a586ceMark Shellenbaum		}
5750a586ceMark Shellenbaum		(void) printf(" %llx : [%d:%d:%d]\n",
5760a586ceMark Shellenbaum		    (u_longlong_t)attr.za_first_integer,
5770a586ceMark Shellenbaum		    (int)ATTR_LENGTH(attr.za_first_integer),
5780a586ceMark Shellenbaum		    (int)ATTR_BSWAP(attr.za_first_integer),
5790a586ceMark Shellenbaum		    (int)ATTR_NUM(attr.za_first_integer));
5800a586ceMark Shellenbaum	}
5810a586ceMark Shellenbaum	zap_cursor_fini(&zc);
5820a586ceMark Shellenbaum}
5830a586ceMark Shellenbaum
5840a586ceMark Shellenbaum/*ARGSUSED*/
5850a586ceMark Shellenbaumstatic void
5860a586ceMark Shellenbaumdump_sa_layouts(objset_t *os, uint64_t object, void *data, size_t size)
5870a586ceMark Shellenbaum{
5880a586ceMark Shellenbaum	zap_cursor_t zc;
5890a586ceMark Shellenbaum	zap_attribute_t attr;
5900a586ceMark Shellenbaum	uint16_t *layout_attrs;
5913f7978dAlan Somers	unsigned i;
5920a586ceMark Shellenbaum
5930a586ceMark Shellenbaum	dump_zap_stats(os, object);
5940a586ceMark Shellenbaum	(void) printf("\n");
5950a586ceMark Shellenbaum
5960a586ceMark Shellenbaum	for (zap_cursor_init(&zc, os, object);
5970a586ceMark Shellenbaum	    zap_cursor_retrieve(&zc, &attr) == 0;
5980a586ceMark Shellenbaum	    zap_cursor_advance(&zc)) {
5990a586ceMark Shellenbaum		(void) printf("\t\t%s = [", attr.za_name);
6000a586ceMark Shellenbaum		if (attr.za_num_integers == 0) {
6010a586ceMark Shellenbaum			(void) printf("\n");
6020a586ceMark Shellenbaum			continue;
6030a586ceMark Shellenbaum		}
6040a586ceMark Shellenbaum
6050a586ceMark Shellenbaum		VERIFY(attr.za_integer_length == 2);
6060a586ceMark Shellenbaum		layout_attrs = umem_zalloc(attr.za_num_integers *
6070a586ceMark Shellenbaum		    attr.za_integer_length, UMEM_NOFAIL);
6080a586ceMark Shellenbaum
6090a586ceMark Shellenbaum		VERIFY(zap_lookup(os, object, attr.za_name,
6100a586ceMark Shellenbaum		    attr.za_integer_length,
6110a586ceMark Shellenbaum		    attr.za_num_integers, layout_attrs) == 0);
6120a586ceMark Shellenbaum
6130a586ceMark Shellenbaum		for (i = 0; i != attr.za_num_integers; i++)
6140a586ceMark Shellenbaum			(void) printf(" %d ", (int)layout_attrs[i]);
6150a586ceMark Shellenbaum		(void) printf("]\n");
6160a586ceMark Shellenbaum		umem_free(layout_attrs,
6170a586ceMark Shellenbaum		    attr.za_num_integers * attr.za_integer_length);
6180a586ceMark Shellenbaum	}
6190a586ceMark Shellenbaum	zap_cursor_fini(&zc);
6200a586ceMark Shellenbaum}
6210a586ceMark Shellenbaum
6220a586ceMark Shellenbaum/*ARGSUSED*/
6230a586ceMark Shellenbaumstatic void
624e743726ahrensdump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
625e743726ahrens{
626e743726ahrens	zap_cursor_t zc;
627e743726ahrens	zap_attribute_t attr;
628e743726ahrens	const char *typenames[] = {
629e743726ahrens		/* 0 */ "not specified",
630e743726ahrens		/* 1 */ "FIFO",
631e743726ahrens		/* 2 */ "Character Device",
632e743726ahrens		/* 3 */ "3 (invalid)",
633e743726ahrens		/* 4 */ "Directory",
634e743726ahrens		/* 5 */ "5 (invalid)",
635e743726ahrens		/* 6 */ "Block Device",
636e743726ahrens		/* 7 */ "7 (invalid)",
637e743726ahrens		/* 8 */ "Regular File",
638e743726ahrens		/* 9 */ "9 (invalid)",
639e743726ahrens		/* 10 */ "Symbolic Link",
640e743726ahrens		/* 11 */ "11 (invalid)",
641e743726ahrens		/* 12 */ "Socket",
642e743726ahrens		/* 13 */ "Door",
643e743726ahrens		/* 14 */ "Event Port",
644e743726ahrens		/* 15 */ "15 (invalid)",
645e743726ahrens	};
646e743726ahrens
647e743726ahrens	dump_zap_stats(os, object);
648e743726ahrens	(void) printf("\n");
649e743726ahrens
650e743726ahrens	for (zap_cursor_init(&zc, os, object);
651e743726ahrens	    zap_cursor_retrieve(&zc, &attr) == 0;
652e743726ahrens	    zap_cursor_advance(&zc)) {
653e743726ahrens		(void) printf("\t\t%s = %lld (type: %s)\n",
654e743726ahrens		    attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
655e743726ahrens		    typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
656e743726ahrens	}
657e743726ahrens	zap_cursor_fini(&zc);
658e743726ahrens}
659e743726ahrens
6603f7978dAlan Somersstatic int
6610713e23George Wilsonget_dtl_refcount(vdev_t *vd)
6620713e23George Wilson{
6630713e23George Wilson	int refcount = 0;
6640713e23George Wilson
6650713e23George Wilson	if (vd->vdev_ops->vdev_op_leaf) {
6660713e23George Wilson		space_map_t *sm = vd->vdev_dtl_sm;
6670713e23George Wilson
6680713e23George Wilson		if (sm != NULL &&
6690713e23George Wilson		    sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
6700713e23George Wilson			return (1);
6710713e23George Wilson		return (0);
6720713e23George Wilson	}
6730713e23George Wilson
6743f7978dAlan Somers	for (unsigned c = 0; c < vd->vdev_children; c++)
6750713e23George Wilson		refcount += get_dtl_refcount(vd->vdev_child[c]);
6760713e23George Wilson	return (refcount);
6770713e23George Wilson}
6780713e23George Wilson
6793f7978dAlan Somersstatic int
6800713e23George Wilsonget_metaslab_refcount(vdev_t *vd)
6810713e23George Wilson{
6820713e23George Wilson	int refcount = 0;
6830713e23George Wilson
6845cabbc6Prashanth Sreenivasa	if (vd->vdev_top == vd) {
6855cabbc6Prashanth Sreenivasa		for (uint64_t m = 0; m < vd->vdev_ms_count; m++) {
6860713e23George Wilson			space_map_t *sm = vd->vdev_ms[m]->ms_sm;
6870713e23George Wilson
6880713e23George Wilson			if (sm != NULL &&
6890713e23George Wilson			    sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
6900713e23George Wilson				refcount++;
6910713e23George Wilson		}
6920713e23George Wilson	}
6933f7978dAlan Somers	for (unsigned c = 0; c < vd->vdev_children; c++)
6940713e23George Wilson		refcount += get_metaslab_refcount(vd->vdev_child[c]);
6950713e23George Wilson
6960713e23George Wilson	return (refcount);
6970713e23George Wilson}
6980713e23George Wilson
6990713e23George Wilsonstatic int
7005cabbc6Prashanth Sreenivasaget_obsolete_refcount(vdev_t *vd)
7015cabbc6Prashanth Sreenivasa{
7025cabbc6Prashanth Sreenivasa	int refcount = 0;
7035cabbc6Prashanth Sreenivasa
7045cabbc6Prashanth Sreenivasa	uint64_t obsolete_sm_obj = vdev_obsolete_sm_object(vd);
7055cabbc6Prashanth Sreenivasa	if (vd->vdev_top == vd && obsolete_sm_obj != 0) {
7065cabbc6Prashanth Sreenivasa		dmu_object_info_t doi;
7075cabbc6Prashanth Sreenivasa		VERIFY0(dmu_object_info(vd->vdev_spa->spa_meta_objset,
7085cabbc6Prashanth Sreenivasa		    obsolete_sm_obj, &doi));
7095cabbc6Prashanth Sreenivasa		if (doi.doi_bonus_size == sizeof (space_map_phys_t)) {
7105cabbc6Prashanth Sreenivasa			refcount++;
7115cabbc6Prashanth Sreenivasa		}
7125cabbc6Prashanth Sreenivasa	} else {
7135cabbc6Prashanth Sreenivasa		ASSERT3P(vd->vdev_obsolete_sm, ==, NULL);
7145cabbc6Prashanth Sreenivasa		ASSERT3U(obsolete_sm_obj, ==, 0);
7155cabbc6Prashanth Sreenivasa	}
7165cabbc6Prashanth Sreenivasa	for (unsigned c = 0; c < vd->vdev_children; c++) {
7175cabbc6Prashanth Sreenivasa		refcount += get_obsolete_refcount(vd->vdev_child[c]);
7185cabbc6Prashanth Sreenivasa	}
7195cabbc6Prashanth Sreenivasa
7205cabbc6Prashanth Sreenivasa	return (refcount);
7215cabbc6Prashanth Sreenivasa}
7225cabbc6Prashanth Sreenivasa
7235cabbc6Prashanth Sreenivasastatic int
7245cabbc6Prashanth Sreenivasaget_prev_obsolete_spacemap_refcount(spa_t *spa)
7255cabbc6Prashanth Sreenivasa{
7265cabbc6Prashanth Sreenivasa	uint64_t prev_obj =
7275cabbc6Prashanth Sreenivasa	    spa->spa_condensing_indirect_phys.scip_prev_obsolete_sm_object;
7285cabbc6Prashanth Sreenivasa	if (prev_obj != 0) {
7295cabbc6Prashanth Sreenivasa		dmu_object_info_t doi;
7305cabbc6Prashanth Sreenivasa		VERIFY0(dmu_object_info(spa->spa_meta_objset, prev_obj, &doi));
7315cabbc6Prashanth Sreenivasa		if (doi.doi_bonus_size == sizeof (space_map_phys_t)) {
7325cabbc6Prashanth Sreenivasa			return (1);
7335cabbc6Prashanth Sreenivasa		}
7345cabbc6Prashanth Sreenivasa	}
7355cabbc6Prashanth Sreenivasa	return (0);
7365cabbc6Prashanth Sreenivasa}
7375cabbc6Prashanth Sreenivasa
7385cabbc6Prashanth Sreenivasastatic int
7398671400Serapheim Dimitropoulosget_checkpoint_refcount(vdev_t *vd)
7408671400Serapheim Dimitropoulos{
7418671400Serapheim Dimitropoulos	int refcount = 0;
7428671400Serapheim Dimitropoulos
7438671400Serapheim Dimitropoulos	if (vd->vdev_top == vd && vd->vdev_top_zap != 0 &&
7448671400Serapheim Dimitropoulos	    zap_contains(spa_meta_objset(vd->vdev_spa),
7458671400Serapheim Dimitropoulos	    vd->vdev_top_zap, VDEV_TOP_ZAP_POOL_CHECKPOINT_SM) == 0)
7468671400Serapheim Dimitropoulos		refcount++;
7478671400Serapheim Dimitropoulos
7488671400Serapheim Dimitropoulos	for (uint64_t c = 0; c < vd->vdev_children; c++)
7498671400Serapheim Dimitropoulos		refcount += get_checkpoint_refcount(vd->vdev_child[c]);
7508671400Serapheim Dimitropoulos
7518671400Serapheim Dimitropoulos	return (refcount);
7528671400Serapheim Dimitropoulos}
7538671400Serapheim Dimitropoulos
7548671400Serapheim Dimitropoulosstatic int
7550713e23George Wilsonverify_spacemap_refcounts(spa_t *spa)
7560713e23George Wilson{
7572acef22Matthew Ahrens	uint64_t expected_refcount = 0;
7582acef22Matthew Ahrens	uint64_t actual_refcount;
7590713e23George Wilson
7602acef22Matthew Ahrens	(void) feature_get_refcount(spa,
7612acef22Matthew Ahrens	    &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM],
7622acef22Matthew Ahrens	    &expected_refcount);
7630713e23George Wilson	actual_refcount = get_dtl_refcount(spa->spa_root_vdev);
7640713e23George Wilson	actual_refcount += get_metaslab_refcount(spa->spa_root_vdev);
7655cabbc6Prashanth Sreenivasa	actual_refcount += get_obsolete_refcount(spa->spa_root_vdev);
7665cabbc6Prashanth Sreenivasa	actual_refcount += get_prev_obsolete_spacemap_refcount(spa);
7678671400Serapheim Dimitropoulos	actual_refcount += get_checkpoint_refcount(spa->spa_root_vdev);
7680713e23George Wilson
7690713e23George Wilson	if (expected_refcount != actual_refcount) {
7702acef22Matthew Ahrens		(void) printf("space map refcount mismatch: expected %lld != "
7712acef22Matthew Ahrens		    "actual %lld\n",
7722acef22Matthew Ahrens		    (longlong_t)expected_refcount,
7732acef22Matthew Ahrens		    (longlong_t)actual_refcount);
7740713e23George Wilson		return (2);
7750713e23George Wilson	}
7760713e23George Wilson	return (0);
7770713e23George Wilson}
7780713e23George Wilson
779fa9e406ahrensstatic void
7800713e23George Wilsondump_spacemap(objset_t *os, space_map_t *sm)
781fa9e406ahrens{
7825cabbc6Prashanth Sreenivasa	char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
7835cabbc6Prashanth Sreenivasa	    "INVALID", "INVALID", "INVALID", "INVALID" };
784fa9e406ahrens
7850713e23George Wilson	if (sm == NULL)
786fa9e406ahrens		return;
787fa9e406ahrens
7885cabbc6Prashanth Sreenivasa	(void) printf("space map object %llu:\n",
789555d674Serapheim Dimitropoulos	    (longlong_t)sm->sm_object);
790555d674Serapheim Dimitropoulos	(void) printf("  smp_length = 0x%llx\n",
791555d674Serapheim Dimitropoulos	    (longlong_t)sm->sm_phys->smp_length);
7925cabbc6Prashanth Sreenivasa	(void) printf("  smp_alloc = 0x%llx\n",
7935cabbc6Prashanth Sreenivasa	    (longlong_t)sm->sm_phys->smp_alloc);
7945cabbc6Prashanth Sreenivasa
795555d674Serapheim Dimitropoulos	if (dump_opt['d'] < 6 && dump_opt['m'] < 4)
796555d674Serapheim Dimitropoulos		return;
797555d674Serapheim Dimitropoulos
798fa9e406ahrens	/*
799fa9e406ahrens	 * Print out the freelist entries in both encoded and decoded form.
800fa9e406ahrens	 */
80117f1128Serapheim Dimitropoulos	uint8_t mapshift = sm->sm_shift;
80217f1128Serapheim Dimitropoulos	int64_t alloc = 0;
803555d674Serapheim Dimitropoulos	uint64_t word, entry_id = 0;
80417f1128Serapheim Dimitropoulos	for (uint64_t offset = 0; offset < space_map_length(sm);
80517f1128Serapheim Dimitropoulos	    offset += sizeof (word)) {
8060713e23George Wilson
8070713e23George Wilson		VERIFY0(dmu_read(os, space_map_object(sm), offset,
80817f1128Serapheim Dimitropoulos		    sizeof (word), &word, DMU_READ_PREFETCH));
8090713e23George Wilson
81017f1128Serapheim Dimitropoulos		if (sm_entry_is_debug(word)) {
811555d674Serapheim Dimitropoulos			(void) printf("\t    [%6llu] %s: txg %llu pass %llu\n",
812555d674Serapheim Dimitropoulos			    (u_longlong_t)entry_id,
81317f1128Serapheim Dimitropoulos			    ddata[SM_DEBUG_ACTION_DECODE(word)],
81417f1128Serapheim Dimitropoulos			    (u_longlong_t)SM_DEBUG_TXG_DECODE(word),
81517f1128Serapheim Dimitropoulos			    (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(word));
816555d674Serapheim Dimitropoulos			entry_id++;
81717f1128Serapheim Dimitropoulos			continue;
81817f1128Serapheim Dimitropoulos		}
81917f1128Serapheim Dimitropoulos
82017f1128Serapheim Dimitropoulos		uint8_t words;
82117f1128Serapheim Dimitropoulos		char entry_type;
82217f1128Serapheim Dimitropoulos		uint64_t entry_off, entry_run, entry_vdev = SM_NO_VDEVID;
82317f1128Serapheim Dimitropoulos
82417f1128Serapheim Dimitropoulos		if (sm_entry_is_single_word(word)) {
82517f1128Serapheim Dimitropoulos			entry_type = (SM_TYPE_DECODE(word) == SM_ALLOC) ?
82617f1128Serapheim Dimitropoulos			    'A' : 'F';
82717f1128Serapheim Dimitropoulos			entry_off = (SM_OFFSET_DECODE(word) << mapshift) +
82817f1128Serapheim Dimitropoulos			    sm->sm_start;
82917f1128Serapheim Dimitropoulos			entry_run = SM_RUN_DECODE(word) << mapshift;
83017f1128Serapheim Dimitropoulos			words = 1;
831fa9e406ahrens		} else {
83217f1128Serapheim Dimitropoulos			/* it is a two-word entry so we read another word */
83317f1128Serapheim Dimitropoulos			ASSERT(sm_entry_is_double_word(word));
83417f1128Serapheim Dimitropoulos
83517f1128Serapheim Dimitropoulos			uint64_t extra_word;
83617f1128Serapheim Dimitropoulos			offset += sizeof (extra_word);
83717f1128Serapheim Dimitropoulos			VERIFY0(dmu_read(os, space_map_object(sm), offset,
83817f1128Serapheim Dimitropoulos			    sizeof (extra_word), &extra_word,
83917f1128Serapheim Dimitropoulos			    DMU_READ_PREFETCH));
84017f1128Serapheim Dimitropoulos
84117f1128Serapheim Dimitropoulos			ASSERT3U(offset, <=, space_map_length(sm));
84217f1128Serapheim Dimitropoulos
84317f1128Serapheim Dimitropoulos			entry_run = SM2_RUN_DECODE(word) << mapshift;
84417f1128Serapheim Dimitropoulos			entry_vdev = SM2_VDEV_DECODE(word);
84517f1128Serapheim Dimitropoulos			entry_type = (SM2_TYPE_DECODE(extra_word) == SM_ALLOC) ?
84617f1128Serapheim Dimitropoulos			    'A' : 'F';
84717f1128Serapheim Dimitropoulos			entry_off = (SM2_OFFSET_DECODE(extra_word) <<
84817f1128Serapheim Dimitropoulos			    mapshift) + sm->sm_start;
84917f1128Serapheim Dimitropoulos			words = 2;
850fa9e406ahrens		}
85117f1128Serapheim Dimitropoulos
85217f1128Serapheim Dimitropoulos		(void) printf("\t    [%6llu]    %c  range:"
85317f1128Serapheim Dimitropoulos		    " %010llx-%010llx  size: %06llx vdev: %06llu words: %u\n",
854555d674Serapheim Dimitropoulos		    (u_longlong_t)entry_id,
85517f1128Serapheim Dimitropoulos		    entry_type, (u_longlong_t)entry_off,
85617f1128Serapheim Dimitropoulos		    (u_longlong_t)(entry_off + entry_run),
85717f1128Serapheim Dimitropoulos		    (u_longlong_t)entry_run,
85817f1128Serapheim Dimitropoulos		    (u_longlong_t)entry_vdev, words);
85917f1128Serapheim Dimitropoulos
86017f1128Serapheim Dimitropoulos		if (entry_type == 'A')
86117f1128Serapheim Dimitropoulos			alloc += entry_run;
86217f1128Serapheim Dimitropoulos		else
86317f1128Serapheim Dimitropoulos			alloc -= entry_run;
864555d674Serapheim Dimitropoulos		entry_id++;
865fa9e406ahrens	}
866555d674Serapheim Dimitropoulos	if (alloc != space_map_allocated(sm)) {
86717f1128Serapheim Dimitropoulos		(void) printf("space_map_object alloc (%lld) INCONSISTENT "
86817f1128Serapheim Dimitropoulos		    "with space map summary (%lld)\n",
86917f1128Serapheim Dimitropoulos		    (longlong_t)space_map_allocated(sm), (longlong_t)alloc);
870fa9e406ahrens	}
871