# HG changeset patch # User Jason King # Date 1580502313 21600 # Node ID cefa3fedc6e33d76b832b29e3997403ee8dea4da # Parent 96bdb88b33c498b35a9bbaa7b5a558e4cfd0c064 12269 mdb multilist walker should be a layered walker Reviewed by: Kody Kantor Reviewed by: Jerry Jelinek Approved by: Dan McDonald diff -r 96bdb88b33c4 -r cefa3fedc6e3 usr/src/cmd/mdb/common/modules/zfs/zfs.c --- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c Sun Feb 02 20:37:22 2020 +0200 +++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c Fri Jan 31 14:25:13 2020 -0600 @@ -22,7 +22,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2011, 2018 by Delphix. All rights reserved. - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ /* Portions Copyright 2010 Robert Milkowski */ @@ -2869,61 +2869,57 @@ uintptr_t ml_sublists; } mdb_multilist_t; -typedef struct multilist_walk_data { - uint64_t mwd_idx; - mdb_multilist_t mwd_ml; -} multilist_walk_data_t; - -/* ARGSUSED */ -static int -multilist_print_cb(uintptr_t addr, const void *unknown, void *arg) -{ - mdb_printf("%#lr\n", addr); - return (WALK_NEXT); -} - static int multilist_walk_step(mdb_walk_state_t *wsp) { - multilist_walk_data_t *mwd = wsp->walk_data; - - if (mwd->mwd_idx >= mwd->mwd_ml.ml_num_sublists) - return (WALK_DONE); - - wsp->walk_addr = mwd->mwd_ml.ml_sublists + - mdb_ctf_sizeof_by_name("multilist_sublist_t") * mwd->mwd_idx + - mdb_ctf_offsetof_by_name("multilist_sublist_t", "mls_list"); - - mdb_pwalk("list", multilist_print_cb, (void*)NULL, wsp->walk_addr); - mwd->mwd_idx++; - - return (WALK_NEXT); + return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, + wsp->walk_cbdata)); } static int multilist_walk_init(mdb_walk_state_t *wsp) { - multilist_walk_data_t *mwd; + mdb_multilist_t ml; + ssize_t sublist_sz; + int list_offset; + size_t i; if (wsp->walk_addr == 0) { mdb_warn("must supply address of multilist_t\n"); return (WALK_ERR); } - mwd = mdb_zalloc(sizeof (multilist_walk_data_t), UM_SLEEP | UM_GC); - if (mdb_ctf_vread(&mwd->mwd_ml, "multilist_t", "mdb_multilist_t", + if (mdb_ctf_vread(&ml, "multilist_t", "mdb_multilist_t", wsp->walk_addr, 0) == -1) { return (WALK_ERR); } - if (mwd->mwd_ml.ml_num_sublists == 0 || - mwd->mwd_ml.ml_sublists == 0) { + if (ml.ml_num_sublists == 0 || ml.ml_sublists == 0) { mdb_warn("invalid or uninitialized multilist at %#lx\n", wsp->walk_addr); return (WALK_ERR); } - wsp->walk_data = mwd; + /* mdb_ctf_sizeof_by_name() will print an error for us */ + sublist_sz = mdb_ctf_sizeof_by_name("multilist_sublist_t"); + if (sublist_sz == -1) + return (WALK_ERR); + + /* mdb_ctf_offsetof_by_name will print an error for us */ + list_offset = mdb_ctf_offsetof_by_name("multilist_sublist_t", + "mls_list"); + if (list_offset == -1) + return (WALK_ERR); + + for (i = 0; i < ml.ml_num_sublists; i++) { + wsp->walk_addr = ml.ml_sublists + i * sublist_sz + list_offset; + + if (mdb_layered_walk("list", wsp) == -1) { + mdb_warn("can't walk multilist sublist"); + return (WALK_ERR); + } + } + return (WALK_NEXT); }