summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2013-04-08 23:48:27 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2013-04-08 23:48:27 +0000
commit3b35eac0fb52dcc3609f7757bf34c82ff92a95c1 (patch)
tree3895191ae52d79e79062faffe5c4c6ed8e5c286a
parent19e0355d7a64b2c771a95292ee26a5935cb39c30 (diff)
parent22ce014825a14b6ce90123db2834a13e343d6caf (diff)
downloadillumos-joyent-3b35eac0fb52dcc3609f7757bf34c82ff92a95c1.tar.gz
[illumos-gate merge]
commit 22ce014825a14b6ce90123db2834a13e343d6caf 3650 mdb global symbol tab completion should find all symbols 3651 mdb_readsym() and friends should find all symbols 3652 convert ::spa and ::spa_vdevs to use mdb_ctf_vread() 3653 userland ::whatis always complains about "umem_internal_arena" symbol commit d5ee8a1311accef11ec2057f70da38d1dd687088 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
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_ctf.c20
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_modapi.c11
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_tab.c2
-rw-r--r--usr/src/cmd/mdb/common/modules/libumem/umem.c1
-rw-r--r--usr/src/cmd/mdb/common/modules/zfs/zfs.c228
-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
10 files changed, 161 insertions, 214 deletions
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c
index b490ca9e2f..3128f95766 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c
@@ -1289,12 +1289,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);
@@ -1306,7 +1300,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:
/*
@@ -1639,7 +1643,7 @@ mdb_ctf_readsym(void *buf, const char *typename, const char *name, uint_t flags)
{
GElf_Sym sym;
- if (mdb_lookup_by_name(name, &sym) != 0) {
+ if (mdb_lookup_by_obj(MDB_TGT_OBJ_EVERY, name, &sym) != 0) {
mdb_ctf_warn(flags, "couldn't find symbol %s\n", name);
return (-1); /* errno is set for us */
}
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_modapi.c b/usr/src/cmd/mdb/common/mdb/mdb_modapi.c
index a79894e80e..a675398302 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_modapi.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_modapi.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#include <mdb/mdb_modapi.h>
@@ -120,7 +121,7 @@ ssize_t
mdb_readsym(void *buf, size_t nbytes, const char *name)
{
ssize_t rbytes = mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT,
- buf, nbytes, MDB_TGT_OBJ_EXEC, name);
+ buf, nbytes, MDB_TGT_OBJ_EVERY, name);
if (rbytes > 0 && rbytes < nbytes)
return (set_errbytes(rbytes, nbytes));
@@ -132,7 +133,7 @@ ssize_t
mdb_writesym(const void *buf, size_t nbytes, const char *name)
{
return (mdb_tgt_writesym(mdb.m_target, MDB_TGT_AS_VIRT,
- buf, nbytes, MDB_TGT_OBJ_EXEC, name));
+ buf, nbytes, MDB_TGT_OBJ_EVERY, name));
}
ssize_t
@@ -140,7 +141,7 @@ mdb_readvar(void *buf, const char *name)
{
GElf_Sym sym;
- if (mdb_tgt_lookup_by_name(mdb.m_target, MDB_TGT_OBJ_EXEC,
+ if (mdb_tgt_lookup_by_name(mdb.m_target, MDB_TGT_OBJ_EVERY,
name, &sym, NULL))
return (-1);
@@ -156,7 +157,7 @@ mdb_writevar(const void *buf, const char *name)
{
GElf_Sym sym;
- if (mdb_tgt_lookup_by_name(mdb.m_target, MDB_TGT_OBJ_EXEC,
+ if (mdb_tgt_lookup_by_name(mdb.m_target, MDB_TGT_OBJ_EVERY,
name, &sym, NULL))
return (-1);
@@ -170,7 +171,7 @@ mdb_writevar(const void *buf, const char *name)
int
mdb_lookup_by_name(const char *name, GElf_Sym *sym)
{
- return (mdb_lookup_by_obj(MDB_TGT_OBJ_EXEC, name, sym));
+ return (mdb_lookup_by_obj(MDB_TGT_OBJ_EVERY, name, sym));
}
int
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_tab.c b/usr/src/cmd/mdb/common/mdb/mdb_tab.c
index e07f8f4065..af5dec943d 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_tab.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_tab.c
@@ -502,7 +502,7 @@ mdb_tab_complete_global(mdb_tab_cookie_t *mcp, const char *name)
{
mdb_tab_setmbase(mcp, name);
(void) mdb_tgt_symbol_iter(mdb.m_target, MDB_TGT_OBJ_EVERY,
- MDB_TGT_SYMTAB, MDB_TGT_BIND_GLOBAL | MDB_TGT_TYPE_OBJECT |
+ MDB_TGT_SYMTAB, MDB_TGT_BIND_ANY | MDB_TGT_TYPE_OBJECT |
MDB_TGT_TYPE_FUNC, tab_complete_global, mcp);
return (0);
}
diff --git a/usr/src/cmd/mdb/common/modules/libumem/umem.c b/usr/src/cmd/mdb/common/modules/libumem/umem.c
index c213e815d9..69b003cc5c 100644
--- a/usr/src/cmd/mdb/common/modules/libumem/umem.c
+++ b/usr/src/cmd/mdb/common/modules/libumem/umem.c
@@ -25,6 +25,7 @@
/*
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#include "umem.h"
diff --git a/usr/src/cmd/mdb/common/modules/zfs/zfs.c b/usr/src/cmd/mdb/common/modules/zfs/zfs.c
index 792c9a1855..b04b05d75a 100644
--- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c
+++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c
@@ -36,7 +36,6 @@
#include <sys/metaslab_impl.h>
#include <sys/space_map.h>
#include <sys/list.h>
-#include <sys/spa_impl.h>
#include <sys/vdev_impl.h>
#include <sys/zap_leaf.h>
#include <sys/zap_impl.h>
@@ -380,7 +379,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 +415,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);
}
@@ -778,7 +777,7 @@ abuf_find(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
}
for (i = 0; i < sizeof (syms) / sizeof (syms[0]); i++) {
- if (mdb_lookup_by_name(syms[i], &sym)) {
+ if (mdb_lookup_by_obj(ZFS_OBJ_NAME, syms[i], &sym)) {
mdb_warn("can't find symbol %s", syms[i]);
return (DCMD_ERR);
}
@@ -896,7 +895,7 @@ arc_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
NULL
};
- if (mdb_lookup_by_name("arc_stats", &sym) == -1) {
+ if (mdb_lookup_by_obj(ZFS_OBJ_NAME, "arc_stats", &sym) == -1) {
mdb_warn("failed to find 'arc_stats'");
return (DCMD_ERR);
}
@@ -963,7 +962,7 @@ arc_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
for (i = 0; extras[i]; i++) {
uint64_t buf;
- if (mdb_lookup_by_name(extras[i], &sym) == -1) {
+ if (mdb_lookup_by_obj(ZFS_OBJ_NAME, extras[i], &sym) == -1) {
mdb_warn("failed to find '%s'", extras[i]);
return (DCMD_ERR);
}
@@ -992,12 +991,17 @@ arc_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
return (DCMD_OK);
}
+typedef struct mdb_spa_print {
+ pool_state_t spa_state;
+ char spa_name[MAXNAMELEN];
+} mdb_spa_print_t;
+
/*
* ::spa
*
- * -c Print configuration information as well
- * -v Print vdev state
- * -e Print vdev error stats
+ * -c Print configuration information as well
+ * -v Print vdev state
+ * -e Print vdev error stats
*
* Print a summarized spa_t. When given no arguments, prints out a table of all
* active pools on the system.
@@ -1006,7 +1010,6 @@ arc_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
static int
spa_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
- spa_t spa;
const char *statetab[] = { "ACTIVE", "EXPORTED", "DESTROYED",
"SPARE", "L2CACHE", "UNINIT", "UNAVAIL", "POTENTIAL" };
const char *state;
@@ -1039,10 +1042,9 @@ spa_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
mdb_printf("%<u>%-?s %9s %-*s%</u>\n", "ADDR", "STATE",
sizeof (uintptr_t) == 4 ? 60 : 52, "NAME");
- if (mdb_vread(&spa, sizeof (spa), addr) == -1) {
- mdb_warn("failed to read spa_t at %p", addr);
+ mdb_spa_print_t spa;
+ if (mdb_ctf_vread(&spa, "spa_t", "mdb_spa_print_t", addr, 0) == -1)
return (DCMD_ERR);
- }
if (spa.spa_state < 0 || spa.spa_state > POOL_STATE_UNAVAIL)
state = "UNKNOWN";
@@ -1078,7 +1080,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 +1103,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));
}
@@ -1577,36 +1579,19 @@ spa_space(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
return (DCMD_OK);
}
-/*
- * ::spa_verify
- *
- * Given a spa_t, verify that that the pool is self-consistent.
- * Currently, it only checks to make sure that the vdev tree exists.
- */
-/* ARGSUSED */
-static int
-spa_verify(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
- spa_t spa;
+typedef struct mdb_spa_aux_vdev {
+ int sav_count;
+ uintptr_t sav_vdevs;
+} mdb_spa_aux_vdev_t;
- if (argc != 0 || !(flags & DCMD_ADDRSPEC))
- return (DCMD_USAGE);
-
- if (mdb_vread(&spa, sizeof (spa), addr) == -1) {
- mdb_warn("failed to read spa_t at %p", addr);
- return (DCMD_ERR);
- }
-
- if (spa.spa_root_vdev == NULL) {
- mdb_printf("no vdev tree present\n");
- return (DCMD_OK);
- }
-
- return (DCMD_OK);
-}
+typedef struct mdb_spa_vdevs {
+ uintptr_t spa_root_vdev;
+ mdb_spa_aux_vdev_t spa_l2cache;
+ mdb_spa_aux_vdev_t spa_spares;
+} mdb_spa_vdevs_t;
static int
-spa_print_aux(spa_aux_vdev_t *sav, uint_t flags, mdb_arg_t *v,
+spa_print_aux(mdb_spa_aux_vdev_t *sav, uint_t flags, mdb_arg_t *v,
const char *name)
{
uintptr_t *aux;
@@ -1627,8 +1612,7 @@ spa_print_aux(spa_aux_vdev_t *sav, uint_t flags, mdb_arg_t *v,
len = sav->sav_count * sizeof (uintptr_t);
aux = mdb_alloc(len, UM_SLEEP);
- if (mdb_vread(aux, len,
- (uintptr_t)sav->sav_vdevs) == -1) {
+ if (mdb_vread(aux, len, sav->sav_vdevs) == -1) {
mdb_free(aux, len);
mdb_warn("failed to read l2cache vdevs at %p",
sav->sav_vdevs);
@@ -1664,7 +1648,6 @@ spa_print_aux(spa_aux_vdev_t *sav, uint_t flags, mdb_arg_t *v,
static int
spa_vdevs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
- spa_t spa;
mdb_arg_t v[3];
int errors = FALSE;
int ret;
@@ -1677,10 +1660,9 @@ spa_vdevs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
- if (mdb_vread(&spa, sizeof (spa), addr) == -1) {
- mdb_warn("failed to read spa_t at %p", addr);
+ mdb_spa_vdevs_t spa;
+ if (mdb_ctf_vread(&spa, "spa_t", "mdb_spa_vdevs_t", addr, 0) == -1)
return (DCMD_ERR);
- }
/*
* Unitialized spa_t structures can have a NULL root vdev.
@@ -1736,11 +1718,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 +1779,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
@@ -2045,14 +2027,7 @@ spa_walk_init(mdb_walk_state_t *wsp)
static int
spa_walk_step(mdb_walk_state_t *wsp)
{
- spa_t spa;
-
- if (mdb_vread(&spa, sizeof (spa), wsp->walk_addr) == -1) {
- mdb_warn("failed to read spa_t at %p", wsp->walk_addr);
- return (WALK_ERR);
- }
-
- return (wsp->walk_callback(wsp->walk_addr, &spa, wsp->walk_cbdata));
+ return (wsp->walk_callback(wsp->walk_addr, NULL, wsp->walk_cbdata));
}
/*
@@ -2065,7 +2040,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 +2054,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 +2075,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 +2265,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 +2302,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 +2311,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 +2341,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 +2979,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 +3000,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);
}
@@ -3077,7 +3052,6 @@ static const mdb_dcmd_t dcmds[] = {
abuf_find },
{ "spa", "?[-cv]", "spa_t summary", spa_print },
{ "spa_config", ":", "print spa_t configuration", spa_print_config },
- { "spa_verify", ":", "verify spa_t consistency", spa_verify },
{ "spa_space", ":[-b]", "print spa_t on-disk space usage", spa_space },
{ "spa_vdevs", ":", "given a spa_t, print vdev summary", spa_vdevs },
{ "vdev", ":[-re]\n"
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;