1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_ZAP_LEAF_H 28 #define _SYS_ZAP_LEAF_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 struct zap; 37 38 #define ZAP_LEAF_MAGIC 0x2AB1EAF 39 40 /* chunk size = 24 bytes */ 41 42 #define ZAP_LEAF_NUMCHUNKS 5118 43 #define ZAP_LEAF_ARRAY_BYTES 21 44 #define ZAP_LEAF_HASH_SHIFT 12 45 #define ZAP_LEAF_HASH_NUMENTRIES (1 << ZAP_LEAF_HASH_SHIFT) 46 #define ZAP_LLA_DATA_BYTES ((1 << ZAP_BLOCK_SHIFT) - 16) 47 48 typedef enum zap_entry_type { 49 ZAP_LEAF_FREE = 253, 50 ZAP_LEAF_ENTRY = 252, 51 ZAP_LEAF_ARRAY = 251, 52 ZAP_LEAF_TYPE_MAX = 250 53 } zap_entry_type_t; 54 55 /* 56 * TAKE NOTE: 57 * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified. 58 */ 59 typedef struct zap_leaf_phys { 60 struct zap_leaf_header { 61 uint64_t lhr_block_type; /* ZBT_LEAF */ 62 uint64_t lhr_next; /* next block in leaf chain */ 63 uint64_t lhr_prefix; 64 uint32_t lhr_magic; /* ZAP_LEAF_MAGIC */ 65 uint16_t lhr_nfree; /* number free chunks */ 66 uint16_t lhr_nentries; /* number of entries */ 67 uint16_t lhr_prefix_len; 68 69 #define lh_block_type l_phys->l_hdr.lhr_block_type 70 #define lh_magic l_phys->l_hdr.lhr_magic 71 #define lh_next l_phys->l_hdr.lhr_next 72 #define lh_prefix l_phys->l_hdr.lhr_prefix 73 #define lh_nfree l_phys->l_hdr.lhr_nfree 74 #define lh_prefix_len l_phys->l_hdr.lhr_prefix_len 75 #define lh_nentries l_phys->l_hdr.lhr_nentries 76 77 /* above is accessable to zap, below is zap_leaf private */ 78 79 uint16_t lh_freelist; /* chunk head of free list */ 80 uint8_t lh_pad2[12]; 81 } l_hdr; /* 2 24-byte chunks */ 82 83 uint16_t l_hash[ZAP_LEAF_HASH_NUMENTRIES]; 84 /* 170 24-byte chunks plus 16 bytes leftover space */ 85 86 union zap_leaf_chunk { 87 struct zap_leaf_entry { 88 uint8_t le_type; /* always ZAP_LEAF_ENTRY */ 89 uint8_t le_int_size; /* size of ints */ 90 uint16_t le_next; /* next entry in hash chain */ 91 uint16_t le_name_chunk; /* first chunk of the name */ 92 uint16_t le_name_length; /* bytes in name, incl null */ 93 uint16_t le_value_chunk; /* first chunk of the value */ 94 uint16_t le_value_length; /* value length in ints */ 95 uint32_t le_cd; /* collision differentiator */ 96 uint64_t le_hash; /* hash value of the name */ 97 } l_entry; 98 struct zap_leaf_array { 99 uint8_t la_type; 100 uint8_t la_array[ZAP_LEAF_ARRAY_BYTES]; 101 uint16_t la_next; /* next blk or CHAIN_END */ 102 } l_array; 103 struct zap_leaf_free { 104 uint8_t lf_type; /* always ZAP_LEAF_FREE */ 105 uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES]; 106 uint16_t lf_next; /* next in free list, or CHAIN_END */ 107 } l_free; 108 } l_chunk[ZAP_LEAF_NUMCHUNKS]; 109 } zap_leaf_phys_t; 110 111 typedef struct zap_leaf { 112 krwlock_t l_rwlock; /* only used on head of chain */ 113 uint64_t l_blkid; /* 1<<ZAP_BLOCK_SHIFT byte block off */ 114 struct zap_leaf *l_next; /* next in chain */ 115 dmu_buf_t *l_dbuf; 116 zap_leaf_phys_t *l_phys; 117 } zap_leaf_t; 118 119 120 typedef struct zap_entry_handle { 121 /* below is set by zap_leaf.c and is public to zap.c */ 122 uint64_t zeh_num_integers; 123 uint64_t zeh_hash; 124 uint32_t zeh_cd; 125 uint8_t zeh_integer_size; 126 127 /* below is private to zap_leaf.c */ 128 uint16_t zeh_fakechunk; 129 uint16_t *zeh_chunkp; 130 zap_leaf_t *zeh_head_leaf; 131 zap_leaf_t *zeh_found_leaf; 132 } zap_entry_handle_t; 133 134 /* 135 * Return a handle to the named entry, or ENOENT if not found. The hash 136 * value must equal zap_hash(name). 137 */ 138 extern int zap_leaf_lookup(zap_leaf_t *l, 139 const char *name, uint64_t h, zap_entry_handle_t *zeh); 140 141 /* 142 * Return a handle to the entry with this hash+cd, or the entry with the 143 * next closest hash+cd. 144 */ 145 extern int zap_leaf_lookup_closest(zap_leaf_t *l, 146 uint64_t hash, uint32_t cd, zap_entry_handle_t *zeh); 147 148 /* 149 * Read the first num_integers in the attribute. Integer size 150 * conversion will be done without sign extension. Return EINVAL if 151 * integer_size is too small. Return EOVERFLOW if there are more than 152 * num_integers in the attribute. 153 */ 154 extern int zap_entry_read(const zap_entry_handle_t *zeh, 155 uint8_t integer_size, uint64_t num_integers, void *buf); 156 157 extern int zap_entry_read_name(const zap_entry_handle_t *zeh, 158 uint16_t buflen, char *buf); 159 160 /* 161 * Replace the value of an existing entry. 162 * 163 * zap_entry_update may fail if it runs out of space (ENOSPC). 164 */ 165 extern int zap_entry_update(zap_entry_handle_t *zeh, 166 uint8_t integer_size, uint64_t num_integers, const void *buf); 167 168 /* 169 * Remove an entry. 170 */ 171 extern void zap_entry_remove(zap_entry_handle_t *zeh); 172 173 /* 174 * Create an entry. An equal entry must not exist, and this entry must 175 * belong in this leaf (according to its hash value). Fills in the 176 * entry handle on success. Returns 0 on success or ENOSPC on failure. 177 */ 178 extern int zap_entry_create(zap_leaf_t *l, 179 const char *name, uint64_t h, uint32_t cd, 180 uint8_t integer_size, uint64_t num_integers, const void *buf, 181 zap_entry_handle_t *zeh); 182 183 /* 184 * Other stuff. 185 */ 186 187 extern void zap_leaf_init(zap_leaf_t *l); 188 extern void zap_leaf_byteswap(zap_leaf_phys_t *buf); 189 190 extern zap_leaf_t *zap_leaf_split(struct zap *zap, zap_leaf_t *l, dmu_tx_t *tx); 191 192 extern int zap_leaf_merge(zap_leaf_t *l, zap_leaf_t *sibling); 193 194 extern zap_leaf_t *zap_leaf_chainmore(zap_leaf_t *l, zap_leaf_t *nl); 195 196 extern int zap_leaf_advance(zap_leaf_t *l, zap_cursor_t *zc); 197 198 extern void zap_stats_leaf(zap_t *zap, zap_leaf_t *l, zap_stats_t *zs); 199 200 #ifdef __cplusplus 201 } 202 #endif 203 204 #endif /* _SYS_ZAP_LEAF_H */ 205