xref: /illumos-gate/usr/src/cmd/zdb/zdb.c (revision f0a05239)
1fa9e4066Sahrens /*
2fa9e4066Sahrens  * CDDL HEADER START
3fa9e4066Sahrens  *
4fa9e4066Sahrens  * The contents of this file are subject to the terms of the
5ea8dc4b6Seschrock  * Common Development and Distribution License (the "License").
6ea8dc4b6Seschrock  * You may not use this file except in compliance with the License.
7fa9e4066Sahrens  *
8fa9e4066Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e4066Sahrens  * or http://www.opensolaris.org/os/licensing.
10fa9e4066Sahrens  * See the License for the specific language governing permissions
11fa9e4066Sahrens  * and limitations under the License.
12fa9e4066Sahrens  *
13fa9e4066Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14fa9e4066Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e4066Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16fa9e4066Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e4066Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e4066Sahrens  *
19fa9e4066Sahrens  * CDDL HEADER END
20fa9e4066Sahrens  */
21ad135b5dSChristopher Siden 
22fa9e4066Sahrens /*
238f2529deSMark Shellenbaum  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24af1d63abSPaul Dagnelie  * Copyright (c) 2011, 2019 by Delphix. All rights reserved.
25c3d26abcSMatthew Ahrens  * Copyright (c) 2014 Integros [integros.com]
26ed61ec1dSYuri Pankov  * Copyright 2017 Nexenta Systems, Inc.
27e0f1c0afSOlaf Faaland  * Copyright (c) 2017, 2018 Lawrence Livermore National Security, LLC.
28f06dce2cSAndrew Stormont  * Copyright 2017 RackTop Systems.
29fa9e4066Sahrens  */
31fa9e4066Sahrens #include <stdio.h>
32490d05b9SMatthew Ahrens #include <unistd.h>
33004388ebScasper #include <stdio_ext.h>
34fa9e4066Sahrens #include <stdlib.h>
3544cd46caSbillm #include <ctype.h>
36fa9e4066Sahrens #include <sys/zfs_context.h>
37fa9e4066Sahrens #include <sys/spa.h>
38fa9e4066Sahrens #include <sys/spa_impl.h>
39fa9e4066Sahrens #include <sys/dmu.h>
40fa9e4066Sahrens #include <sys/zap.h>
41fa9e4066Sahrens #include <sys/fs/zfs.h>
42fa9e4066Sahrens #include <sys/zfs_znode.h>
430a586ceaSMark Shellenbaum #include <sys/zfs_sa.h>
440a586ceaSMark Shellenbaum #include <sys/sa.h>
450a586ceaSMark Shellenbaum #include <sys/sa_impl.h>
46fa9e4066Sahrens #include <sys/vdev.h>
47fa9e4066Sahrens #include <sys/vdev_impl.h>
48fa9e4066Sahrens #include <sys/metaslab_impl.h>
49fa9e4066Sahrens #include <sys/dmu_objset.h>
50fa9e4066Sahrens #include <sys/dsl_dir.h>
51fa9e4066Sahrens #include <sys/dsl_dataset.h>
52fa9e4066Sahrens #include <sys/dsl_pool.h>
53fa9e4066Sahrens #include <sys/dbuf.h>
54fa9e4066Sahrens #include <sys/zil.h>
55fa9e4066Sahrens #include <sys/zil_impl.h>
56fa9e4066Sahrens #include <sys/stat.h>
57fa9e4066Sahrens #include <sys/resource.h>
58fa9e4066Sahrens #include <sys/dmu_traverse.h>
59fa9e4066Sahrens #include <sys/zio_checksum.h>
60fa9e4066Sahrens #include <sys/zio_compress.h>
61*f0a05239SGeorge Amanakis #include <zfs_fletcher.h>
62e0d35c44Smarks #include <sys/zfs_fuid.h>
6388b7b0f2SMatthew Ahrens #include <sys/arc.h>
64*f0a05239SGeorge Amanakis #include <sys/arc_impl.h>
65b24ab676SJeff Bonwick #include <sys/ddt.h>
66ad135b5dSChristopher Siden #include <sys/zfeature.h>
67770499e1SDan Kimmel #include <sys/abd.h>
684923c69fSMatthew Ahrens #include <sys/blkptr.h>
6917fb938fSMatthew Ahrens #include <sys/dsl_scan.h>
70eb633035STom Caputi #include <sys/dsl_crypt.h>
714445fffbSMatthew Ahrens #include <zfs_comutil.h>
720a055120SJason King #include <libcmdutils.h>
73de6628f0Sck #undef verify
74de6628f0Sck #include <libzfs.h>
76d8ab6e12SDon Brady #include <libnvpair.h>
77d8ab6e12SDon Brady #include <libzutil.h>
78d8ab6e12SDon Brady 
793f7978d0SAlan Somers #include "zdb.h"
803f7978d0SAlan Somers 
81e690fb27SChristopher Siden #define	ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ?	\
82e690fb27SChristopher Siden 	zio_compress_table[(idx)].ci_name : "UNKNOWN")
83e690fb27SChristopher Siden #define	ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ?	\
84e690fb27SChristopher Siden 	zio_checksum_table[(idx)].ci_name : "UNKNOWN")
85e690fb27SChristopher Siden #define	ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ?	\
86e690fb27SChristopher Siden 	dmu_ot[(idx)].ot_name : DMU_OT_IS_VALID(idx) ?	\
87e690fb27SChristopher Siden 	dmu_ot_byteswap[DMU_OT_BYTESWAP(idx)].ob_name : "UNKNOWN")
88e690fb27SChristopher Siden #define	ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) :		\
895cabbc6bSPrashanth Sreenivasa 	(idx) == DMU_OTN_ZAP_DATA || (idx) == DMU_OTN_ZAP_METADATA ?	\
905cabbc6bSPrashanth Sreenivasa 	DMU_OT_ZAP_OTHER : \
915cabbc6bSPrashanth Sreenivasa 	(idx) == DMU_OTN_UINT64_DATA || (idx) == DMU_OTN_UINT64_METADATA ? \
925cabbc6bSPrashanth Sreenivasa 	DMU_OT_UINT64_OTHER : DMU_OT_NUMTYPES)
936de8f417SVictor Latushkin 
944dd77f9eSMatthew Ahrens extern int reference_tracking_enable;
957fd05ac4SMatthew Ahrens extern boolean_t zfs_recover;
9606be9802SMatthew Ahrens extern uint64_t zfs_arc_max, zfs_arc_meta_limit;
97f7950bf1SMatthew Ahrens extern int zfs_vdev_async_read_max_active;
98f06dce2cSAndrew Stormont extern int aok;
99e144c4e6SPavel Zakharov extern boolean_t spa_load_verify_dryrun;
1004d7988d6SPaul Dagnelie extern int zfs_btree_verify_intensity;
101feef89cfSVictor Latushkin 
1023f7978d0SAlan Somers static const char cmdname[] = "zdb";
103fa9e4066Sahrens uint8_t dump_opt[256];
105fa9e4066Sahrens typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
107fa9e4066Sahrens uint64_t *zopt_object = NULL;
1083f7978d0SAlan Somers static unsigned zopt_objects = 0;
10906be9802SMatthew Ahrens uint64_t max_inflight = 1000;
11020b5dafbSPaul Dagnelie static int leaked_objects = 0;
112732885fcSMatthew Ahrens static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *);
11317fb938fSMatthew Ahrens static void mos_obj_refd(uint64_t);
114732885fcSMatthew Ahrens 
115fa9e4066Sahrens /*
116fa9e4066Sahrens  * These libumem hooks provide a reasonable set of defaults for the allocator's
117fa9e4066Sahrens  * debugging facilities.
118fa9e4066Sahrens  */
119fa9e4066Sahrens const char *
_umem_debug_init()120fa9e4066Sahrens _umem_debug_init()
121fa9e4066Sahrens {
122fa9e4066Sahrens 	return ("default,verbose"); /* $UMEM_DEBUG setting */
123fa9e4066Sahrens }
125fa9e4066Sahrens const char *
_umem_logging_init(void)126fa9e4066Sahrens _umem_logging_init(void)
127fa9e4066Sahrens {
128fa9e4066Sahrens 	return ("fail,contents"); /* $UMEM_LOGGING setting */
129fa9e4066Sahrens }
131fa9e4066Sahrens static void
usage(void)132fa9e4066Sahrens usage(void)
133fa9e4066Sahrens {
134fa9e4066Sahrens 	(void) fprintf(stderr,
13586714001SSerapheim Dimitropoulos 	    "Usage:\t%s [-AbcdDFGhikLMPsvX] [-e [-V] [-p <path> ...]] "
136ed61ec1dSYuri Pankov 	    "[-I <inflight I/Os>]\n"
137ed61ec1dSYuri Pankov 	    "\t\t[-o <var>=<value>]... [-t <txg>] [-U <cache>] [-x <dumpdir>]\n"
138ed61ec1dSYuri Pankov 	    "\t\t[<poolname> [<object> ...]]\n"
139dfd5965fSRichard Yao 	    "\t%s [-AdiPv] [-e [-V] [-p <path> ...]] [-U <cache>] <dataset> "
140ed61ec1dSYuri Pankov 	    "[<object> ...]\n"
141ed61ec1dSYuri Pankov 	    "\t%s -C [-A] [-U <cache>]\n"
142ed61ec1dSYuri Pankov 	    "\t%s -l [-Aqu] <device>\n"
143dfd5965fSRichard Yao 	    "\t%s -m [-AFLPX] [-e [-V] [-p <path> ...]] [-t <txg>] "
144dfd5965fSRichard Yao 	    "[-U <cache>]\n\t\t<poolname> [<vdev> [<metaslab> ...]]\n"
145ed61ec1dSYuri Pankov 	    "\t%s -O <dataset> <path>\n"
146dfd5965fSRichard Yao 	    "\t%s -R [-A] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
147ed61ec1dSYuri Pankov 	    "\t\t<poolname> <vdev>:<offset>:<size>[:<flags>]\n"
1484923c69fSMatthew Ahrens 	    "\t%s -E [-A] word0:word1:...:word15\n"
149dfd5965fSRichard Yao 	    "\t%s -S [-AP] [-e [-V] [-p <path> ...]] [-U <cache>] "
150dfd5965fSRichard Yao 	    "<poolname>\n\n",
151ed61ec1dSYuri Pankov 	    cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname,
1524923c69fSMatthew Ahrens 	    cmdname, cmdname);
1533ad6c7f9SVictor Latushkin 
1543ad6c7f9SVictor Latushkin 	(void) fprintf(stderr, "    Dataset name must include at least one "
1553ad6c7f9SVictor Latushkin 	    "separator character '/' or '@'\n");
1563ad6c7f9SVictor Latushkin 	(void) fprintf(stderr, "    If dataset name is specified, only that "
1573ad6c7f9SVictor Latushkin 	    "dataset is dumped\n");
1583ad6c7f9SVictor Latushkin 	(void) fprintf(stderr, "    If object numbers are specified, only "
1593ad6c7f9SVictor Latushkin 	    "those objects are dumped\n\n");
1603ad6c7f9SVictor Latushkin 	(void) fprintf(stderr, "    Options to control amount of output:\n");
1613ad6c7f9SVictor Latushkin 	(void) fprintf(stderr, "        -b block statistics\n");
1623ad6c7f9SVictor Latushkin 	(void) fprintf(stderr, "        -c checksum all metadata (twice for "
1636365109dSVictor Latushkin 	    "all data) blocks\n");
164ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -C config (or cachefile if alone)\n");
165ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -d dataset(s)\n");
166f0ba89beSJeff Bonwick 	(void) fprintf(stderr, "        -D dedup statistics\n");
1674923c69fSMatthew Ahrens 	(void) fprintf(stderr, "        -E decode and display block from an "
1684923c69fSMatthew Ahrens 	    "embedded block pointer\n");
169ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -h pool history\n");
170ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -i intent logs\n");
17164723e36SYuri Pankov 	(void) fprintf(stderr, "        -l read label contents\n");
17286714001SSerapheim Dimitropoulos 	(void) fprintf(stderr, "        -k examine the checkpointed state "
17386714001SSerapheim Dimitropoulos 	    "of the pool\n");
17482a0a985SVictor Latushkin 	(void) fprintf(stderr, "        -L disable leak tracking (do not "
17582a0a985SVictor Latushkin 	    "load spacemaps)\n");
176ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -m metaslabs\n");
177ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -M metaslab groups\n");
178ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -O perform object lookups by path\n");
179d41e7643Sek 	(void) fprintf(stderr, "        -R read and display block from a "
180ed61ec1dSYuri Pankov 	    "device\n");
181ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -s report stats on zdb's I/O\n");
182ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -S simulate dedup to measure effect\n");
183ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -v verbose (applies to all "
184ed61ec1dSYuri Pankov 	    "others)\n\n");
1853ad6c7f9SVictor Latushkin 	(void) fprintf(stderr, "    Below options are intended for use "
186df15e419SMatthew Ahrens 	    "with other options:\n");
187feef89cfSVictor Latushkin 	(void) fprintf(stderr, "        -A ignore assertions (-A), enable "
188feef89cfSVictor Latushkin 	    "panic recovery (-AA) or both (-AAA)\n");
1893ad6c7f9SVictor Latushkin 	(void) fprintf(stderr, "        -e pool is exported/destroyed/"
1903ad6c7f9SVictor Latushkin 	    "has altroot/not in a cachefile\n");
191ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -F attempt automatic rewind within "
192ed61ec1dSYuri Pankov 	    "safe range of transaction groups\n");
193ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -G dump zfs_dbgmsg buffer before "
194ed61ec1dSYuri Pankov 	    "exiting\n");
1952e4c9986SGeorge Wilson 	(void) fprintf(stderr, "        -I <number of inflight I/Os> -- "
196df15e419SMatthew Ahrens 	    "specify the maximum number of "
197df15e419SMatthew Ahrens 	    "checksumming I/Os [default is 200]\n");
1980e60744cSPavel Zakharov 	(void) fprintf(stderr, "        -o <variable>=<value> set global "
1990e60744cSPavel Zakharov 	    "variable to an unsigned 32-bit integer value\n");
200ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -p <path> -- use one or more with "
201ed61ec1dSYuri Pankov 	    "-e to specify path to vdev dir\n");
202ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -P print numbers in parseable form\n");
20364723e36SYuri Pankov 	(void) fprintf(stderr, "        -q don't print label contents\n");
204ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -t <txg> -- highest txg to use when "
205ed61ec1dSYuri Pankov 	    "searching for uberblocks\n");
20664723e36SYuri Pankov 	(void) fprintf(stderr, "        -u uberblock\n");
207ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -U <cachefile_path> -- use alternate "
208ed61ec1dSYuri Pankov 	    "cachefile\n");
209dfd5965fSRichard Yao 	(void) fprintf(stderr, "        -V do verbatim import\n");
210ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -x <dumpdir> -- "
211ed61ec1dSYuri Pankov 	    "dump all read blocks into specified directory\n");
212ed61ec1dSYuri Pankov 	(void) fprintf(stderr, "        -X attempt extreme rewind (does not "
213ed61ec1dSYuri Pankov 	    "work with dataset)\n\n");
214fa9e4066Sahrens 	(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
215fa9e4066Sahrens 	    "to make only that option verbose\n");
216fa9e4066Sahrens 	(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
217fa9e4066Sahrens 	exit(1);
218fa9e4066Sahrens }
22029bdd2f9SPavel Zakharov static void
dump_debug_buffer()22129bdd2f9SPavel Zakharov dump_debug_buffer()
22229bdd2f9SPavel Zakharov {
22329bdd2f9SPavel Zakharov 	if (dump_opt['G']) {
22429bdd2f9SPavel Zakharov 		(void) printf("\n");
22529bdd2f9SPavel Zakharov 		zfs_dbgmsg_print("zdb");
22629bdd2f9SPavel Zakharov 	}
22729bdd2f9SPavel Zakharov }
22829bdd2f9SPavel Zakharov 
229ccba0801SRich Morris /*
230ccba0801SRich Morris  * Called for usage errors that are discovered after a call to spa_open(),
231ccba0801SRich Morris  * dmu_bonus_hold(), or pool_match().  abort() is called for other errors.
232ccba0801SRich Morris  */
233ccba0801SRich Morris 
234fa9e4066Sahrens static void
fatal(const char * fmt,...)235fa9e4066Sahrens fatal(const char *fmt, ...)
236fa9e4066Sahrens {
237fa9e4066Sahrens 	va_list ap;
239fa9e4066Sahrens 	va_start(ap, fmt);
240fa9e4066Sahrens 	(void) fprintf(stderr, "%s: ", cmdname);
241fa9e4066Sahrens 	(void) vfprintf(stderr, fmt, ap);
242fa9e4066Sahrens 	va_end(ap);
243fa9e4066Sahrens 	(void) fprintf(stderr, "\n");
24529bdd2f9SPavel Zakharov 	dump_debug_buffer();
24629bdd2f9SPavel Zakharov 
247ccba0801SRich Morris 	exit(1);
248fa9e4066Sahrens }
250fa9e4066Sahrens /* ARGSUSED */
251fa9e4066Sahrens static void
dump_packed_nvlist(objset_t * os,uint64_t object,void * data,size_t size)252fa9e4066Sahrens dump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
253fa9e4066Sahrens {
254fa9e4066Sahrens 	nvlist_t *nv;
255fa9e4066Sahrens 	size_t nvsize = *(uint64_t *)data;
256fa9e4066Sahrens 	char *packed = umem_alloc(nvsize, UMEM_NOFAIL);
2587bfdf011SNeil Perrin 	VERIFY(0 == dmu_read(os, object, 0, nvsize, packed, DMU_READ_PREFETCH));
260fa9e4066Sahrens 	VERIFY(nvlist_unpack(packed, nvsize, &nv, 0) == 0);
262fa9e4066Sahrens 	umem_free(packed, nvsize);
264fa9e4066Sahrens 	dump_nvlist(nv, 8);
266fa9e4066Sahrens 	nvlist_free(nv);
267fa9e4066Sahrens }
2694445fffbSMatthew Ahrens /* ARGSUSED */
2704445fffbSMatthew Ahrens static void
dump_history_offsets(objset_t * os,uint64_t object,void * data,size_t size)2714445fffbSMatthew Ahrens dump_history_offsets(objset_t *os, uint64_t object, void *data, size_t size)
2724445fffbSMatthew Ahrens {
2734445fffbSMatthew Ahrens 	spa_history_phys_t *shp = data;
2744445fffbSMatthew Ahrens 
2754445fffbSMatthew Ahrens 	if (shp == NULL)
2764445fffbSMatthew Ahrens 		return;
2774445fffbSMatthew Ahrens 
2784445fffbSMatthew Ahrens 	(void) printf("\t\tpool_create_len = %llu\n",
2794445fffbSMatthew Ahrens 	    (u_longlong_t)shp->sh_pool_create_len);
2804445fffbSMatthew Ahrens 	(void) printf("\t\tphys_max_off = %llu\n",
2814445fffbSMatthew Ahrens 	    (u_longlong_t)shp->sh_phys_max_off);
2824445fffbSMatthew Ahrens 	(void) printf("\t\tbof = %llu\n",
2834445fffbSMatthew Ahrens 	    (u_longlong_t)shp->sh_bof);
2844445fffbSMatthew Ahrens 	(void) printf("\t\teof = %llu\n",
2854445fffbSMatthew Ahrens 	    (u_longlong_t)shp->sh_eof);
2864445fffbSMatthew Ahrens 	(void) printf("\t\trecords_lost = %llu\n",
2874445fffbSMatthew Ahrens 	    (u_longlong_t)shp->sh_records_lost);
2884445fffbSMatthew Ahrens }
2894445fffbSMatthew Ahrens 
2903f9d6ad7SLin Ling static void
zdb_nicenum(uint64_t num,char * buf,size_t buflen)2910a055120SJason King zdb_nicenum(uint64_t num, char *buf, size_t buflen)
2923f9d6ad7SLin Ling {
2933f9d6ad7SLin Ling 	if (dump_opt['P'])
2940a055120SJason King 		(void) snprintf(buf, buflen, "%llu", (longlong_t)num);
2953f9d6ad7SLin Ling 	else
2960a055120SJason King 		nicenum(num, buf, sizeof (buf));
2973f9d6ad7SLin Ling }
2983f9d6ad7SLin Ling 
2993f7978d0SAlan Somers static const char histo_stars[] = "****************************************";
3003f7978d0SAlan Somers static const uint64_t histo_width = sizeof (histo_stars) - 1;
302fa9e4066Sahrens static void
dump_histogram(const uint64_t * histo,int size,int offset)3030713e232SGeorge Wilson dump_histogram(const uint64_t *histo, int size, int offset)
304fa9e4066Sahrens {
305fa9e4066Sahrens 	int i;
306490d05b9SMatthew Ahrens 	int minidx = size - 1;
307fa9e4066Sahrens 	int maxidx = 0;
308fa9e4066Sahrens 	uint64_t max = 0;
310490d05b9SMatthew Ahrens 	for (i = 0; i < size; i++) {
311fa9e4066Sahrens 		if (histo[i] > max)
312fa9e4066Sahrens 			max = histo[i];
313fa9e4066Sahrens 		if (histo[i] > 0 && i > maxidx)
314fa9e4066Sahrens 			maxidx = i;
315fa9e4066Sahrens 		if (histo[i] > 0 && i < minidx)
316fa9e4066Sahrens 			minidx = i;
317fa9e4066Sahrens 	}
319490d05b9SMatthew Ahrens 	if (max < histo_width)
320490d05b9SMatthew Ahrens 		max = histo_width;
322490d05b9SMatthew Ahrens 	for (i = minidx; i <= maxidx; i++) {
323490d05b9SMatthew Ahrens 		(void) printf("\t\t\t%3u: %6llu %s\n",
3240713e232SGeorge Wilson 		    i + offset, (u_longlong_t)histo[i],
325490d05b9SMatthew Ahrens 		    &histo_stars[(max - histo[i]) * histo_width / max]);
326490d05b9SMatthew Ahrens 	}
327fa9e4066Sahrens }
329fa9e4066Sahrens static void
dump_zap_stats(objset_t * os,uint64_t object)330fa9e4066Sahrens dump_zap_stats(objset_t *os, uint64_t object)
331fa9e4066Sahrens {
332fa9e4066Sahrens 	int error;
333fa9e4066Sahrens 	zap_stats_t zs;
335fa9e4066Sahrens 	error = zap_get_stats(os, object, &zs);
336fa9e4066Sahrens 	if (error)
337fa9e4066Sahrens 		return;
339fa9e4066Sahrens 	if (zs.zs_ptrtbl_len == 0) {
340fa9e4066Sahrens 		ASSERT(zs.zs_num_blocks == 1);
341fa9e4066Sahrens 		(void) printf("\tmicrozap: %llu bytes, %llu entries\n",
342fa9e4066Sahrens 		    (u_longlong_t)zs.zs_blocksize,
343fa9e4066Sahrens 		    (u_longlong_t)zs.zs_num_entries);
344fa9e4066Sahrens 		return;
345fa9e4066Sahrens 	}
347fa9e4066Sahrens 	(void) printf("\tFat ZAP stats:\n");
3498248818dSnd 	(void) printf("\t\tPointer table:\n");
3508248818dSnd 	(void) printf("\t\t\t%llu elements\n",
351fa9e4066Sahrens 	    (u_longlong_t)zs.zs_ptrtbl_len);
3528248818dSnd 	(void) printf("\t\t\tzt_blk: %llu\n",
3538248818dSnd 	    (u_longlong_t)zs.zs_ptrtbl_zt_blk);
3548248818dSnd 	(void) printf("\t\t\tzt_numblks: %llu\n",
3558248818dSnd 	    (u_longlong_t)zs.zs_ptrtbl_zt_numblks);
3568248818dSnd 	(void) printf("\t\t\tzt_shift: %llu\n",
3578248818dSnd 	    (u_longlong_t)zs.zs_ptrtbl_zt_shift);
3588248818dSnd 	(void) printf("\t\t\tzt_blks_copied: %llu\n",
3598248818dSnd 	    (u_longlong_t)zs.zs_ptrtbl_blks_copied);
3608248818dSnd 	(void) printf("\t\t\tzt_nextblk: %llu\n",
3618248818dSnd 	    (u_longlong_t)zs.zs_ptrtbl_nextblk);
363fa9e4066Sahrens 	(void) printf("\t\tZAP entries: %llu\n",
364fa9e4066Sahrens 	    (u_longlong_t)zs.zs_num_entries);
365fa9e4066Sahrens 	(void) printf("\t\tLeaf blocks: %llu\n",
366fa9e4066Sahrens 	    (u_longlong_t)zs.zs_num_leafs);
367fa9e4066Sahrens 	(void) printf("\t\tTotal blocks: %llu\n",
368fa9e4066Sahrens 	    (u_longlong_t)zs.zs_num_blocks);
3698248818dSnd 	(void) printf("\t\tzap_block_type: 0x%llx\n",
3708248818dSnd 	    (u_longlong_t)zs.zs_block_type);
3718248818dSnd 	(void) printf("\t\tzap_magic: 0x%llx\n",
3728248818dSnd 	    (u_longlong_t)zs.zs_magic);
3738248818dSnd 	(void) printf("\t\tzap_salt: 0x%llx\n",
3748248818dSnd 	    (u_longlong_t)zs.zs_salt);
376fa9e4066Sahrens 	(void) printf("\t\tLeafs with 2^n pointers:\n");
3770713e232SGeorge Wilson 	dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE, 0);
379fa9e4066Sahrens 	(void) printf("\t\tBlocks with n*5 entries:\n");
3800713e232SGeorge Wilson 	dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE, 0);
382fa9e4066Sahrens 	(void) printf("\t\tBlocks n/10 full:\n");
3830713e232SGeorge Wilson 	dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE, 0);
385fa9e4066Sahrens 	(void) printf("\t\tEntries with n chunks:\n");
3860713e232SGeorge Wilson 	dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE, 0);
388fa9e4066Sahrens 	(void) printf("\t\tBuckets with n entries:\n");
3890713e232SGeorge Wilson 	dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE, 0);
390fa9e4066Sahrens }
392fa9e4066Sahrens /*ARGSUSED*/
393fa9e4066Sahrens static void
dump_none(objset_t * os,uint64_t object,void * data,size_t size)394fa9e4066Sahrens dump_none(objset_t *os, uint64_t object, void *data, size_t size)
395fa9e4066Sahrens {
396fa9e4066Sahrens }
3986de8f417SVictor Latushkin /*ARGSUSED*/
3996de8f417SVictor Latushkin static void
dump_unknown(objset_t * os,uint64_t object,void * data,size_t size)4006de8f417SVictor Latushkin dump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
4016de8f417SVictor Latushkin {
4026de8f417SVictor Latushkin 	(void) printf("\tUNKNOWN OBJECT TYPE\n");
4036de8f417SVictor Latushkin }
4046de8f417SVictor Latushkin 
405fa9e4066Sahrens /*ARGSUSED*/
4063f7978d0SAlan Somers static void
dump_uint8(objset_t * os,uint64_t object,void * data,size_t size)407fa9e4066Sahrens dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
408fa9e4066Sahrens {
409fa9e4066Sahrens }
411fa9e4066Sahrens /*ARGSUSED*/
412fa9e4066Sahrens static void
dump_uint64(objset_t * os,uint64_t object,void * data,size_t size)413fa9e4066Sahrens dump_uint64(objset_t *os, uint64_t object, void *data, size_t size)
414fa9e4066Sahrens {
415fa9e4066Sahrens }
417fa9e4066Sahrens /*ARGSUSED*/
418fa9e4066Sahrens static void
dump_zap(objset_t * os,uint64_t object,void * data,size_t size)419fa9e4066Sahrens dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
420fa9e4066Sahrens {
421fa9e4066Sahrens 	zap_cursor_t zc;
422fa9e4066Sahrens 	zap_attribute_t attr;
423fa9e4066Sahrens 	void *prop;
4243f7978d0SAlan Somers 	unsigned i;
426fa9e4066Sahrens 	dump_zap_stats(os, object);
427fa9e4066Sahrens 	(void) printf("\n");
429fa9e4066Sahrens 	for (zap_cursor_init(&zc, os, object);
430fa9e4066Sahrens 	    zap_cursor_retrieve(&zc, &attr) == 0;
431fa9e4066Sahrens 	    zap_cursor_advance(&zc)) {
432fa9e4066Sahrens 		(void) printf("\t\t%s = ", attr.za_name);
433fa9e4066Sahrens 		if (attr.za_num_integers == 0) {
434fa9e4066Sahrens 			(void) printf("\n");
435fa9e4066Sahrens 			continue;
436fa9e4066Sahrens 		}
437fa9e4066Sahrens 		prop = umem_zalloc(attr.za_num_integers *
438fa9e4066Sahrens 		    attr.za_integer_length, UMEM_NOFAIL);
439fa9e4066Sahrens 		(void) zap_lookup(os, object, attr.za_name,
440fa9e4066Sahrens 		    attr.za_integer_length, attr.za_num_integers, prop);
441fa9e4066Sahrens 		if (attr.za_integer_length == 1) {
4422d37a1a3SToomas Soome 			if (strcmp(attr.za_name,
4432d37a1a3SToomas Soome 			    DSL_CRYPTO_KEY_MASTER_KEY) == 0 ||
4442d37a1a3SToomas Soome 			    strcmp(attr.za_name,
4452d37a1a3SToomas Soome 			    DSL_CRYPTO_KEY_HMAC_KEY) == 0 ||
4462d37a1a3SToomas Soome 			    strcmp(attr.za_name, DSL_CRYPTO_KEY_IV) == 0 ||
44732114f88SToomas Soome 			    strcmp(attr.za_name, DSL_CRYPTO_KEY_MAC) == 0 ||
44832114f88SToomas Soome 			    strcmp(attr.za_name, DMU_POOL_CHECKSUM_SALT) == 0) {
4492d37a1a3SToomas Soome 				uint8_t *u8 = prop;
4502d37a1a3SToomas Soome 
4512d37a1a3SToomas Soome 				for (i = 0; i < attr.za_num_integers; i++) {
4522d37a1a3SToomas Soome 					(void) printf("%02x", u8[i]);
4532d37a1a3SToomas Soome 				}
4542d37a1a3SToomas Soome 			} else {
4552d37a1a3SToomas Soome 				(void) printf("%s", (char *)prop);
4562d37a1a3SToomas Soome 			}
457fa9e4066Sahrens 		} else {
458fa9e4066Sahrens 			for (i = 0; i < attr.za_num_integers; i++) {
459fa9e4066Sahrens 				switch (attr.za_integer_length) {
460fa9e4066Sahrens 				case 2:
461fa9e4066Sahrens 					(void) printf("%u ",
462fa9e4066Sahrens 					    ((uint16_t *)prop)[i]);
463fa9e4066Sahrens 					break;
464fa9e4066Sahrens 				case 4:
465fa9e4066Sahrens 					(void) printf("%u ",
466fa9e4066Sahrens 					    ((uint32_t *)prop)[i]);
467fa9e4066Sahrens 					break;
468fa9e4066Sahrens 				case 8:
469fa9e4066Sahrens 					(void) printf("%lld ",
470fa9e4066Sahrens 					    (u_longlong_t)((int64_t *)prop)[i]);
471fa9e4066Sahrens 					break;
472fa9e4066Sahrens 				}
473fa9e4066Sahrens 			}
474fa9e4066Sahrens 		}
475fa9e4066Sahrens 		(void) printf("\n");
476fa9e4066Sahrens 		umem_free(prop, attr.za_num_integers * attr.za_integer_length);
477fa9e4066Sahrens 	}
47887e5029aSahrens 	zap_cursor_fini(&zc);
479fa9e4066Sahrens }
481732885fcSMatthew Ahrens static void
dump_bpobj(objset_t * os,uint64_t object,void * data,size_t size)482732885fcSMatthew Ahrens dump_bpobj(objset_t *os, uint64_t object, void *data, size_t size)
483732885fcSMatthew Ahrens {
484732885fcSMatthew Ahrens 	bpobj_phys_t *bpop = data;
485732885fcSMatthew Ahrens 	char bytes[32], comp[32], uncomp[32];
486732885fcSMatthew Ahrens 
4870a055120SJason King 	/* make sure the output won't get truncated */
4880a055120SJason King 	CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ);
4890a055120SJason King 	CTASSERT(sizeof (comp) >= NN_NUMBUF_SZ);
4900a055120SJason King 	CTASSERT(sizeof (uncomp) >= NN_NUMBUF_SZ);
4910a055120SJason King 
492732885fcSMatthew Ahrens 	if (bpop == NULL)
493732885fcSMatthew Ahrens 		return;
494732885fcSMatthew Ahrens 
4950a055120SJason King 	zdb_nicenum(bpop->bpo_bytes, bytes, sizeof (bytes));
4960a055120SJason King 	zdb_nicenum(bpop->bpo_comp, comp, sizeof (comp));
4970a055120SJason King 	zdb_nicenum(bpop->bpo_uncomp, uncomp, sizeof (uncomp));
498732885fcSMatthew Ahrens 
499732885fcSMatthew Ahrens 	(void) printf("\t\tnum_blkptrs = %llu\n",
500732885fcSMatthew Ahrens 	    (u_longlong_t)bpop->bpo_num_blkptrs);
501732885fcSMatthew Ahrens 	(void) printf("\t\tbytes = %s\n", bytes);
502732885fcSMatthew Ahrens 	if (size >= BPOBJ_SIZE_V1) {
503732885fcSMatthew Ahrens 		(void) printf("\t\tcomp = %s\n", comp);
504732885fcSMatthew Ahrens 		(void) printf("\t\tuncomp = %s\n", uncomp);
505732885fcSMatthew Ahrens 	}
506732885fcSMatthew Ahrens 	if (size >= sizeof (*bpop)) {
507732885fcSMatthew Ahrens 		(void) printf("\t\tsubobjs = %llu\n",
508732885fcSMatthew Ahrens 		    (u_longlong_t)bpop->bpo_subobjs);
509732885fcSMatthew Ahrens 		(void) printf("\t\tnum_subobjs = %llu\n",
510732885fcSMatthew Ahrens 		    (u_longlong_t)bpop->bpo_num_subobjs);
511732885fcSMatthew Ahrens 	}
512732885fcSMatthew Ahrens 
513732885fcSMatthew Ahrens 	if (dump_opt['d'] < 5)
514732885fcSMatthew Ahrens 		return;
515732885fcSMatthew Ahrens 
516732885fcSMatthew Ahrens 	for (uint64_t i = 0; i < bpop->bpo_num_blkptrs; i++) {
517732885fcSMatthew Ahrens 		char blkbuf[BP_SPRINTF_LEN];
518732885fcSMatthew Ahrens 		blkptr_t bp;
519732885fcSMatthew Ahrens 
520732885fcSMatthew Ahrens 		int err = dmu_read(os, object,
521732885fcSMatthew Ahrens 		    i * sizeof (bp), sizeof (bp), &bp, 0);
522732885fcSMatthew Ahrens 		if (err != 0) {
523732885fcSMatthew Ahrens 			(void) printf("got error %u from dmu_read\n", err);
524732885fcSMatthew Ahrens 			break;
525732885fcSMatthew Ahrens 		}
526732885fcSMatthew Ahrens 		snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), &bp);
527732885fcSMatthew Ahrens 		(void) printf("\t%s\n", blkbuf);
528732885fcSMatthew Ahrens 	}
529732885fcSMatthew Ahrens }
530732885fcSMatthew Ahrens 
531732885fcSMatthew Ahrens /* ARGSUSED */
532732885fcSMatthew Ahrens static void
dump_bpobj_subobjs(objset_t * os,uint64_t object,void * data,size_t size)533732885fcSMatthew Ahrens dump_bpobj_subobjs(objset_t *os, uint64_t object, void *data, size_t size)
534732885fcSMatthew Ahrens {
535732885fcSMatthew Ahrens 	dmu_object_info_t doi;
536732885fcSMatthew Ahrens 
537732885fcSMatthew Ahrens 	VERIFY0(dmu_object_info(os, object, &doi));
538732885fcSMatthew Ahrens 	uint64_t *subobjs = kmem_alloc(doi.doi_max_offset, KM_SLEEP);
539732885fcSMatthew Ahrens 
540732885fcSMatthew Ahrens 	int err = dmu_read(os, object, 0, doi.doi_max_offset, subobjs, 0);
541732885fcSMatthew Ahrens 	if (err != 0) {
542732885fcSMatthew Ahrens 		(void) printf("got error %u from dmu_read\n", err);
543732885fcSMatthew Ahrens 		kmem_free(subobjs, doi.doi_max_offset);
544732885fcSMatthew Ahrens 		return;
545732885fcSMatthew Ahrens 	}
546732885fcSMatthew Ahrens 
547732885fcSMatthew Ahrens 	int64_t last_nonzero = -1;
548732885fcSMatthew Ahrens 	for (uint64_t i = 0; i < doi.doi_max_offset / 8; i++) {
549732885fcSMatthew Ahrens 		if (subobjs[i] != 0)
550732885fcSMatthew Ahrens 			last_nonzero = i;
551732885fcSMatthew Ahrens 	}
552732885fcSMatthew Ahrens 
553732885fcSMatthew Ahrens 	for (int64_t i = 0; i <= last_nonzero; i++) {
554732885fcSMatthew Ahrens 		(void) printf("\t%llu\n", (longlong_t)subobjs[i]);
555732885fcSMatthew Ahrens 	}
556732885fcSMatthew Ahrens 	kmem_free(subobjs, doi.doi_max_offset);
557732885fcSMatthew Ahrens }
558732885fcSMatthew Ahrens 
559486ae710SMatthew Ahrens /*ARGSUSED*/
560486ae710SMatthew Ahrens static void
dump_ddt_zap(objset_t * os,uint64_t object,void * data,size_t size)561486ae710SMatthew Ahrens dump_ddt_zap(objset_t *os, uint64_t object, void *data, size_t size)
562486ae710SMatthew Ahrens {
563486ae710SMatthew Ahrens 	dump_zap_stats(os, object);
564486ae710SMatthew Ahrens 	/* contents are printed elsewhere, properly decoded */
565486ae710SMatthew Ahrens }
566486ae710SMatthew Ahrens 
5670a586ceaSMark Shellenbaum /*ARGSUSED*/
5680a586ceaSMark Shellenbaum static void
dump_sa_attrs(objset_t * os,uint64_t object,void * data,size_t size)5690a586ceaSMark Shellenbaum dump_sa_attrs(objset_t *os, uint64_t object, void *data, size_t size)
5700a586ceaSMark Shellenbaum {
5710a586ceaSMark Shellenbaum 	zap_cursor_t zc;
5720a586ceaSMark Shellenbaum 	zap_attribute_t attr;
5730a586ceaSMark Shellenbaum 
5740a586ceaSMark Shellenbaum 	dump_zap_stats(os, object);
5750a586ceaSMark Shellenbaum 	(void) printf("\n");
5760a586ceaSMark Shellenbaum 
5770a586ceaSMark Shellenbaum 	for (zap_cursor_init(&zc, os, object);
5780a586ceaSMark Shellenbaum 	    zap_cursor_retrieve(&zc, &attr) == 0;
5790a586ceaSMark Shellenbaum 	    zap_cursor_advance(&zc)) {
5800a586ceaSMark Shellenbaum 		(void) printf("\t\t%s = ", attr.za_name);
5810a586ceaSMark Shellenbaum 		if (attr.za_num_integers == 0) {
5820a586ceaSMark Shellenbaum 			(void) printf("\n");
5830a586ceaSMark Shellenbaum 			continue;
5840a586ceaSMark Shellenbaum 		}
5850a586ceaSMark Shellenbaum 		(void) printf(" %llx : [%d:%d:%d]\n",
5860a586ceaSMark Shellenbaum 		    (u_longlong_t)attr.za_first_integer,
5870a586ceaSMark Shellenbaum 		    (int)ATTR_LENGTH(attr.za_first_integer),
5880a586ceaSMark Shellenbaum 		    (int)ATTR_BSWAP(attr.za_first_integer),
5890a586ceaSMark Shellenbaum 		    (int)ATTR_NUM(attr.za_first_integer));
5900a586ceaSMark Shellenbaum 	}
5910a586ceaSMark Shellenbaum 	zap_cursor_fini(&zc);
5920a586ceaSMark Shellenbaum }
5930a586ceaSMark Shellenbaum 
5940a586ceaSMark Shellenbaum /*ARGSUSED*/
5950a586ceaSMark Shellenbaum static void
dump_sa_layouts(objset_t * os,uint64_t object,void * data,size_t size)5960a586ceaSMark Shellenbaum dump_sa_layouts(objset_t *os, uint64_t object, void *data, size_t size)
5970a586ceaSMark Shellenbaum {
5980a586ceaSMark Shellenbaum 	zap_cursor_t zc;
5990a586ceaSMark Shellenbaum 	zap_attribute_t attr;
6000a586ceaSMark Shellenbaum 	uint16_t *layout_attrs;
6013f7978d0SAlan Somers 	unsigned i;
6020a586ceaSMark Shellenbaum 
6030a586ceaSMark Shellenbaum 	dump_zap_stats(os, object);
6040a586ceaSMark Shellenbaum 	(void) printf("\n");
6050a586ceaSMark Shellenbaum 
6060a586ceaSMark Shellenbaum 	for (zap_cursor_init(&zc, os, object);
6070a586ceaSMark Shellenbaum 	    zap_cursor_retrieve(&zc, &attr) == 0;
6080a586ceaSMark Shellenbaum 	    zap_cursor_advance(&zc)) {
6090a586ceaSMark Shellenbaum 		(void) printf("\t\t%s = [", attr.za_name);
6100a586ceaSMark Shellenbaum 		if (attr.za_num_integers == 0) {
6110a586ceaSMark Shellenbaum 			(void) printf("\n");
6120a586ceaSMark Shellenbaum 			continue;
6130a586ceaSMark Shellenbaum 		}
6140a586ceaSMark Shellenbaum 
6150a586ceaSMark Shellenbaum 		VERIFY(attr.za_integer_length == 2);
6160a586ceaSMark Shellenbaum 		layout_attrs = umem_zalloc(attr.za_num_integers *
6170a586ceaSMark Shellenbaum 		    attr.za_integer_length, UMEM_NOFAIL);
6180a586ceaSMark Shellenbaum 
6190a586ceaSMark Shellenbaum 		VERIFY(zap_lookup(os, object, attr.za_name,
6200a586ceaSMark Shellenbaum 		    attr.za_integer_length,
6210a586ceaSMark Shellenbaum 		    attr.za_num_integers, layout_attrs) == 0);
6220a586ceaSMark Shellenbaum 
6230a586ceaSMark Shellenbaum 		for (i = 0; i != attr.za_num_integers; i++)
6240a586ceaSMark Shellenbaum 			(void) printf(" %d ", (int)layout_attrs[i]);
6250a586ceaSMark Shellenbaum 		(void) printf("]\n");
6260a586ceaSMark Shellenbaum 		umem_free(layout_attrs,
6270a586ceaSMark Shellenbaum 		    attr.za_num_integers * attr.za_integer_length);
6280a586ceaSMark Shellenbaum 	}
6290a586ceaSMark Shellenbaum 	zap_cursor_fini(&zc);
6300a586ceaSMark Shellenbaum }
6310a586ceaSMark Shellenbaum 
632e7437265Sahrens /*ARGSUSED*/
633e7437265Sahrens static void
dump_zpldir(objset_t * os,uint64_t object,void * data,size_t size)634e7437265Sahrens dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
635e7437265Sahrens {
636e7437265Sahrens 	zap_cursor_t zc;
637e7437265Sahrens 	zap_attribute_t attr;
638e7437265Sahrens 	const char *typenames[] = {
639e7437265Sahrens 		/* 0 */ "not specified",
640e7437265Sahrens 		/* 1 */ "FIFO",
641e7437265Sahrens 		/* 2 */ "Character Device",
642e7437265Sahrens 		/* 3 */ "3 (invalid)",
643e7437265Sahrens 		/* 4 */ "Directory",
644e7437265Sahrens 		/* 5 */ "5 (invalid)",
645e7437265Sahrens 		/* 6 */ "Block Device",
646e7437265Sahrens 		/* 7 */ "7 (invalid)",
647e7437265Sahrens 		/* 8 */ "Regular File",
648e7437265Sahrens 		/* 9 */ "9 (invalid)",
649e7437265Sahrens 		/* 10 */ "Symbolic Link",
650e7437265Sahrens 		/* 11 */ "11 (invalid)",
651e7437265Sahrens 		/* 12 */ "Socket",
652e7437265Sahrens 		/* 13 */ "Door",
653e7437265Sahrens 		/* 14 */ "Event Port",
654e7437265Sahrens 		/* 15 */ "15 (invalid)",
655e7437265Sahrens 	};
657e7437265Sahrens 	dump_zap_stats(os, object);
658e7437265Sahrens 	(void) printf("\n");
660e7437265Sahrens 	for (zap_cursor_init(&zc, os, object);
661e7437265Sahrens 	    zap_cursor_retrieve(&zc, &attr) == 0;
662e7437265Sahrens 	    zap_cursor_advance(&zc)) {
663e7437265Sahrens 		(void) printf("\t\t%s = %lld (type: %s)\n",
664e7437265Sahrens 		    attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
665e7437265Sahrens 		    typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
666e7437265Sahrens 	}
667e7437265Sahrens 	zap_cursor_fini(&zc);
668e7437265Sahrens }
6703f7978d0SAlan Somers static int
get_dtl_refcount(vdev_t * vd)6710713e232SGeorge Wilson get_dtl_refcount(vdev_t *vd)
6720713e232SGeorge Wilson {
6730713e232SGeorge Wilson 	int refcount = 0;
6740713e232SGeorge Wilson 
6750713e232SGeorge Wilson 	if (vd->vdev_ops->vdev_op_leaf) {
6760713e232SGeorge Wilson 		space_map_t *sm = vd->vdev_dtl_sm;
6770713e232SGeorge Wilson 
6780713e232SGeorge Wilson 		if (sm != NULL &&
6790713e232SGeorge Wilson 		    sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
6800713e232SGeorge Wilson 			return (1);
6810713e232SGeorge Wilson 		return (0);
6820713e232SGeorge Wilson 	}
6830713e232SGeorge Wilson 
6843f7978d0SAlan Somers 	for (unsigned c = 0; c < vd->vdev_children; c++)
6850713e232SGeorge Wilson 		refcount += get_dtl_refcount(vd->vdev_child[c]);
6860713e232SGeorge Wilson 	return (refcount);
6870713e232SGeorge Wilson }
6880713e232SGeorge Wilson 
6893f7978d0SAlan Somers static int
get_metaslab_refcount(vdev_t * vd)6900713e232SGeorge Wilson get_metaslab_refcount(vdev_t *vd)
6910713e232SGeorge Wilson {
6920713e232SGeorge Wilson 	int refcount = 0;
6930713e232SGeorge Wilson 
6945cabbc6bSPrashanth Sreenivasa 	if (vd->vdev_top == vd) {
6955cabbc6bSPrashanth Sreenivasa 		for (uint64_t m = 0; m < vd->vdev_ms_count; m++) {
6960713e232SGeorge Wilson 			space_map_t *sm = vd->vdev_ms[m]->ms_sm;
6970713e232SGeorge Wilson 
6980713e232SGeorge Wilson 			if (sm != NULL &&
6990713e232SGeorge Wilson 			    sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
7000713e232SGeorge Wilson 				refcount++;
7010713e232SGeorge Wilson 		}
7020713e232SGeorge Wilson 	}
7033f7978d0SAlan Somers 	for (unsigned c = 0; c < vd->vdev_children; c++)
7040713e232SGeorge Wilson 		refcount += get_metaslab_refcount(vd->vdev_child[c]);
7050713e232SGeorge Wilson 
7060713e232SGeorge Wilson 	return (refcount);
7070713e232SGeorge Wilson }
7080713e232SGeorge Wilson 
7095cabbc6bSPrashanth Sreenivasa static int
get_obsolete_refcount(vdev_t * vd)7105cabbc6bSPrashanth Sreenivasa get_obsolete_refcount(vdev_t *vd)
7115cabbc6bSPrashanth Sreenivasa {
7125cabbc6bSPrashanth Sreenivasa 	int refcount = 0;
7135cabbc6bSPrashanth Sreenivasa 
7145cabbc6bSPrashanth Sreenivasa 	uint64_t obsolete_sm_obj = vdev_obsolete_sm_object(vd);
7155cabbc6bSPrashanth Sreenivasa 	if (vd->vdev_top == vd && obsolete_sm_obj != 0) {
7165cabbc6bSPrashanth Sreenivasa 		dmu_object_info_t doi;
7175cabbc6bSPrashanth Sreenivasa 		VERIFY0(dmu_object_info(vd->vdev_spa->spa_meta_objset,
7185cabbc6bSPrashanth Sreenivasa 		    obsolete_sm_obj, &doi));
7195cabbc6bSPrashanth Sreenivasa 		if (doi.doi_bonus_size == sizeof (space_map_phys_t)) {
7205cabbc6bSPrashanth Sreenivasa 			refcount++;
7215cabbc6bSPrashanth Sreenivasa 		}