summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Ahrens <mahrens@delphix.com>2013-04-07 18:40:39 -0800
committerChristopher Siden <chris.siden@delphix.com>2013-04-07 19:40:39 -0700
commitd5ee8a1311accef11ec2057f70da38d1dd687088 (patch)
tree4b6256dd397b75b1207456339e6d01f702a9960a
parentb1fa6326238973aeaf12c34fcda75985b6c06be1 (diff)
downloadillumos-joyent-d5ee8a1311accef11ec2057f70da38d1dd687088.tar.gz
3654 zdb should print number of ganged blocks
3655 ::rrwlock and ::refcount print errors on non-debug kernels 3656 remove unused function zap_cursor_move_to_key() 3657 mdb_ctf_vread() should allow conversion of pointer to uintptr_t Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Christopher Siden <christopher.siden@delphix.com> Reviewed by: Dan McDonald <danmcd@nexenta.com> Approved by: Garrett D'Amore <garrett@damore.org>
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_ctf.c18
-rw-r--r--usr/src/cmd/mdb/common/modules/zfs/zfs.c148
-rw-r--r--usr/src/cmd/zdb/zdb.c39
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zap.h7
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zap_impl.h2
-rw-r--r--usr/src/uts/common/fs/zfs/zap.c25
-rw-r--r--usr/src/uts/common/fs/zfs/zap_micro.c40
7 files changed, 125 insertions, 154 deletions
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c
index 360e7ad97e..8f43c8cb0f 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c
@@ -1159,12 +1159,6 @@ vread_helper(mdb_ctf_id_t modid, char *modbuf,
return (-1); /* errno is set for us */
}
- if (tgtkind != modkind) {
- mdb_ctf_warn(flags, "unexpected kind for type %s (%s)\n",
- typename, tgtname);
- return (set_errno(EMDB_INCOMPAT));
- }
-
if ((modsz = mdb_ctf_type_size(modid)) == -1UL) {
mdb_ctf_warn(flags, "couldn't determine type size of "
"mdb module type %s\n", mdbtypename);
@@ -1176,7 +1170,17 @@ vread_helper(mdb_ctf_id_t modid, char *modbuf,
return (-1); /* errno is set for us */
}
- switch (modkind) {
+ if (tgtkind == CTF_K_POINTER && modkind == CTF_K_INTEGER &&
+ strcmp(mdbtypename, "uintptr_t") == 0) {
+ /* allow them to convert a pointer to a uintptr_t */
+ ASSERT(modsz == tgtsz);
+ } else if (tgtkind != modkind) {
+ mdb_ctf_warn(flags, "unexpected kind for type %s (%s)\n",
+ typename, tgtname);
+ return (set_errno(EMDB_INCOMPAT));
+ }
+
+ switch (tgtkind) {
case CTF_K_INTEGER:
case CTF_K_FLOAT:
/*
diff --git a/usr/src/cmd/mdb/common/modules/zfs/zfs.c b/usr/src/cmd/mdb/common/modules/zfs/zfs.c
index 792c9a1855..e2a05550c2 100644
--- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c
+++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c
@@ -380,7 +380,7 @@ typedef struct mdb_dmu_buf_impl {
struct {
uint64_t db_object;
} db;
- void *db_objset;
+ uintptr_t db_objset;
uint64_t db_level;
uint64_t db_blkid;
struct {
@@ -416,7 +416,7 @@ dbuf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
(void) mdb_snprintf(blkidname, sizeof (blkidname), "%llx",
(u_longlong_t)db.db_blkid);
- if (objset_name((uintptr_t)db.db_objset, path)) {
+ if (objset_name(db.db_objset, path)) {
return (DCMD_ERR);
}
@@ -1078,7 +1078,7 @@ spa_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
}
typedef struct mdb_spa_config_spa {
- nvlist_t *spa_config;
+ uintptr_t spa_config;
} mdb_spa_config_spa_t;
/*
@@ -1101,12 +1101,12 @@ spa_print_config(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
addr, 0) == -1)
return (DCMD_ERR);
- if (spa.spa_config == NULL) {
+ if (spa.spa_config == 0) {
mdb_printf("(none)\n");
return (DCMD_OK);
}
- return (mdb_call_dcmd("nvlist", (uintptr_t)spa.spa_config, flags,
+ return (mdb_call_dcmd("nvlist", spa.spa_config, flags,
0, NULL));
}
@@ -1736,11 +1736,11 @@ typedef struct zio_print_args {
typedef struct mdb_zio {
enum zio_type io_type;
enum zio_stage io_stage;
- void *io_waiter;
- void *io_spa;
+ uintptr_t io_waiter;
+ uintptr_t io_spa;
struct {
struct {
- void *list_next;
+ uintptr_t list_next;
} list_head;
} io_parent_list;
int io_error;
@@ -1797,8 +1797,8 @@ zio_print_cb(uintptr_t addr, zio_print_args_t *zpa)
} else {
mdb_printf("%*s%-*p %-5s %-16s ", indent, "",
ZIO_MAXWIDTH - indent, addr, type, stage);
- if (zio.io_waiter)
- mdb_printf("%-16p ", zio.io_waiter);
+ if (zio.io_waiter != 0)
+ mdb_printf("%-16lx ", zio.io_waiter);
else
mdb_printf("%-16s ", "-");
#ifdef _KERNEL
@@ -2065,7 +2065,7 @@ spa_walk_step(mdb_walk_state_t *wsp)
static int
zio_walk_init(mdb_walk_state_t *wsp)
{
- wsp->walk_data = (void *)wsp->walk_addr;
+ wsp->walk_data = &wsp->walk_addr;
if (mdb_layered_walk("zio_cache", wsp) == -1) {
mdb_warn("failed to walk 'zio_cache'\n");
@@ -2079,12 +2079,13 @@ static int
zio_walk_step(mdb_walk_state_t *wsp)
{
mdb_zio_t zio;
+ uintptr_t *spap = wsp->walk_data;
if (mdb_ctf_vread(&zio, ZFS_STRUCT "zio", "mdb_zio_t",
wsp->walk_addr, 0) == -1)
return (WALK_ERR);
- if (wsp->walk_data != NULL && wsp->walk_data != zio.io_spa)
+ if (*spap != 0 && *spap != zio.io_spa)
return (WALK_NEXT);
return (wsp->walk_callback(wsp->walk_addr, &zio, wsp->walk_cbdata));
@@ -2099,16 +2100,17 @@ static int
zio_walk_root_step(mdb_walk_state_t *wsp)
{
mdb_zio_t zio;
+ uintptr_t *spap = wsp->walk_data;
if (mdb_ctf_vread(&zio, ZFS_STRUCT "zio", "mdb_zio_t",
wsp->walk_addr, 0) == -1)
return (WALK_ERR);
- if (wsp->walk_data != NULL && wsp->walk_data != zio.io_spa)
+ if (*spap != 0 && *spap != zio.io_spa)
return (WALK_NEXT);
/* If the parent list is not empty, ignore */
- if ((uintptr_t)zio.io_parent_list.list_head.list_next !=
+ if (zio.io_parent_list.list_head.list_next !=
wsp->walk_addr +
mdb_ctf_offsetof_by_name(ZFS_STRUCT "zio", "io_parent_list") +
mdb_ctf_offsetof_by_name("struct list", "list_head"))
@@ -2288,41 +2290,35 @@ zfs_blkstats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
return (DCMD_OK);
}
+typedef struct mdb_reference {
+ uintptr_t ref_holder;
+ uintptr_t ref_removed;
+ uint64_t ref_number;
+} mdb_reference_t;
+
/* ARGSUSED */
static int
reference_cb(uintptr_t addr, const void *ignored, void *arg)
{
- static int gotid;
- static mdb_ctf_id_t ref_id;
- uintptr_t ref_holder;
- uintptr_t ref_removed;
- uint64_t ref_number;
+ mdb_reference_t ref;
boolean_t holder_is_str = B_FALSE;
char holder_str[128];
boolean_t removed = (boolean_t)arg;
- if (!gotid) {
- if (mdb_ctf_lookup_by_name("struct reference", &ref_id) == -1) {
- mdb_warn("couldn't find struct reference");
- return (WALK_ERR);
- }
- gotid = TRUE;
- }
-
- if (GETMEMBID(addr, &ref_id, ref_holder, ref_holder) ||
- GETMEMBID(addr, &ref_id, ref_removed, ref_removed) ||
- GETMEMBID(addr, &ref_id, ref_number, ref_number))
- return (WALK_ERR);
+ if (mdb_ctf_vread(&ref, "reference_t", "mdb_reference_t", addr,
+ 0) == -1)
+ return (DCMD_ERR);
- if (mdb_readstr(holder_str, sizeof (holder_str), ref_holder) != -1)
+ if (mdb_readstr(holder_str, sizeof (holder_str),
+ ref.ref_holder) != -1)
holder_is_str = strisprint(holder_str);
if (removed)
mdb_printf("removed ");
mdb_printf("reference ");
- if (ref_number != 1)
- mdb_printf("with count=%llu ", ref_number);
- mdb_printf("with tag %p", (void*)ref_holder);
+ if (ref.ref_number != 1)
+ mdb_printf("with count=%llu ", ref.ref_number);
+ mdb_printf("with tag %lx", ref.ref_holder);
if (holder_is_str)
mdb_printf(" \"%s\"", holder_str);
mdb_printf(", held at:\n");
@@ -2331,7 +2327,7 @@ reference_cb(uintptr_t addr, const void *ignored, void *arg)
if (removed) {
mdb_printf("removed at:\n");
- (void) mdb_call_dcmd("whatis", ref_removed,
+ (void) mdb_call_dcmd("whatis", ref.ref_removed,
DCMD_ADDRSPEC, 0, NULL);
}
@@ -2340,15 +2336,26 @@ reference_cb(uintptr_t addr, const void *ignored, void *arg)
return (WALK_NEXT);
}
+typedef struct mdb_refcount {
+ uint64_t rc_count;
+} mdb_refcount_t;
+
+typedef struct mdb_refcount_removed {
+ uint64_t rc_removed_count;
+} mdb_refcount_removed_t;
+
+typedef struct mdb_refcount_tracked {
+ boolean_t rc_tracked;
+} mdb_refcount_tracked_t;
+
/* ARGSUSED */
static int
refcount(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
- uint64_t rc_count, rc_removed_count;
- uintptr_t rc_list, rc_removed;
- static int gotid;
- static mdb_ctf_id_t rc_id;
- ulong_t off;
+ mdb_refcount_t rc;
+ mdb_refcount_removed_t rcr;
+ mdb_refcount_tracked_t rct;
+ int off;
boolean_t released = B_FALSE;
if (!(flags & DCMD_ADDRSPEC))
@@ -2359,48 +2366,41 @@ refcount(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
NULL) != argc)
return (DCMD_USAGE);
- if (!gotid) {
- /*
- * The refcount structure is different when compiled debug
- * vs nondebug. Therefore, we want to make sure we get the
- * refcount definition from the ZFS module, in case it has
- * been compiled debug but genunix is nondebug.
- */
- if (mdb_ctf_lookup_by_name(ZFS_STRUCT "refcount",
- &rc_id) == -1) {
- mdb_warn("couldn't find struct refcount");
- return (DCMD_ERR);
- }
- gotid = TRUE;
- }
-
- if (GETMEMBID(addr, &rc_id, rc_count, rc_count))
+ if (mdb_ctf_vread(&rc, "refcount_t", "mdb_refcount_t", addr,
+ 0) == -1)
return (DCMD_ERR);
- if (GETMEMBID(addr, &rc_id, rc_removed_count, rc_removed_count)) {
- mdb_printf("refcount_t at %p has %llu current holds\n",
- addr, (longlong_t)rc_count);
+ if (mdb_ctf_vread(&rcr, "refcount_t", "mdb_refcount_removed_t", addr,
+ MDB_CTF_VREAD_QUIET) == -1) {
+ mdb_printf("refcount_t at %p has %llu holds (untracked)\n",
+ addr, (longlong_t)rc.rc_count);
return (DCMD_OK);
}
+ if (mdb_ctf_vread(&rct, "refcount_t", "mdb_refcount_tracked_t", addr,
+ MDB_CTF_VREAD_QUIET) == -1) {
+ /* If this is an old target, it might be tracked. */
+ rct.rc_tracked = B_TRUE;
+ }
+
mdb_printf("refcount_t at %p has %llu current holds, "
"%llu recently released holds\n",
- addr, (longlong_t)rc_count, (longlong_t)rc_removed_count);
+ addr, (longlong_t)rc.rc_count, (longlong_t)rcr.rc_removed_count);
- if (rc_count > 0)
+ if (rct.rc_tracked && rc.rc_count > 0)
mdb_printf("current holds:\n");
- if (mdb_ctf_offsetof(rc_id, "rc_list", &off) == -1)
+ off = mdb_ctf_offsetof_by_name("refcount_t", "rc_list");
+ if (off == -1)
return (DCMD_ERR);
- rc_list = addr + off/NBBY;
- mdb_pwalk("list", reference_cb, (void*)B_FALSE, rc_list);
+ mdb_pwalk("list", reference_cb, (void*)B_FALSE, addr + off);
+
+ if (released && rcr.rc_removed_count > 0) {
+ mdb_printf("released holds:\n");
- if (released) {
- if (rc_removed_count > 0)
- mdb_printf("released holds:\n");
- if (mdb_ctf_offsetof(rc_id, "rc_removed", &off) == -1)
+ off = mdb_ctf_offsetof_by_name("refcount_t", "rc_removed");
+ if (off == -1)
return (DCMD_ERR);
- rc_removed = addr + off/NBBY;
- mdb_pwalk("list", reference_cb, (void*)B_TRUE, rc_removed);
+ mdb_pwalk("list", reference_cb, (void*)B_FALSE, addr + off);
}
return (DCMD_OK);
@@ -3004,7 +3004,7 @@ zfs_aces_walk_step(mdb_walk_state_t *wsp)
}
typedef struct mdb_zfs_rrwlock {
- kthread_t *rr_writer;
+ uintptr_t rr_writer;
boolean_t rr_writer_wanted;
} mdb_zfs_rrwlock_t;
@@ -3025,8 +3025,8 @@ rrwlock(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
0) == -1)
return (DCMD_ERR);
- if (rrw.rr_writer != NULL) {
- mdb_printf("write lock held by thread %p\n", rrw.rr_writer);
+ if (rrw.rr_writer != 0) {
+ mdb_printf("write lock held by thread %lx\n", rrw.rr_writer);
return (DCMD_OK);
}
diff --git a/usr/src/cmd/zdb/zdb.c b/usr/src/cmd/zdb/zdb.c
index d4d32b9996..2ce719d21d 100644
--- a/usr/src/cmd/zdb/zdb.c
+++ b/usr/src/cmd/zdb/zdb.c
@@ -1997,6 +1997,8 @@ typedef struct zdb_blkstats {
uint64_t zb_lsize;
uint64_t zb_psize;
uint64_t zb_count;
+ uint64_t zb_gangs;
+ uint64_t zb_ditto_samevdev;
uint64_t zb_psize_histogram[PSIZE_HISTO_SIZE];
} zdb_blkstats_t;
@@ -2044,6 +2046,7 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
for (int i = 0; i < 4; i++) {
int l = (i < 2) ? BP_GET_LEVEL(bp) : ZB_TOTAL;
int t = (i & 1) ? type : ZDB_OT_TOTAL;
+ int equal;
zdb_blkstats_t *zb = &zcb->zcb_type[l][t];
zb->zb_asize += BP_GET_ASIZE(bp);
@@ -2051,6 +2054,27 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
zb->zb_psize += BP_GET_PSIZE(bp);
zb->zb_count++;
zb->zb_psize_histogram[BP_GET_PSIZE(bp) >> SPA_MINBLOCKSHIFT]++;
+
+ zb->zb_gangs += BP_COUNT_GANG(bp);
+
+ switch (BP_GET_NDVAS(bp)) {
+ case 2:
+ if (DVA_GET_VDEV(&bp->blk_dva[0]) ==
+ DVA_GET_VDEV(&bp->blk_dva[1]))
+ zb->zb_ditto_samevdev++;
+ break;
+ case 3:
+ equal = (DVA_GET_VDEV(&bp->blk_dva[0]) ==
+ DVA_GET_VDEV(&bp->blk_dva[1])) +
+ (DVA_GET_VDEV(&bp->blk_dva[0]) ==
+ DVA_GET_VDEV(&bp->blk_dva[2])) +
+ (DVA_GET_VDEV(&bp->blk_dva[1]) ==
+ DVA_GET_VDEV(&bp->blk_dva[2]));
+ if (equal != 0)
+ zb->zb_ditto_samevdev++;
+ break;
+ }
+
}
if (dump_opt['L'])
@@ -2439,6 +2463,8 @@ dump_block_stats(spa_t *spa)
(void) printf("\n");
(void) printf("\tbp count: %10llu\n",
(u_longlong_t)tzb->zb_count);
+ (void) printf("\tganged count: %10llu\n",
+ (longlong_t)tzb->zb_gangs);
(void) printf("\tbp logical: %10llu avg: %6llu\n",
(u_longlong_t)tzb->zb_lsize,
(u_longlong_t)(tzb->zb_lsize / tzb->zb_count));
@@ -2460,6 +2486,11 @@ dump_block_stats(spa_t *spa)
(void) printf("\tSPA allocated: %10llu used: %5.2f%%\n",
(u_longlong_t)norm_alloc, 100.0 * norm_alloc / norm_space);
+ if (tzb->zb_ditto_samevdev != 0) {
+ (void) printf("\tDittoed blocks on same vdev: %llu\n",
+ (longlong_t)tzb->zb_ditto_samevdev);
+ }
+
if (dump_opt['b'] >= 2) {
int l, t, level;
(void) printf("\nBlocks\tLSIZE\tPSIZE\tASIZE"
@@ -2467,7 +2498,7 @@ dump_block_stats(spa_t *spa)
for (t = 0; t <= ZDB_OT_TOTAL; t++) {
char csize[32], lsize[32], psize[32], asize[32];
- char avg[32];
+ char avg[32], gang[32];
char *typename;
if (t < DMU_OT_NUMTYPES)
@@ -2508,6 +2539,7 @@ dump_block_stats(spa_t *spa)
zdb_nicenum(zb->zb_psize, psize);
zdb_nicenum(zb->zb_asize, asize);
zdb_nicenum(zb->zb_asize / zb->zb_count, avg);
+ zdb_nicenum(zb->zb_gangs, gang);
(void) printf("%6s\t%5s\t%5s\t%5s\t%5s"
"\t%5.2f\t%6.2f\t",
@@ -2521,6 +2553,11 @@ dump_block_stats(spa_t *spa)
(void) printf(" L%d %s\n",
level, typename);
+ if (dump_opt['b'] >= 3 && zb->zb_gangs > 0) {
+ (void) printf("\t number of ganged "
+ "blocks: %s\n", gang);
+ }
+
if (dump_opt['b'] >= 4) {
(void) printf("psize "
"(in 512-byte sectors): "
diff --git a/usr/src/uts/common/fs/zfs/sys/zap.h b/usr/src/uts/common/fs/zfs/sys/zap.h
index 092669c8b3..1e975e99e0 100644
--- a/usr/src/uts/common/fs/zfs/sys/zap.h
+++ b/usr/src/uts/common/fs/zfs/sys/zap.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#ifndef _SYS_ZAP_H
@@ -368,11 +368,6 @@ void zap_cursor_advance(zap_cursor_t *zc);
uint64_t zap_cursor_serialize(zap_cursor_t *zc);
/*
- * Advance the cursor to the attribute having the given key.
- */
-int zap_cursor_move_to_key(zap_cursor_t *zc, const char *name, matchtype_t mt);
-
-/*
* Initialize a zap cursor pointing to the position recorded by
* zap_cursor_serialize (in the "serialized" argument). You can also
* use a "serialized" argument of 0 to start at the beginning of the
diff --git a/usr/src/uts/common/fs/zfs/sys/zap_impl.h b/usr/src/uts/common/fs/zfs/sys/zap_impl.h
index 1dc322e02f..466aab02ba 100644
--- a/usr/src/uts/common/fs/zfs/sys/zap_impl.h
+++ b/usr/src/uts/common/fs/zfs/sys/zap_impl.h
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#ifndef _SYS_ZAP_IMPL_H
@@ -219,7 +220,6 @@ int fzap_add_cd(zap_name_t *zn,
uint64_t integer_size, uint64_t num_integers,
const void *val, uint32_t cd, dmu_tx_t *tx);
void fzap_upgrade(zap_t *zap, dmu_tx_t *tx, zap_flags_t flags);
-int fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/fs/zfs/zap.c b/usr/src/uts/common/fs/zfs/zap.c
index 0e637d56c9..2f4ccfb6ea 100644
--- a/usr/src/uts/common/fs/zfs/zap.c
+++ b/usr/src/uts/common/fs/zfs/zap.c
@@ -1242,31 +1242,6 @@ zap_stats_ptrtbl(zap_t *zap, uint64_t *tbl, int len, zap_stats_t *zs)
}
}
-int
-fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn)
-{
- int err;
- zap_leaf_t *l;
- zap_entry_handle_t zeh;
-
- if (zn->zn_key_orig_numints * zn->zn_key_intlen > ZAP_MAXNAMELEN)
- return (SET_ERROR(ENAMETOOLONG));
-
- err = zap_deref_leaf(zc->zc_zap, zn->zn_hash, NULL, RW_READER, &l);
- if (err != 0)
- return (err);
-
- err = zap_leaf_lookup(l, zn, &zeh);
- if (err != 0)
- return (err);
-
- zc->zc_leaf = l;
- zc->zc_hash = zeh.zeh_hash;
- zc->zc_cd = zeh.zeh_cd;
-
- return (err);
-}
-
void
fzap_get_stats(zap_t *zap, zap_stats_t *zs)
{
diff --git a/usr/src/uts/common/fs/zfs/zap_micro.c b/usr/src/uts/common/fs/zfs/zap_micro.c
index e79038017f..e2fc0118c6 100644
--- a/usr/src/uts/common/fs/zfs/zap_micro.c
+++ b/usr/src/uts/common/fs/zfs/zap_micro.c
@@ -1316,46 +1316,6 @@ zap_cursor_advance(zap_cursor_t *zc)
}
int
-zap_cursor_move_to_key(zap_cursor_t *zc, const char *name, matchtype_t mt)
-{
- int err = 0;
- mzap_ent_t *mze;
- zap_name_t *zn;
-
- if (zc->zc_zap == NULL) {
- err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
- RW_READER, TRUE, FALSE, &zc->zc_zap);
- if (err)
- return (err);
- } else {
- rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
- }
-
- zn = zap_name_alloc(zc->zc_zap, name, mt);
- if (zn == NULL) {
- rw_exit(&zc->zc_zap->zap_rwlock);
- return (SET_ERROR(ENOTSUP));
- }
-
- if (!zc->zc_zap->zap_ismicro) {
- err = fzap_cursor_move_to_key(zc, zn);
- } else {
- mze = mze_find(zn);
- if (mze == NULL) {
- err = SET_ERROR(ENOENT);
- goto out;
- }
- zc->zc_hash = mze->mze_hash;
- zc->zc_cd = mze->mze_cd;
- }
-
-out:
- zap_name_free(zn);
- rw_exit(&zc->zc_zap->zap_rwlock);
- return (err);
-}
-
-int
zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
{
int err;