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 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 == NULL) { 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 = NULL; 67 wsp->walk_data = hw; 68 69 return (WALK_NEXT); 70 } 71 72 int 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 == NULL) { 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