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.c74
1 files changed, 54 insertions, 20 deletions
diff --git a/usr/src/cmd/zdb/zdb.c b/usr/src/cmd/zdb/zdb.c
index 16c8c60df1..26ed6dacf8 100644
--- a/usr/src/cmd/zdb/zdb.c
+++ b/usr/src/cmd/zdb/zdb.c
@@ -65,6 +65,7 @@
#include <sys/abd.h>
#include <sys/blkptr.h>
#include <sys/dsl_scan.h>
+#include <sys/dsl_crypt.h>
#include <zfs_comutil.h>
#include <libcmdutils.h>
#undef verify
@@ -1388,7 +1389,7 @@ static void
snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp)
{
const dva_t *dva = bp->blk_dva;
- int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1;
+ unsigned int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1;
if (dump_opt['b'] >= 6) {
snprintf_blkptr(blkbuf, buflen, bp);
@@ -1406,7 +1407,7 @@ snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp)
}
blkbuf[0] = '\0';
- for (int i = 0; i < ndvas; i++)
+ for (unsigned int i = 0; i < ndvas; i++)
(void) snprintf(blkbuf + strlen(blkbuf),
buflen - strlen(blkbuf), "%llu:%llx:%llx ",
(u_longlong_t)DVA_GET_VDEV(&dva[i]),
@@ -1871,14 +1872,14 @@ open_objset(const char *path, dmu_objset_type_t type, void *tag, objset_t **osp)
uint64_t version = 0;
VERIFY3P(sa_os, ==, NULL);
- err = dmu_objset_own(path, type, B_TRUE, tag, osp);
+ err = dmu_objset_own(path, type, B_TRUE, B_FALSE, tag, osp);
if (err != 0) {
(void) fprintf(stderr, "failed to own dataset '%s': %s\n", path,
strerror(err));
return (err);
}
- if (dmu_objset_type(*osp) == DMU_OST_ZFS) {
+ if (dmu_objset_type(*osp) == DMU_OST_ZFS && !(*osp)->os_encrypted) {
(void) zap_lookup(*osp, MASTER_NODE_OBJ, ZPL_VERSION_STR,
8, 1, &version);
if (version >= ZPL_VERSION_SA) {
@@ -1890,7 +1891,7 @@ open_objset(const char *path, dmu_objset_type_t type, void *tag, objset_t **osp)
if (err != 0) {
(void) fprintf(stderr, "sa_setup failed: %s\n",
strerror(err));
- dmu_objset_disown(*osp, tag);
+ dmu_objset_disown(*osp, B_FALSE, tag);
*osp = NULL;
}
}
@@ -1905,7 +1906,7 @@ close_objset(objset_t *os, void *tag)
VERIFY3P(os, ==, sa_os);
if (os->os_sa != NULL)
sa_tear_down(os);
- dmu_objset_disown(os, tag);
+ dmu_objset_disown(os, B_FALSE, tag);
sa_attr_table = NULL;
sa_os = NULL;
}
@@ -2061,6 +2062,7 @@ dump_dmu_objset(objset_t *os, uint64_t object, void *data, size_t size)
{
}
+
static object_viewer_t *object_viewer[DMU_OT_NUMTYPES + 1] = {
dump_none, /* unallocated */
dump_zap, /* object directory */
@@ -2126,6 +2128,7 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header,
dmu_buf_t *db = NULL;
dmu_object_info_t doi;
dnode_t *dn;
+ boolean_t dnode_held = B_FALSE;
void *bonus = NULL;
size_t bsize = 0;
char iblk[32], dblk[32], lsize[32], asize[32], fill[32], dnsize[32];
@@ -2149,16 +2152,33 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header,
if (object == 0) {
dn = DMU_META_DNODE(os);
+ dmu_object_info_from_dnode(dn, &doi);
} else {
- error = dmu_bonus_hold(os, object, FTAG, &db);
+ /*
+ * Encrypted datasets will have sensitive bonus buffers
+ * encrypted. Therefore we cannot hold the bonus buffer and
+ * must hold the dnode itself instead.
+ */
+ error = dmu_object_info(os, object, &doi);
if (error)
- fatal("dmu_bonus_hold(%llu) failed, errno %u",
- object, error);
- bonus = db->db_data;
- bsize = db->db_size;
- dn = DB_DNODE((dmu_buf_impl_t *)db);
+ fatal("dmu_object_info() failed, errno %u", error);
+
+ if (os->os_encrypted &&
+ DMU_OT_IS_ENCRYPTED(doi.doi_bonus_type)) {
+ error = dnode_hold(os, object, FTAG, &dn);
+ if (error)
+ fatal("dnode_hold() failed, errno %u", error);
+ dnode_held = B_TRUE;
+ } else {
+ error = dmu_bonus_hold(os, object, FTAG, &db);
+ if (error)
+ fatal("dmu_bonus_hold(%llu) failed, errno %u",
+ object, error);
+ bonus = db->db_data;
+ bsize = db->db_size;
+ dn = DB_DNODE((dmu_buf_impl_t *)db);
+ }
}
- dmu_object_info_from_dnode(dn, &doi);
if (dnode_slots_used != NULL)
*dnode_slots_used = doi.doi_dnodesize / DNODE_MIN_SIZE;
@@ -2207,9 +2227,20 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header,
(void) printf("\tdnode maxblkid: %llu\n",
(longlong_t)dn->dn_phys->dn_maxblkid);
- object_viewer[ZDB_OT_TYPE(doi.doi_bonus_type)](os, object,
- bonus, bsize);
- object_viewer[ZDB_OT_TYPE(doi.doi_type)](os, object, NULL, 0);
+ if (!dnode_held) {
+ object_viewer[ZDB_OT_TYPE(doi.doi_bonus_type)](os,
+ object, bonus, bsize);
+ } else {
+ (void) printf("\t\t(bonus encrypted)\n");
+ }
+
+ if (!os->os_encrypted || !DMU_OT_IS_ENCRYPTED(doi.doi_type)) {
+ object_viewer[ZDB_OT_TYPE(doi.doi_type)](os, object,
+ NULL, 0);
+ } else {
+ (void) printf("\t\t(object encrypted)\n");
+ }
+
*print_header = 1;
}
@@ -2253,6 +2284,8 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header,
if (db != NULL)
dmu_buf_rele(db, FTAG);
+ if (dnode_held)
+ dnode_rele(dn, FTAG);
}
static void
@@ -2631,7 +2664,7 @@ dump_path(char *ds, char *path)
if (err != 0) {
(void) fprintf(stderr, "can't lookup root znode: %s\n",
strerror(err));
- dmu_objset_disown(os, FTAG);
+ dmu_objset_disown(os, B_FALSE, FTAG);
return (EINVAL);
}
@@ -3729,7 +3762,8 @@ dump_block_stats(spa_t *spa)
zdb_cb_t zcb;
zdb_blkstats_t *zb, *tzb;
uint64_t norm_alloc, norm_space, total_alloc, total_found;
- int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD;
+ int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA |
+ TRAVERSE_NO_DECRYPT | TRAVERSE_HARD;
boolean_t leaks = B_FALSE;
int err;
@@ -4106,8 +4140,8 @@ dump_simulated_ddt(spa_t *spa)
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
- (void) traverse_pool(spa, 0, TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA,
- zdb_ddt_add_cb, &t);
+ (void) traverse_pool(spa, 0, TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA |
+ TRAVERSE_NO_DECRYPT, zdb_ddt_add_cb, &t);
spa_config_exit(spa, SCL_CONFIG, FTAG);