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