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