1*eda14cbcSMatt Macy /* 2*eda14cbcSMatt Macy * CDDL HEADER START 3*eda14cbcSMatt Macy * 4*eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5*eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6*eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7*eda14cbcSMatt Macy * 8*eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*eda14cbcSMatt Macy * or http://www.opensolaris.org/os/licensing. 10*eda14cbcSMatt Macy * See the License for the specific language governing permissions 11*eda14cbcSMatt Macy * and limitations under the License. 12*eda14cbcSMatt Macy * 13*eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14*eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16*eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17*eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18*eda14cbcSMatt Macy * 19*eda14cbcSMatt Macy * CDDL HEADER END 20*eda14cbcSMatt Macy */ 21*eda14cbcSMatt Macy 22*eda14cbcSMatt Macy /* 23*eda14cbcSMatt Macy * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24*eda14cbcSMatt Macy * Copyright (c) 2013, 2016 by Delphix. All rights reserved. 25*eda14cbcSMatt Macy * Copyright 2017 Nexenta Systems, Inc. 26*eda14cbcSMatt Macy */ 27*eda14cbcSMatt Macy 28*eda14cbcSMatt Macy /* 29*eda14cbcSMatt Macy * The 512-byte leaf is broken into 32 16-byte chunks. 30*eda14cbcSMatt Macy * chunk number n means l_chunk[n], even though the header precedes it. 31*eda14cbcSMatt Macy * the names are stored null-terminated. 32*eda14cbcSMatt Macy */ 33*eda14cbcSMatt Macy 34*eda14cbcSMatt Macy #include <sys/zio.h> 35*eda14cbcSMatt Macy #include <sys/spa.h> 36*eda14cbcSMatt Macy #include <sys/dmu.h> 37*eda14cbcSMatt Macy #include <sys/zfs_context.h> 38*eda14cbcSMatt Macy #include <sys/fs/zfs.h> 39*eda14cbcSMatt Macy #include <sys/zap.h> 40*eda14cbcSMatt Macy #include <sys/zap_impl.h> 41*eda14cbcSMatt Macy #include <sys/zap_leaf.h> 42*eda14cbcSMatt Macy #include <sys/arc.h> 43*eda14cbcSMatt Macy 44*eda14cbcSMatt Macy static uint16_t *zap_leaf_rehash_entry(zap_leaf_t *l, uint16_t entry); 45*eda14cbcSMatt Macy 46*eda14cbcSMatt Macy #define CHAIN_END 0xffff /* end of the chunk chain */ 47*eda14cbcSMatt Macy 48*eda14cbcSMatt Macy #define LEAF_HASH(l, h) \ 49*eda14cbcSMatt Macy ((ZAP_LEAF_HASH_NUMENTRIES(l)-1) & \ 50*eda14cbcSMatt Macy ((h) >> \ 51*eda14cbcSMatt Macy (64 - ZAP_LEAF_HASH_SHIFT(l) - zap_leaf_phys(l)->l_hdr.lh_prefix_len))) 52*eda14cbcSMatt Macy 53*eda14cbcSMatt Macy #define LEAF_HASH_ENTPTR(l, h) (&zap_leaf_phys(l)->l_hash[LEAF_HASH(l, h)]) 54*eda14cbcSMatt Macy 55*eda14cbcSMatt Macy extern inline zap_leaf_phys_t *zap_leaf_phys(zap_leaf_t *l); 56*eda14cbcSMatt Macy 57*eda14cbcSMatt Macy static void 58*eda14cbcSMatt Macy zap_memset(void *a, int c, size_t n) 59*eda14cbcSMatt Macy { 60*eda14cbcSMatt Macy char *cp = a; 61*eda14cbcSMatt Macy char *cpend = cp + n; 62*eda14cbcSMatt Macy 63*eda14cbcSMatt Macy while (cp < cpend) 64*eda14cbcSMatt Macy *cp++ = c; 65*eda14cbcSMatt Macy } 66*eda14cbcSMatt Macy 67*eda14cbcSMatt Macy static void 68*eda14cbcSMatt Macy stv(int len, void *addr, uint64_t value) 69*eda14cbcSMatt Macy { 70*eda14cbcSMatt Macy switch (len) { 71*eda14cbcSMatt Macy case 1: 72*eda14cbcSMatt Macy *(uint8_t *)addr = value; 73*eda14cbcSMatt Macy return; 74*eda14cbcSMatt Macy case 2: 75*eda14cbcSMatt Macy *(uint16_t *)addr = value; 76*eda14cbcSMatt Macy return; 77*eda14cbcSMatt Macy case 4: 78*eda14cbcSMatt Macy *(uint32_t *)addr = value; 79*eda14cbcSMatt Macy return; 80*eda14cbcSMatt Macy case 8: 81*eda14cbcSMatt Macy *(uint64_t *)addr = value; 82*eda14cbcSMatt Macy return; 83*eda14cbcSMatt Macy default: 84*eda14cbcSMatt Macy cmn_err(CE_PANIC, "bad int len %d", len); 85*eda14cbcSMatt Macy } 86*eda14cbcSMatt Macy } 87*eda14cbcSMatt Macy 88*eda14cbcSMatt Macy static uint64_t 89*eda14cbcSMatt Macy ldv(int len, const void *addr) 90*eda14cbcSMatt Macy { 91*eda14cbcSMatt Macy switch (len) { 92*eda14cbcSMatt Macy case 1: 93*eda14cbcSMatt Macy return (*(uint8_t *)addr); 94*eda14cbcSMatt Macy case 2: 95*eda14cbcSMatt Macy return (*(uint16_t *)addr); 96*eda14cbcSMatt Macy case 4: 97*eda14cbcSMatt Macy return (*(uint32_t *)addr); 98*eda14cbcSMatt Macy case 8: 99*eda14cbcSMatt Macy return (*(uint64_t *)addr); 100*eda14cbcSMatt Macy default: 101*eda14cbcSMatt Macy cmn_err(CE_PANIC, "bad int len %d", len); 102*eda14cbcSMatt Macy } 103*eda14cbcSMatt Macy return (0xFEEDFACEDEADBEEFULL); 104*eda14cbcSMatt Macy } 105*eda14cbcSMatt Macy 106*eda14cbcSMatt Macy void 107*eda14cbcSMatt Macy zap_leaf_byteswap(zap_leaf_phys_t *buf, int size) 108*eda14cbcSMatt Macy { 109*eda14cbcSMatt Macy zap_leaf_t l; 110*eda14cbcSMatt Macy dmu_buf_t l_dbuf; 111*eda14cbcSMatt Macy 112*eda14cbcSMatt Macy l_dbuf.db_data = buf; 113*eda14cbcSMatt Macy l.l_bs = highbit64(size) - 1; 114*eda14cbcSMatt Macy l.l_dbuf = &l_dbuf; 115*eda14cbcSMatt Macy 116*eda14cbcSMatt Macy buf->l_hdr.lh_block_type = BSWAP_64(buf->l_hdr.lh_block_type); 117*eda14cbcSMatt Macy buf->l_hdr.lh_prefix = BSWAP_64(buf->l_hdr.lh_prefix); 118*eda14cbcSMatt Macy buf->l_hdr.lh_magic = BSWAP_32(buf->l_hdr.lh_magic); 119*eda14cbcSMatt Macy buf->l_hdr.lh_nfree = BSWAP_16(buf->l_hdr.lh_nfree); 120*eda14cbcSMatt Macy buf->l_hdr.lh_nentries = BSWAP_16(buf->l_hdr.lh_nentries); 121*eda14cbcSMatt Macy buf->l_hdr.lh_prefix_len = BSWAP_16(buf->l_hdr.lh_prefix_len); 122*eda14cbcSMatt Macy buf->l_hdr.lh_freelist = BSWAP_16(buf->l_hdr.lh_freelist); 123*eda14cbcSMatt Macy 124*eda14cbcSMatt Macy for (int i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(&l); i++) 125*eda14cbcSMatt Macy buf->l_hash[i] = BSWAP_16(buf->l_hash[i]); 126*eda14cbcSMatt Macy 127*eda14cbcSMatt Macy for (int i = 0; i < ZAP_LEAF_NUMCHUNKS(&l); i++) { 128*eda14cbcSMatt Macy zap_leaf_chunk_t *lc = &ZAP_LEAF_CHUNK(&l, i); 129*eda14cbcSMatt Macy struct zap_leaf_entry *le; 130*eda14cbcSMatt Macy 131*eda14cbcSMatt Macy switch (lc->l_free.lf_type) { 132*eda14cbcSMatt Macy case ZAP_CHUNK_ENTRY: 133*eda14cbcSMatt Macy le = &lc->l_entry; 134*eda14cbcSMatt Macy 135*eda14cbcSMatt Macy le->le_type = BSWAP_8(le->le_type); 136*eda14cbcSMatt Macy le->le_value_intlen = BSWAP_8(le->le_value_intlen); 137*eda14cbcSMatt Macy le->le_next = BSWAP_16(le->le_next); 138*eda14cbcSMatt Macy le->le_name_chunk = BSWAP_16(le->le_name_chunk); 139*eda14cbcSMatt Macy le->le_name_numints = BSWAP_16(le->le_name_numints); 140*eda14cbcSMatt Macy le->le_value_chunk = BSWAP_16(le->le_value_chunk); 141*eda14cbcSMatt Macy le->le_value_numints = BSWAP_16(le->le_value_numints); 142*eda14cbcSMatt Macy le->le_cd = BSWAP_32(le->le_cd); 143*eda14cbcSMatt Macy le->le_hash = BSWAP_64(le->le_hash); 144*eda14cbcSMatt Macy break; 145*eda14cbcSMatt Macy case ZAP_CHUNK_FREE: 146*eda14cbcSMatt Macy lc->l_free.lf_type = BSWAP_8(lc->l_free.lf_type); 147*eda14cbcSMatt Macy lc->l_free.lf_next = BSWAP_16(lc->l_free.lf_next); 148*eda14cbcSMatt Macy break; 149*eda14cbcSMatt Macy case ZAP_CHUNK_ARRAY: 150*eda14cbcSMatt Macy lc->l_array.la_type = BSWAP_8(lc->l_array.la_type); 151*eda14cbcSMatt Macy lc->l_array.la_next = BSWAP_16(lc->l_array.la_next); 152*eda14cbcSMatt Macy /* la_array doesn't need swapping */ 153*eda14cbcSMatt Macy break; 154*eda14cbcSMatt Macy default: 155*eda14cbcSMatt Macy cmn_err(CE_PANIC, "bad leaf type %d", 156*eda14cbcSMatt Macy lc->l_free.lf_type); 157*eda14cbcSMatt Macy } 158*eda14cbcSMatt Macy } 159*eda14cbcSMatt Macy } 160*eda14cbcSMatt Macy 161*eda14cbcSMatt Macy void 162*eda14cbcSMatt Macy zap_leaf_init(zap_leaf_t *l, boolean_t sort) 163*eda14cbcSMatt Macy { 164*eda14cbcSMatt Macy l->l_bs = highbit64(l->l_dbuf->db_size) - 1; 165*eda14cbcSMatt Macy zap_memset(&zap_leaf_phys(l)->l_hdr, 0, 166*eda14cbcSMatt Macy sizeof (struct zap_leaf_header)); 167*eda14cbcSMatt Macy zap_memset(zap_leaf_phys(l)->l_hash, CHAIN_END, 168*eda14cbcSMatt Macy 2*ZAP_LEAF_HASH_NUMENTRIES(l)); 169*eda14cbcSMatt Macy for (int i = 0; i < ZAP_LEAF_NUMCHUNKS(l); i++) { 170*eda14cbcSMatt Macy ZAP_LEAF_CHUNK(l, i).l_free.lf_type = ZAP_CHUNK_FREE; 171*eda14cbcSMatt Macy ZAP_LEAF_CHUNK(l, i).l_free.lf_next = i+1; 172*eda14cbcSMatt Macy } 173*eda14cbcSMatt Macy ZAP_LEAF_CHUNK(l, ZAP_LEAF_NUMCHUNKS(l)-1).l_free.lf_next = CHAIN_END; 174*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_block_type = ZBT_LEAF; 175*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_magic = ZAP_LEAF_MAGIC; 176*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_nfree = ZAP_LEAF_NUMCHUNKS(l); 177*eda14cbcSMatt Macy if (sort) 178*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_flags |= ZLF_ENTRIES_CDSORTED; 179*eda14cbcSMatt Macy } 180*eda14cbcSMatt Macy 181*eda14cbcSMatt Macy /* 182*eda14cbcSMatt Macy * Routines which manipulate leaf chunks (l_chunk[]). 183*eda14cbcSMatt Macy */ 184*eda14cbcSMatt Macy 185*eda14cbcSMatt Macy static uint16_t 186*eda14cbcSMatt Macy zap_leaf_chunk_alloc(zap_leaf_t *l) 187*eda14cbcSMatt Macy { 188*eda14cbcSMatt Macy ASSERT(zap_leaf_phys(l)->l_hdr.lh_nfree > 0); 189*eda14cbcSMatt Macy 190*eda14cbcSMatt Macy int chunk = zap_leaf_phys(l)->l_hdr.lh_freelist; 191*eda14cbcSMatt Macy ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); 192*eda14cbcSMatt Macy ASSERT3U(ZAP_LEAF_CHUNK(l, chunk).l_free.lf_type, ==, ZAP_CHUNK_FREE); 193*eda14cbcSMatt Macy 194*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_freelist = 195*eda14cbcSMatt Macy ZAP_LEAF_CHUNK(l, chunk).l_free.lf_next; 196*eda14cbcSMatt Macy 197*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_nfree--; 198*eda14cbcSMatt Macy 199*eda14cbcSMatt Macy return (chunk); 200*eda14cbcSMatt Macy } 201*eda14cbcSMatt Macy 202*eda14cbcSMatt Macy static void 203*eda14cbcSMatt Macy zap_leaf_chunk_free(zap_leaf_t *l, uint16_t chunk) 204*eda14cbcSMatt Macy { 205*eda14cbcSMatt Macy struct zap_leaf_free *zlf = &ZAP_LEAF_CHUNK(l, chunk).l_free; 206*eda14cbcSMatt Macy ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_nfree, <, ZAP_LEAF_NUMCHUNKS(l)); 207*eda14cbcSMatt Macy ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); 208*eda14cbcSMatt Macy ASSERT(zlf->lf_type != ZAP_CHUNK_FREE); 209*eda14cbcSMatt Macy 210*eda14cbcSMatt Macy zlf->lf_type = ZAP_CHUNK_FREE; 211*eda14cbcSMatt Macy zlf->lf_next = zap_leaf_phys(l)->l_hdr.lh_freelist; 212*eda14cbcSMatt Macy bzero(zlf->lf_pad, sizeof (zlf->lf_pad)); /* help it to compress */ 213*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_freelist = chunk; 214*eda14cbcSMatt Macy 215*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_nfree++; 216*eda14cbcSMatt Macy } 217*eda14cbcSMatt Macy 218*eda14cbcSMatt Macy /* 219*eda14cbcSMatt Macy * Routines which manipulate leaf arrays (zap_leaf_array type chunks). 220*eda14cbcSMatt Macy */ 221*eda14cbcSMatt Macy 222*eda14cbcSMatt Macy static uint16_t 223*eda14cbcSMatt Macy zap_leaf_array_create(zap_leaf_t *l, const char *buf, 224*eda14cbcSMatt Macy int integer_size, int num_integers) 225*eda14cbcSMatt Macy { 226*eda14cbcSMatt Macy uint16_t chunk_head; 227*eda14cbcSMatt Macy uint16_t *chunkp = &chunk_head; 228*eda14cbcSMatt Macy int byten = 0; 229*eda14cbcSMatt Macy uint64_t value = 0; 230*eda14cbcSMatt Macy int shift = (integer_size - 1) * 8; 231*eda14cbcSMatt Macy int len = num_integers; 232*eda14cbcSMatt Macy 233*eda14cbcSMatt Macy ASSERT3U(num_integers * integer_size, <=, ZAP_MAXVALUELEN); 234*eda14cbcSMatt Macy 235*eda14cbcSMatt Macy while (len > 0) { 236*eda14cbcSMatt Macy uint16_t chunk = zap_leaf_chunk_alloc(l); 237*eda14cbcSMatt Macy struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array; 238*eda14cbcSMatt Macy 239*eda14cbcSMatt Macy la->la_type = ZAP_CHUNK_ARRAY; 240*eda14cbcSMatt Macy for (int i = 0; i < ZAP_LEAF_ARRAY_BYTES; i++) { 241*eda14cbcSMatt Macy if (byten == 0) 242*eda14cbcSMatt Macy value = ldv(integer_size, buf); 243*eda14cbcSMatt Macy la->la_array[i] = value >> shift; 244*eda14cbcSMatt Macy value <<= 8; 245*eda14cbcSMatt Macy if (++byten == integer_size) { 246*eda14cbcSMatt Macy byten = 0; 247*eda14cbcSMatt Macy buf += integer_size; 248*eda14cbcSMatt Macy if (--len == 0) 249*eda14cbcSMatt Macy break; 250*eda14cbcSMatt Macy } 251*eda14cbcSMatt Macy } 252*eda14cbcSMatt Macy 253*eda14cbcSMatt Macy *chunkp = chunk; 254*eda14cbcSMatt Macy chunkp = &la->la_next; 255*eda14cbcSMatt Macy } 256*eda14cbcSMatt Macy *chunkp = CHAIN_END; 257*eda14cbcSMatt Macy 258*eda14cbcSMatt Macy return (chunk_head); 259*eda14cbcSMatt Macy } 260*eda14cbcSMatt Macy 261*eda14cbcSMatt Macy static void 262*eda14cbcSMatt Macy zap_leaf_array_free(zap_leaf_t *l, uint16_t *chunkp) 263*eda14cbcSMatt Macy { 264*eda14cbcSMatt Macy uint16_t chunk = *chunkp; 265*eda14cbcSMatt Macy 266*eda14cbcSMatt Macy *chunkp = CHAIN_END; 267*eda14cbcSMatt Macy 268*eda14cbcSMatt Macy while (chunk != CHAIN_END) { 269*eda14cbcSMatt Macy int nextchunk = ZAP_LEAF_CHUNK(l, chunk).l_array.la_next; 270*eda14cbcSMatt Macy ASSERT3U(ZAP_LEAF_CHUNK(l, chunk).l_array.la_type, ==, 271*eda14cbcSMatt Macy ZAP_CHUNK_ARRAY); 272*eda14cbcSMatt Macy zap_leaf_chunk_free(l, chunk); 273*eda14cbcSMatt Macy chunk = nextchunk; 274*eda14cbcSMatt Macy } 275*eda14cbcSMatt Macy } 276*eda14cbcSMatt Macy 277*eda14cbcSMatt Macy /* array_len and buf_len are in integers, not bytes */ 278*eda14cbcSMatt Macy static void 279*eda14cbcSMatt Macy zap_leaf_array_read(zap_leaf_t *l, uint16_t chunk, 280*eda14cbcSMatt Macy int array_int_len, int array_len, int buf_int_len, uint64_t buf_len, 281*eda14cbcSMatt Macy void *buf) 282*eda14cbcSMatt Macy { 283*eda14cbcSMatt Macy int len = MIN(array_len, buf_len); 284*eda14cbcSMatt Macy int byten = 0; 285*eda14cbcSMatt Macy uint64_t value = 0; 286*eda14cbcSMatt Macy char *p = buf; 287*eda14cbcSMatt Macy 288*eda14cbcSMatt Macy ASSERT3U(array_int_len, <=, buf_int_len); 289*eda14cbcSMatt Macy 290*eda14cbcSMatt Macy /* Fast path for one 8-byte integer */ 291*eda14cbcSMatt Macy if (array_int_len == 8 && buf_int_len == 8 && len == 1) { 292*eda14cbcSMatt Macy struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array; 293*eda14cbcSMatt Macy uint8_t *ip = la->la_array; 294*eda14cbcSMatt Macy uint64_t *buf64 = buf; 295*eda14cbcSMatt Macy 296*eda14cbcSMatt Macy *buf64 = (uint64_t)ip[0] << 56 | (uint64_t)ip[1] << 48 | 297*eda14cbcSMatt Macy (uint64_t)ip[2] << 40 | (uint64_t)ip[3] << 32 | 298*eda14cbcSMatt Macy (uint64_t)ip[4] << 24 | (uint64_t)ip[5] << 16 | 299*eda14cbcSMatt Macy (uint64_t)ip[6] << 8 | (uint64_t)ip[7]; 300*eda14cbcSMatt Macy return; 301*eda14cbcSMatt Macy } 302*eda14cbcSMatt Macy 303*eda14cbcSMatt Macy /* Fast path for an array of 1-byte integers (eg. the entry name) */ 304*eda14cbcSMatt Macy if (array_int_len == 1 && buf_int_len == 1 && 305*eda14cbcSMatt Macy buf_len > array_len + ZAP_LEAF_ARRAY_BYTES) { 306*eda14cbcSMatt Macy while (chunk != CHAIN_END) { 307*eda14cbcSMatt Macy struct zap_leaf_array *la = 308*eda14cbcSMatt Macy &ZAP_LEAF_CHUNK(l, chunk).l_array; 309*eda14cbcSMatt Macy bcopy(la->la_array, p, ZAP_LEAF_ARRAY_BYTES); 310*eda14cbcSMatt Macy p += ZAP_LEAF_ARRAY_BYTES; 311*eda14cbcSMatt Macy chunk = la->la_next; 312*eda14cbcSMatt Macy } 313*eda14cbcSMatt Macy return; 314*eda14cbcSMatt Macy } 315*eda14cbcSMatt Macy 316*eda14cbcSMatt Macy while (len > 0) { 317*eda14cbcSMatt Macy struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array; 318*eda14cbcSMatt Macy 319*eda14cbcSMatt Macy ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); 320*eda14cbcSMatt Macy for (int i = 0; i < ZAP_LEAF_ARRAY_BYTES && len > 0; i++) { 321*eda14cbcSMatt Macy value = (value << 8) | la->la_array[i]; 322*eda14cbcSMatt Macy byten++; 323*eda14cbcSMatt Macy if (byten == array_int_len) { 324*eda14cbcSMatt Macy stv(buf_int_len, p, value); 325*eda14cbcSMatt Macy byten = 0; 326*eda14cbcSMatt Macy len--; 327*eda14cbcSMatt Macy if (len == 0) 328*eda14cbcSMatt Macy return; 329*eda14cbcSMatt Macy p += buf_int_len; 330*eda14cbcSMatt Macy } 331*eda14cbcSMatt Macy } 332*eda14cbcSMatt Macy chunk = la->la_next; 333*eda14cbcSMatt Macy } 334*eda14cbcSMatt Macy } 335*eda14cbcSMatt Macy 336*eda14cbcSMatt Macy static boolean_t 337*eda14cbcSMatt Macy zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn, 338*eda14cbcSMatt Macy int chunk, int array_numints) 339*eda14cbcSMatt Macy { 340*eda14cbcSMatt Macy int bseen = 0; 341*eda14cbcSMatt Macy 342*eda14cbcSMatt Macy if (zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY) { 343*eda14cbcSMatt Macy uint64_t *thiskey = 344*eda14cbcSMatt Macy kmem_alloc(array_numints * sizeof (*thiskey), KM_SLEEP); 345*eda14cbcSMatt Macy ASSERT(zn->zn_key_intlen == sizeof (*thiskey)); 346*eda14cbcSMatt Macy 347*eda14cbcSMatt Macy zap_leaf_array_read(l, chunk, sizeof (*thiskey), array_numints, 348*eda14cbcSMatt Macy sizeof (*thiskey), array_numints, thiskey); 349*eda14cbcSMatt Macy boolean_t match = bcmp(thiskey, zn->zn_key_orig, 350*eda14cbcSMatt Macy array_numints * sizeof (*thiskey)) == 0; 351*eda14cbcSMatt Macy kmem_free(thiskey, array_numints * sizeof (*thiskey)); 352*eda14cbcSMatt Macy return (match); 353*eda14cbcSMatt Macy } 354*eda14cbcSMatt Macy 355*eda14cbcSMatt Macy ASSERT(zn->zn_key_intlen == 1); 356*eda14cbcSMatt Macy if (zn->zn_matchtype & MT_NORMALIZE) { 357*eda14cbcSMatt Macy char *thisname = kmem_alloc(array_numints, KM_SLEEP); 358*eda14cbcSMatt Macy 359*eda14cbcSMatt Macy zap_leaf_array_read(l, chunk, sizeof (char), array_numints, 360*eda14cbcSMatt Macy sizeof (char), array_numints, thisname); 361*eda14cbcSMatt Macy boolean_t match = zap_match(zn, thisname); 362*eda14cbcSMatt Macy kmem_free(thisname, array_numints); 363*eda14cbcSMatt Macy return (match); 364*eda14cbcSMatt Macy } 365*eda14cbcSMatt Macy 366*eda14cbcSMatt Macy /* 367*eda14cbcSMatt Macy * Fast path for exact matching. 368*eda14cbcSMatt Macy * First check that the lengths match, so that we don't read 369*eda14cbcSMatt Macy * past the end of the zn_key_orig array. 370*eda14cbcSMatt Macy */ 371*eda14cbcSMatt Macy if (array_numints != zn->zn_key_orig_numints) 372*eda14cbcSMatt Macy return (B_FALSE); 373*eda14cbcSMatt Macy while (bseen < array_numints) { 374*eda14cbcSMatt Macy struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array; 375*eda14cbcSMatt Macy int toread = MIN(array_numints - bseen, ZAP_LEAF_ARRAY_BYTES); 376*eda14cbcSMatt Macy ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); 377*eda14cbcSMatt Macy if (bcmp(la->la_array, (char *)zn->zn_key_orig + bseen, toread)) 378*eda14cbcSMatt Macy break; 379*eda14cbcSMatt Macy chunk = la->la_next; 380*eda14cbcSMatt Macy bseen += toread; 381*eda14cbcSMatt Macy } 382*eda14cbcSMatt Macy return (bseen == array_numints); 383*eda14cbcSMatt Macy } 384*eda14cbcSMatt Macy 385*eda14cbcSMatt Macy /* 386*eda14cbcSMatt Macy * Routines which manipulate leaf entries. 387*eda14cbcSMatt Macy */ 388*eda14cbcSMatt Macy 389*eda14cbcSMatt Macy int 390*eda14cbcSMatt Macy zap_leaf_lookup(zap_leaf_t *l, zap_name_t *zn, zap_entry_handle_t *zeh) 391*eda14cbcSMatt Macy { 392*eda14cbcSMatt Macy struct zap_leaf_entry *le; 393*eda14cbcSMatt Macy 394*eda14cbcSMatt Macy ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC); 395*eda14cbcSMatt Macy 396*eda14cbcSMatt Macy for (uint16_t *chunkp = LEAF_HASH_ENTPTR(l, zn->zn_hash); 397*eda14cbcSMatt Macy *chunkp != CHAIN_END; chunkp = &le->le_next) { 398*eda14cbcSMatt Macy uint16_t chunk = *chunkp; 399*eda14cbcSMatt Macy le = ZAP_LEAF_ENTRY(l, chunk); 400*eda14cbcSMatt Macy 401*eda14cbcSMatt Macy ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); 402*eda14cbcSMatt Macy ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); 403*eda14cbcSMatt Macy 404*eda14cbcSMatt Macy if (le->le_hash != zn->zn_hash) 405*eda14cbcSMatt Macy continue; 406*eda14cbcSMatt Macy 407*eda14cbcSMatt Macy /* 408*eda14cbcSMatt Macy * NB: the entry chain is always sorted by cd on 409*eda14cbcSMatt Macy * normalized zap objects, so this will find the 410*eda14cbcSMatt Macy * lowest-cd match for MT_NORMALIZE. 411*eda14cbcSMatt Macy */ 412*eda14cbcSMatt Macy ASSERT((zn->zn_matchtype == 0) || 413*eda14cbcSMatt Macy (zap_leaf_phys(l)->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED)); 414*eda14cbcSMatt Macy if (zap_leaf_array_match(l, zn, le->le_name_chunk, 415*eda14cbcSMatt Macy le->le_name_numints)) { 416*eda14cbcSMatt Macy zeh->zeh_num_integers = le->le_value_numints; 417*eda14cbcSMatt Macy zeh->zeh_integer_size = le->le_value_intlen; 418*eda14cbcSMatt Macy zeh->zeh_cd = le->le_cd; 419*eda14cbcSMatt Macy zeh->zeh_hash = le->le_hash; 420*eda14cbcSMatt Macy zeh->zeh_chunkp = chunkp; 421*eda14cbcSMatt Macy zeh->zeh_leaf = l; 422*eda14cbcSMatt Macy return (0); 423*eda14cbcSMatt Macy } 424*eda14cbcSMatt Macy } 425*eda14cbcSMatt Macy 426*eda14cbcSMatt Macy return (SET_ERROR(ENOENT)); 427*eda14cbcSMatt Macy } 428*eda14cbcSMatt Macy 429*eda14cbcSMatt Macy /* Return (h1,cd1 >= h2,cd2) */ 430*eda14cbcSMatt Macy #define HCD_GTEQ(h1, cd1, h2, cd2) \ 431*eda14cbcSMatt Macy ((h1 > h2) ? TRUE : ((h1 == h2 && cd1 >= cd2) ? TRUE : FALSE)) 432*eda14cbcSMatt Macy 433*eda14cbcSMatt Macy int 434*eda14cbcSMatt Macy zap_leaf_lookup_closest(zap_leaf_t *l, 435*eda14cbcSMatt Macy uint64_t h, uint32_t cd, zap_entry_handle_t *zeh) 436*eda14cbcSMatt Macy { 437*eda14cbcSMatt Macy uint64_t besth = -1ULL; 438*eda14cbcSMatt Macy uint32_t bestcd = -1U; 439*eda14cbcSMatt Macy uint16_t bestlh = ZAP_LEAF_HASH_NUMENTRIES(l)-1; 440*eda14cbcSMatt Macy struct zap_leaf_entry *le; 441*eda14cbcSMatt Macy 442*eda14cbcSMatt Macy ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC); 443*eda14cbcSMatt Macy 444*eda14cbcSMatt Macy for (uint16_t lh = LEAF_HASH(l, h); lh <= bestlh; lh++) { 445*eda14cbcSMatt Macy for (uint16_t chunk = zap_leaf_phys(l)->l_hash[lh]; 446*eda14cbcSMatt Macy chunk != CHAIN_END; chunk = le->le_next) { 447*eda14cbcSMatt Macy le = ZAP_LEAF_ENTRY(l, chunk); 448*eda14cbcSMatt Macy 449*eda14cbcSMatt Macy ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); 450*eda14cbcSMatt Macy ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); 451*eda14cbcSMatt Macy 452*eda14cbcSMatt Macy if (HCD_GTEQ(le->le_hash, le->le_cd, h, cd) && 453*eda14cbcSMatt Macy HCD_GTEQ(besth, bestcd, le->le_hash, le->le_cd)) { 454*eda14cbcSMatt Macy ASSERT3U(bestlh, >=, lh); 455*eda14cbcSMatt Macy bestlh = lh; 456*eda14cbcSMatt Macy besth = le->le_hash; 457*eda14cbcSMatt Macy bestcd = le->le_cd; 458*eda14cbcSMatt Macy 459*eda14cbcSMatt Macy zeh->zeh_num_integers = le->le_value_numints; 460*eda14cbcSMatt Macy zeh->zeh_integer_size = le->le_value_intlen; 461*eda14cbcSMatt Macy zeh->zeh_cd = le->le_cd; 462*eda14cbcSMatt Macy zeh->zeh_hash = le->le_hash; 463*eda14cbcSMatt Macy zeh->zeh_fakechunk = chunk; 464*eda14cbcSMatt Macy zeh->zeh_chunkp = &zeh->zeh_fakechunk; 465*eda14cbcSMatt Macy zeh->zeh_leaf = l; 466*eda14cbcSMatt Macy } 467*eda14cbcSMatt Macy } 468*eda14cbcSMatt Macy } 469*eda14cbcSMatt Macy 470*eda14cbcSMatt Macy return (bestcd == -1U ? SET_ERROR(ENOENT) : 0); 471*eda14cbcSMatt Macy } 472*eda14cbcSMatt Macy 473*eda14cbcSMatt Macy int 474*eda14cbcSMatt Macy zap_entry_read(const zap_entry_handle_t *zeh, 475*eda14cbcSMatt Macy uint8_t integer_size, uint64_t num_integers, void *buf) 476*eda14cbcSMatt Macy { 477*eda14cbcSMatt Macy struct zap_leaf_entry *le = 478*eda14cbcSMatt Macy ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp); 479*eda14cbcSMatt Macy ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); 480*eda14cbcSMatt Macy 481*eda14cbcSMatt Macy if (le->le_value_intlen > integer_size) 482*eda14cbcSMatt Macy return (SET_ERROR(EINVAL)); 483*eda14cbcSMatt Macy 484*eda14cbcSMatt Macy zap_leaf_array_read(zeh->zeh_leaf, le->le_value_chunk, 485*eda14cbcSMatt Macy le->le_value_intlen, le->le_value_numints, 486*eda14cbcSMatt Macy integer_size, num_integers, buf); 487*eda14cbcSMatt Macy 488*eda14cbcSMatt Macy if (zeh->zeh_num_integers > num_integers) 489*eda14cbcSMatt Macy return (SET_ERROR(EOVERFLOW)); 490*eda14cbcSMatt Macy return (0); 491*eda14cbcSMatt Macy 492*eda14cbcSMatt Macy } 493*eda14cbcSMatt Macy 494*eda14cbcSMatt Macy int 495*eda14cbcSMatt Macy zap_entry_read_name(zap_t *zap, const zap_entry_handle_t *zeh, uint16_t buflen, 496*eda14cbcSMatt Macy char *buf) 497*eda14cbcSMatt Macy { 498*eda14cbcSMatt Macy struct zap_leaf_entry *le = 499*eda14cbcSMatt Macy ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp); 500*eda14cbcSMatt Macy ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); 501*eda14cbcSMatt Macy 502*eda14cbcSMatt Macy if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) { 503*eda14cbcSMatt Macy zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 8, 504*eda14cbcSMatt Macy le->le_name_numints, 8, buflen / 8, buf); 505*eda14cbcSMatt Macy } else { 506*eda14cbcSMatt Macy zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 1, 507*eda14cbcSMatt Macy le->le_name_numints, 1, buflen, buf); 508*eda14cbcSMatt Macy } 509*eda14cbcSMatt Macy if (le->le_name_numints > buflen) 510*eda14cbcSMatt Macy return (SET_ERROR(EOVERFLOW)); 511*eda14cbcSMatt Macy return (0); 512*eda14cbcSMatt Macy } 513*eda14cbcSMatt Macy 514*eda14cbcSMatt Macy int 515*eda14cbcSMatt Macy zap_entry_update(zap_entry_handle_t *zeh, 516*eda14cbcSMatt Macy uint8_t integer_size, uint64_t num_integers, const void *buf) 517*eda14cbcSMatt Macy { 518*eda14cbcSMatt Macy zap_leaf_t *l = zeh->zeh_leaf; 519*eda14cbcSMatt Macy struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, *zeh->zeh_chunkp); 520*eda14cbcSMatt Macy 521*eda14cbcSMatt Macy int delta_chunks = ZAP_LEAF_ARRAY_NCHUNKS(num_integers * integer_size) - 522*eda14cbcSMatt Macy ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints * le->le_value_intlen); 523*eda14cbcSMatt Macy 524*eda14cbcSMatt Macy if ((int)zap_leaf_phys(l)->l_hdr.lh_nfree < delta_chunks) 525*eda14cbcSMatt Macy return (SET_ERROR(EAGAIN)); 526*eda14cbcSMatt Macy 527*eda14cbcSMatt Macy zap_leaf_array_free(l, &le->le_value_chunk); 528*eda14cbcSMatt Macy le->le_value_chunk = 529*eda14cbcSMatt Macy zap_leaf_array_create(l, buf, integer_size, num_integers); 530*eda14cbcSMatt Macy le->le_value_numints = num_integers; 531*eda14cbcSMatt Macy le->le_value_intlen = integer_size; 532*eda14cbcSMatt Macy return (0); 533*eda14cbcSMatt Macy } 534*eda14cbcSMatt Macy 535*eda14cbcSMatt Macy void 536*eda14cbcSMatt Macy zap_entry_remove(zap_entry_handle_t *zeh) 537*eda14cbcSMatt Macy { 538*eda14cbcSMatt Macy zap_leaf_t *l = zeh->zeh_leaf; 539*eda14cbcSMatt Macy 540*eda14cbcSMatt Macy ASSERT3P(zeh->zeh_chunkp, !=, &zeh->zeh_fakechunk); 541*eda14cbcSMatt Macy 542*eda14cbcSMatt Macy uint16_t entry_chunk = *zeh->zeh_chunkp; 543*eda14cbcSMatt Macy struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, entry_chunk); 544*eda14cbcSMatt Macy ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); 545*eda14cbcSMatt Macy 546*eda14cbcSMatt Macy zap_leaf_array_free(l, &le->le_name_chunk); 547*eda14cbcSMatt Macy zap_leaf_array_free(l, &le->le_value_chunk); 548*eda14cbcSMatt Macy 549*eda14cbcSMatt Macy *zeh->zeh_chunkp = le->le_next; 550*eda14cbcSMatt Macy zap_leaf_chunk_free(l, entry_chunk); 551*eda14cbcSMatt Macy 552*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_nentries--; 553*eda14cbcSMatt Macy } 554*eda14cbcSMatt Macy 555*eda14cbcSMatt Macy int 556*eda14cbcSMatt Macy zap_entry_create(zap_leaf_t *l, zap_name_t *zn, uint32_t cd, 557*eda14cbcSMatt Macy uint8_t integer_size, uint64_t num_integers, const void *buf, 558*eda14cbcSMatt Macy zap_entry_handle_t *zeh) 559*eda14cbcSMatt Macy { 560*eda14cbcSMatt Macy uint16_t chunk; 561*eda14cbcSMatt Macy struct zap_leaf_entry *le; 562*eda14cbcSMatt Macy uint64_t h = zn->zn_hash; 563*eda14cbcSMatt Macy 564*eda14cbcSMatt Macy uint64_t valuelen = integer_size * num_integers; 565*eda14cbcSMatt Macy 566*eda14cbcSMatt Macy int numchunks = 1 + ZAP_LEAF_ARRAY_NCHUNKS(zn->zn_key_orig_numints * 567*eda14cbcSMatt Macy zn->zn_key_intlen) + ZAP_LEAF_ARRAY_NCHUNKS(valuelen); 568*eda14cbcSMatt Macy if (numchunks > ZAP_LEAF_NUMCHUNKS(l)) 569*eda14cbcSMatt Macy return (SET_ERROR(E2BIG)); 570*eda14cbcSMatt Macy 571*eda14cbcSMatt Macy if (cd == ZAP_NEED_CD) { 572*eda14cbcSMatt Macy /* find the lowest unused cd */ 573*eda14cbcSMatt Macy if (zap_leaf_phys(l)->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED) { 574*eda14cbcSMatt Macy cd = 0; 575*eda14cbcSMatt Macy 576*eda14cbcSMatt Macy for (chunk = *LEAF_HASH_ENTPTR(l, h); 577*eda14cbcSMatt Macy chunk != CHAIN_END; chunk = le->le_next) { 578*eda14cbcSMatt Macy le = ZAP_LEAF_ENTRY(l, chunk); 579*eda14cbcSMatt Macy if (le->le_cd > cd) 580*eda14cbcSMatt Macy break; 581*eda14cbcSMatt Macy if (le->le_hash == h) { 582*eda14cbcSMatt Macy ASSERT3U(cd, ==, le->le_cd); 583*eda14cbcSMatt Macy cd++; 584*eda14cbcSMatt Macy } 585*eda14cbcSMatt Macy } 586*eda14cbcSMatt Macy } else { 587*eda14cbcSMatt Macy /* old unsorted format; do it the O(n^2) way */ 588*eda14cbcSMatt Macy for (cd = 0; ; cd++) { 589*eda14cbcSMatt Macy for (chunk = *LEAF_HASH_ENTPTR(l, h); 590*eda14cbcSMatt Macy chunk != CHAIN_END; chunk = le->le_next) { 591*eda14cbcSMatt Macy le = ZAP_LEAF_ENTRY(l, chunk); 592*eda14cbcSMatt Macy if (le->le_hash == h && 593*eda14cbcSMatt Macy le->le_cd == cd) { 594*eda14cbcSMatt Macy break; 595*eda14cbcSMatt Macy } 596*eda14cbcSMatt Macy } 597*eda14cbcSMatt Macy /* If this cd is not in use, we are good. */ 598*eda14cbcSMatt Macy if (chunk == CHAIN_END) 599*eda14cbcSMatt Macy break; 600*eda14cbcSMatt Macy } 601*eda14cbcSMatt Macy } 602*eda14cbcSMatt Macy /* 603*eda14cbcSMatt Macy * We would run out of space in a block before we could 604*eda14cbcSMatt Macy * store enough entries to run out of CD values. 605*eda14cbcSMatt Macy */ 606*eda14cbcSMatt Macy ASSERT3U(cd, <, zap_maxcd(zn->zn_zap)); 607*eda14cbcSMatt Macy } 608*eda14cbcSMatt Macy 609*eda14cbcSMatt Macy if (zap_leaf_phys(l)->l_hdr.lh_nfree < numchunks) 610*eda14cbcSMatt Macy return (SET_ERROR(EAGAIN)); 611*eda14cbcSMatt Macy 612*eda14cbcSMatt Macy /* make the entry */ 613*eda14cbcSMatt Macy chunk = zap_leaf_chunk_alloc(l); 614*eda14cbcSMatt Macy le = ZAP_LEAF_ENTRY(l, chunk); 615*eda14cbcSMatt Macy le->le_type = ZAP_CHUNK_ENTRY; 616*eda14cbcSMatt Macy le->le_name_chunk = zap_leaf_array_create(l, zn->zn_key_orig, 617*eda14cbcSMatt Macy zn->zn_key_intlen, zn->zn_key_orig_numints); 618*eda14cbcSMatt Macy le->le_name_numints = zn->zn_key_orig_numints; 619*eda14cbcSMatt Macy le->le_value_chunk = 620*eda14cbcSMatt Macy zap_leaf_array_create(l, buf, integer_size, num_integers); 621*eda14cbcSMatt Macy le->le_value_numints = num_integers; 622*eda14cbcSMatt Macy le->le_value_intlen = integer_size; 623*eda14cbcSMatt Macy le->le_hash = h; 624*eda14cbcSMatt Macy le->le_cd = cd; 625*eda14cbcSMatt Macy 626*eda14cbcSMatt Macy /* link it into the hash chain */ 627*eda14cbcSMatt Macy /* XXX if we did the search above, we could just use that */ 628*eda14cbcSMatt Macy uint16_t *chunkp = zap_leaf_rehash_entry(l, chunk); 629*eda14cbcSMatt Macy 630*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_nentries++; 631*eda14cbcSMatt Macy 632*eda14cbcSMatt Macy zeh->zeh_leaf = l; 633*eda14cbcSMatt Macy zeh->zeh_num_integers = num_integers; 634*eda14cbcSMatt Macy zeh->zeh_integer_size = le->le_value_intlen; 635*eda14cbcSMatt Macy zeh->zeh_cd = le->le_cd; 636*eda14cbcSMatt Macy zeh->zeh_hash = le->le_hash; 637*eda14cbcSMatt Macy zeh->zeh_chunkp = chunkp; 638*eda14cbcSMatt Macy 639*eda14cbcSMatt Macy return (0); 640*eda14cbcSMatt Macy } 641*eda14cbcSMatt Macy 642*eda14cbcSMatt Macy /* 643*eda14cbcSMatt Macy * Determine if there is another entry with the same normalized form. 644*eda14cbcSMatt Macy * For performance purposes, either zn or name must be provided (the 645*eda14cbcSMatt Macy * other can be NULL). Note, there usually won't be any hash 646*eda14cbcSMatt Macy * conflicts, in which case we don't need the concatenated/normalized 647*eda14cbcSMatt Macy * form of the name. But all callers have one of these on hand anyway, 648*eda14cbcSMatt Macy * so might as well take advantage. A cleaner but slower interface 649*eda14cbcSMatt Macy * would accept neither argument, and compute the normalized name as 650*eda14cbcSMatt Macy * needed (using zap_name_alloc(zap_entry_read_name(zeh))). 651*eda14cbcSMatt Macy */ 652*eda14cbcSMatt Macy boolean_t 653*eda14cbcSMatt Macy zap_entry_normalization_conflict(zap_entry_handle_t *zeh, zap_name_t *zn, 654*eda14cbcSMatt Macy const char *name, zap_t *zap) 655*eda14cbcSMatt Macy { 656*eda14cbcSMatt Macy struct zap_leaf_entry *le; 657*eda14cbcSMatt Macy boolean_t allocdzn = B_FALSE; 658*eda14cbcSMatt Macy 659*eda14cbcSMatt Macy if (zap->zap_normflags == 0) 660*eda14cbcSMatt Macy return (B_FALSE); 661*eda14cbcSMatt Macy 662*eda14cbcSMatt Macy for (uint16_t chunk = *LEAF_HASH_ENTPTR(zeh->zeh_leaf, zeh->zeh_hash); 663*eda14cbcSMatt Macy chunk != CHAIN_END; chunk = le->le_next) { 664*eda14cbcSMatt Macy le = ZAP_LEAF_ENTRY(zeh->zeh_leaf, chunk); 665*eda14cbcSMatt Macy if (le->le_hash != zeh->zeh_hash) 666*eda14cbcSMatt Macy continue; 667*eda14cbcSMatt Macy if (le->le_cd == zeh->zeh_cd) 668*eda14cbcSMatt Macy continue; 669*eda14cbcSMatt Macy 670*eda14cbcSMatt Macy if (zn == NULL) { 671*eda14cbcSMatt Macy zn = zap_name_alloc(zap, name, MT_NORMALIZE); 672*eda14cbcSMatt Macy allocdzn = B_TRUE; 673*eda14cbcSMatt Macy } 674*eda14cbcSMatt Macy if (zap_leaf_array_match(zeh->zeh_leaf, zn, 675*eda14cbcSMatt Macy le->le_name_chunk, le->le_name_numints)) { 676*eda14cbcSMatt Macy if (allocdzn) 677*eda14cbcSMatt Macy zap_name_free(zn); 678*eda14cbcSMatt Macy return (B_TRUE); 679*eda14cbcSMatt Macy } 680*eda14cbcSMatt Macy } 681*eda14cbcSMatt Macy if (allocdzn) 682*eda14cbcSMatt Macy zap_name_free(zn); 683*eda14cbcSMatt Macy return (B_FALSE); 684*eda14cbcSMatt Macy } 685*eda14cbcSMatt Macy 686*eda14cbcSMatt Macy /* 687*eda14cbcSMatt Macy * Routines for transferring entries between leafs. 688*eda14cbcSMatt Macy */ 689*eda14cbcSMatt Macy 690*eda14cbcSMatt Macy static uint16_t * 691*eda14cbcSMatt Macy zap_leaf_rehash_entry(zap_leaf_t *l, uint16_t entry) 692*eda14cbcSMatt Macy { 693*eda14cbcSMatt Macy struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, entry); 694*eda14cbcSMatt Macy struct zap_leaf_entry *le2; 695*eda14cbcSMatt Macy uint16_t *chunkp; 696*eda14cbcSMatt Macy 697*eda14cbcSMatt Macy /* 698*eda14cbcSMatt Macy * keep the entry chain sorted by cd 699*eda14cbcSMatt Macy * NB: this will not cause problems for unsorted leafs, though 700*eda14cbcSMatt Macy * it is unnecessary there. 701*eda14cbcSMatt Macy */ 702*eda14cbcSMatt Macy for (chunkp = LEAF_HASH_ENTPTR(l, le->le_hash); 703*eda14cbcSMatt Macy *chunkp != CHAIN_END; chunkp = &le2->le_next) { 704*eda14cbcSMatt Macy le2 = ZAP_LEAF_ENTRY(l, *chunkp); 705*eda14cbcSMatt Macy if (le2->le_cd > le->le_cd) 706*eda14cbcSMatt Macy break; 707*eda14cbcSMatt Macy } 708*eda14cbcSMatt Macy 709*eda14cbcSMatt Macy le->le_next = *chunkp; 710*eda14cbcSMatt Macy *chunkp = entry; 711*eda14cbcSMatt Macy return (chunkp); 712*eda14cbcSMatt Macy } 713*eda14cbcSMatt Macy 714*eda14cbcSMatt Macy static uint16_t 715*eda14cbcSMatt Macy zap_leaf_transfer_array(zap_leaf_t *l, uint16_t chunk, zap_leaf_t *nl) 716*eda14cbcSMatt Macy { 717*eda14cbcSMatt Macy uint16_t new_chunk; 718*eda14cbcSMatt Macy uint16_t *nchunkp = &new_chunk; 719*eda14cbcSMatt Macy 720*eda14cbcSMatt Macy while (chunk != CHAIN_END) { 721*eda14cbcSMatt Macy uint16_t nchunk = zap_leaf_chunk_alloc(nl); 722*eda14cbcSMatt Macy struct zap_leaf_array *nla = 723*eda14cbcSMatt Macy &ZAP_LEAF_CHUNK(nl, nchunk).l_array; 724*eda14cbcSMatt Macy struct zap_leaf_array *la = 725*eda14cbcSMatt Macy &ZAP_LEAF_CHUNK(l, chunk).l_array; 726*eda14cbcSMatt Macy int nextchunk = la->la_next; 727*eda14cbcSMatt Macy 728*eda14cbcSMatt Macy ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); 729*eda14cbcSMatt Macy ASSERT3U(nchunk, <, ZAP_LEAF_NUMCHUNKS(l)); 730*eda14cbcSMatt Macy 731*eda14cbcSMatt Macy *nla = *la; /* structure assignment */ 732*eda14cbcSMatt Macy 733*eda14cbcSMatt Macy zap_leaf_chunk_free(l, chunk); 734*eda14cbcSMatt Macy chunk = nextchunk; 735*eda14cbcSMatt Macy *nchunkp = nchunk; 736*eda14cbcSMatt Macy nchunkp = &nla->la_next; 737*eda14cbcSMatt Macy } 738*eda14cbcSMatt Macy *nchunkp = CHAIN_END; 739*eda14cbcSMatt Macy return (new_chunk); 740*eda14cbcSMatt Macy } 741*eda14cbcSMatt Macy 742*eda14cbcSMatt Macy static void 743*eda14cbcSMatt Macy zap_leaf_transfer_entry(zap_leaf_t *l, int entry, zap_leaf_t *nl) 744*eda14cbcSMatt Macy { 745*eda14cbcSMatt Macy struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, entry); 746*eda14cbcSMatt Macy ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); 747*eda14cbcSMatt Macy 748*eda14cbcSMatt Macy uint16_t chunk = zap_leaf_chunk_alloc(nl); 749*eda14cbcSMatt Macy struct zap_leaf_entry *nle = ZAP_LEAF_ENTRY(nl, chunk); 750*eda14cbcSMatt Macy *nle = *le; /* structure assignment */ 751*eda14cbcSMatt Macy 752*eda14cbcSMatt Macy (void) zap_leaf_rehash_entry(nl, chunk); 753*eda14cbcSMatt Macy 754*eda14cbcSMatt Macy nle->le_name_chunk = zap_leaf_transfer_array(l, le->le_name_chunk, nl); 755*eda14cbcSMatt Macy nle->le_value_chunk = 756*eda14cbcSMatt Macy zap_leaf_transfer_array(l, le->le_value_chunk, nl); 757*eda14cbcSMatt Macy 758*eda14cbcSMatt Macy zap_leaf_chunk_free(l, entry); 759*eda14cbcSMatt Macy 760*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_nentries--; 761*eda14cbcSMatt Macy zap_leaf_phys(nl)->l_hdr.lh_nentries++; 762*eda14cbcSMatt Macy } 763*eda14cbcSMatt Macy 764*eda14cbcSMatt Macy /* 765*eda14cbcSMatt Macy * Transfer the entries whose hash prefix ends in 1 to the new leaf. 766*eda14cbcSMatt Macy */ 767*eda14cbcSMatt Macy void 768*eda14cbcSMatt Macy zap_leaf_split(zap_leaf_t *l, zap_leaf_t *nl, boolean_t sort) 769*eda14cbcSMatt Macy { 770*eda14cbcSMatt Macy int bit = 64 - 1 - zap_leaf_phys(l)->l_hdr.lh_prefix_len; 771*eda14cbcSMatt Macy 772*eda14cbcSMatt Macy /* set new prefix and prefix_len */ 773*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_prefix <<= 1; 774*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_prefix_len++; 775*eda14cbcSMatt Macy zap_leaf_phys(nl)->l_hdr.lh_prefix = 776*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_prefix | 1; 777*eda14cbcSMatt Macy zap_leaf_phys(nl)->l_hdr.lh_prefix_len = 778*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_prefix_len; 779*eda14cbcSMatt Macy 780*eda14cbcSMatt Macy /* break existing hash chains */ 781*eda14cbcSMatt Macy zap_memset(zap_leaf_phys(l)->l_hash, CHAIN_END, 782*eda14cbcSMatt Macy 2*ZAP_LEAF_HASH_NUMENTRIES(l)); 783*eda14cbcSMatt Macy 784*eda14cbcSMatt Macy if (sort) 785*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_flags |= ZLF_ENTRIES_CDSORTED; 786*eda14cbcSMatt Macy 787*eda14cbcSMatt Macy /* 788*eda14cbcSMatt Macy * Transfer entries whose hash bit 'bit' is set to nl; rehash 789*eda14cbcSMatt Macy * the remaining entries 790*eda14cbcSMatt Macy * 791*eda14cbcSMatt Macy * NB: We could find entries via the hashtable instead. That 792*eda14cbcSMatt Macy * would be O(hashents+numents) rather than O(numblks+numents), 793*eda14cbcSMatt Macy * but this accesses memory more sequentially, and when we're 794*eda14cbcSMatt Macy * called, the block is usually pretty full. 795*eda14cbcSMatt Macy */ 796*eda14cbcSMatt Macy for (int i = 0; i < ZAP_LEAF_NUMCHUNKS(l); i++) { 797*eda14cbcSMatt Macy struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, i); 798*eda14cbcSMatt Macy if (le->le_type != ZAP_CHUNK_ENTRY) 799*eda14cbcSMatt Macy continue; 800*eda14cbcSMatt Macy 801*eda14cbcSMatt Macy if (le->le_hash & (1ULL << bit)) 802*eda14cbcSMatt Macy zap_leaf_transfer_entry(l, i, nl); 803*eda14cbcSMatt Macy else 804*eda14cbcSMatt Macy (void) zap_leaf_rehash_entry(l, i); 805*eda14cbcSMatt Macy } 806*eda14cbcSMatt Macy } 807*eda14cbcSMatt Macy 808*eda14cbcSMatt Macy void 809*eda14cbcSMatt Macy zap_leaf_stats(zap_t *zap, zap_leaf_t *l, zap_stats_t *zs) 810*eda14cbcSMatt Macy { 811*eda14cbcSMatt Macy int n = zap_f_phys(zap)->zap_ptrtbl.zt_shift - 812*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_prefix_len; 813*eda14cbcSMatt Macy n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 814*eda14cbcSMatt Macy zs->zs_leafs_with_2n_pointers[n]++; 815*eda14cbcSMatt Macy 816*eda14cbcSMatt Macy 817*eda14cbcSMatt Macy n = zap_leaf_phys(l)->l_hdr.lh_nentries/5; 818*eda14cbcSMatt Macy n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 819*eda14cbcSMatt Macy zs->zs_blocks_with_n5_entries[n]++; 820*eda14cbcSMatt Macy 821*eda14cbcSMatt Macy n = ((1<<FZAP_BLOCK_SHIFT(zap)) - 822*eda14cbcSMatt Macy zap_leaf_phys(l)->l_hdr.lh_nfree * (ZAP_LEAF_ARRAY_BYTES+1))*10 / 823*eda14cbcSMatt Macy (1<<FZAP_BLOCK_SHIFT(zap)); 824*eda14cbcSMatt Macy n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 825*eda14cbcSMatt Macy zs->zs_blocks_n_tenths_full[n]++; 826*eda14cbcSMatt Macy 827*eda14cbcSMatt Macy for (int i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(l); i++) { 828*eda14cbcSMatt Macy int nentries = 0; 829*eda14cbcSMatt Macy int chunk = zap_leaf_phys(l)->l_hash[i]; 830*eda14cbcSMatt Macy 831*eda14cbcSMatt Macy while (chunk != CHAIN_END) { 832*eda14cbcSMatt Macy struct zap_leaf_entry *le = 833*eda14cbcSMatt Macy ZAP_LEAF_ENTRY(l, chunk); 834*eda14cbcSMatt Macy 835*eda14cbcSMatt Macy n = 1 + ZAP_LEAF_ARRAY_NCHUNKS(le->le_name_numints) + 836*eda14cbcSMatt Macy ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints * 837*eda14cbcSMatt Macy le->le_value_intlen); 838*eda14cbcSMatt Macy n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 839*eda14cbcSMatt Macy zs->zs_entries_using_n_chunks[n]++; 840*eda14cbcSMatt Macy 841*eda14cbcSMatt Macy chunk = le->le_next; 842*eda14cbcSMatt Macy nentries++; 843*eda14cbcSMatt Macy } 844*eda14cbcSMatt Macy 845*eda14cbcSMatt Macy n = nentries; 846*eda14cbcSMatt Macy n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 847*eda14cbcSMatt Macy zs->zs_buckets_with_n_entries[n]++; 848*eda14cbcSMatt Macy } 849*eda14cbcSMatt Macy } 850