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