1e0687fa3SGordon Ross /*
2e0687fa3SGordon Ross  * This file and its contents are supplied under the terms of the
3e0687fa3SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4e0687fa3SGordon Ross  * You may only use this file in accordance with the terms of version
5e0687fa3SGordon Ross  * 1.0 of the CDDL.
6e0687fa3SGordon Ross  *
7e0687fa3SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8e0687fa3SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9e0687fa3SGordon Ross  * http://www.illumos.org/license/CDDL.
10e0687fa3SGordon Ross  */
11e0687fa3SGordon Ross 
12e0687fa3SGordon Ross /*
13e0687fa3SGordon Ross  * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
14e0687fa3SGordon Ross  */
15e0687fa3SGordon Ross 
16e0687fa3SGordon Ross /*
17e0687fa3SGordon Ross  * walker for libsmb : smb_ht.c (hash tables)
18e0687fa3SGordon Ross  */
19e0687fa3SGordon Ross 
20e0687fa3SGordon Ross #include <mdb/mdb_modapi.h>
21e0687fa3SGordon Ross #include <mdb/mdb_ks.h>
22e0687fa3SGordon Ross #include <mdb/mdb_ctf.h>
23e0687fa3SGordon Ross 
24e0687fa3SGordon Ross #include <smbsrv/hash_table.h>
25e0687fa3SGordon Ross 
26e0687fa3SGordon Ross /* smb_ht_walk info */
27e0687fa3SGordon Ross struct hw_info {
28e0687fa3SGordon Ross 	HT_HANDLE hw_handle;	/* struct ht_handle being walked */
29e0687fa3SGordon Ross 	HT_TABLE_ENTRY hw_tblent;
30e0687fa3SGordon Ross 	HT_ITEM hw_item;
31e0687fa3SGordon Ross 	int hw_idx;
32e0687fa3SGordon Ross };
33e0687fa3SGordon Ross 
34e0687fa3SGordon Ross /*
35e0687fa3SGordon Ross  * Walker for libsmb/smb_ht.c code.  Calls the call-back function with
36e0687fa3SGordon Ross  * each HT_ITEM object.  Top-level is HT_HANDLE, passed to _walk_init.
37e0687fa3SGordon Ross  */
38e0687fa3SGordon Ross int
smb_ht_walk_init(mdb_walk_state_t * wsp)39e0687fa3SGordon Ross smb_ht_walk_init(mdb_walk_state_t *wsp)
40e0687fa3SGordon Ross {
41e0687fa3SGordon Ross 	struct hw_info *hw;
42e0687fa3SGordon Ross 	uintptr_t addr = wsp->walk_addr;
43e0687fa3SGordon Ross 	HT_HANDLE *ht;
44e0687fa3SGordon Ross 
45*cc3780e6SGordon Ross 	if (addr == 0) {
46e0687fa3SGordon Ross 		mdb_printf("require address of an HT_HANDLE\n");
47e0687fa3SGordon Ross 		return (WALK_ERR);
48e0687fa3SGordon Ross 	}
49e0687fa3SGordon Ross 
50e0687fa3SGordon Ross 	/*
51e0687fa3SGordon Ross 	 * allocate the AVL walk data
52e0687fa3SGordon Ross 	 */
53e0687fa3SGordon Ross 	wsp->walk_data = hw = mdb_zalloc(sizeof (*hw), UM_GC|UM_SLEEP);
54e0687fa3SGordon Ross 
55e0687fa3SGordon Ross 	/*
56e0687fa3SGordon Ross 	 * get an mdb copy of the HT_HANDLE being walked
57e0687fa3SGordon Ross 	 */
58e0687fa3SGordon Ross 	ht = &hw->hw_handle;
59e0687fa3SGordon Ross 	if (mdb_vread(ht, sizeof (*ht), wsp->walk_addr) == -1) {
60e0687fa3SGordon Ross 		mdb_warn("failed to read %s at %#lx",
61e0687fa3SGordon Ross 		    "HT_HANDLE", wsp->walk_addr);
62e0687fa3SGordon Ross 		return (WALK_ERR);
63e0687fa3SGordon Ross 	}
64e0687fa3SGordon Ross 
65e0687fa3SGordon Ross 	hw->hw_idx = -1;
66*cc3780e6SGordon Ross 	wsp->walk_addr = 0;
67e0687fa3SGordon Ross 	wsp->walk_data = hw;
68e0687fa3SGordon Ross 
69e0687fa3SGordon Ross 	return (WALK_NEXT);
70e0687fa3SGordon Ross }
71e0687fa3SGordon Ross 
72e0687fa3SGordon Ross int
smb_ht_walk_step(mdb_walk_state_t * wsp)73e0687fa3SGordon Ross smb_ht_walk_step(mdb_walk_state_t *wsp)
74e0687fa3SGordon Ross {
75e0687fa3SGordon Ross 	struct hw_info *hw = wsp->walk_data;
76e0687fa3SGordon Ross 	HT_TABLE_ENTRY *he = &hw->hw_tblent;
77e0687fa3SGordon Ross 	HT_ITEM *hi = &hw->hw_item;
78e0687fa3SGordon Ross 	uintptr_t he_addr;
79e0687fa3SGordon Ross 	int rv;
80e0687fa3SGordon Ross 
81*cc3780e6SGordon Ross 	while (wsp->walk_addr == 0) {
82e0687fa3SGordon Ross 		if (++hw->hw_idx >= hw->hw_handle.ht_table_size)
83e0687fa3SGordon Ross 			return (WALK_DONE);
84e0687fa3SGordon Ross 		he_addr = (uintptr_t)hw->hw_handle.ht_table +
85e0687fa3SGordon Ross 		    (hw->hw_idx * sizeof (HT_TABLE_ENTRY));
86e0687fa3SGordon Ross 		if (mdb_vread(he, sizeof (*he), he_addr) == -1) {
87e0687fa3SGordon Ross 			mdb_warn("failed to read %s at %p",
88e0687fa3SGordon Ross 			    "HT_TABLE_ENTRY", wsp->walk_addr);
89e0687fa3SGordon Ross 			return (WALK_ERR);
90e0687fa3SGordon Ross 		}
91e0687fa3SGordon Ross 		wsp->walk_addr = (uintptr_t)he->he_head;
92e0687fa3SGordon Ross 	}
93e0687fa3SGordon Ross 
94e0687fa3SGordon Ross 	if (mdb_vread(hi, sizeof (*hi), wsp->walk_addr) == -1) {
95e0687fa3SGordon Ross 		mdb_warn("failed to read %s at %p",
96e0687fa3SGordon Ross 		    "HT_ITEM", wsp->walk_addr);
97e0687fa3SGordon Ross 		return (WALK_ERR);
98e0687fa3SGordon Ross 	}
99e0687fa3SGordon Ross 
100e0687fa3SGordon Ross 	rv = wsp->walk_callback(wsp->walk_addr, hi,
101e0687fa3SGordon Ross 	    wsp->walk_cbdata);
102e0687fa3SGordon Ross 
103e0687fa3SGordon Ross 	wsp->walk_addr = (uintptr_t)hi->hi_next;
104e0687fa3SGordon Ross 
105e0687fa3SGordon Ross 	return (rv);
106e0687fa3SGordon Ross }
107