1*789Sahrens /* 2*789Sahrens * CDDL HEADER START 3*789Sahrens * 4*789Sahrens * The contents of this file are subject to the terms of the 5*789Sahrens * Common Development and Distribution License, Version 1.0 only 6*789Sahrens * (the "License"). You may not use this file except in compliance 7*789Sahrens * with the License. 8*789Sahrens * 9*789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*789Sahrens * or http://www.opensolaris.org/os/licensing. 11*789Sahrens * See the License for the specific language governing permissions 12*789Sahrens * and limitations under the License. 13*789Sahrens * 14*789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 15*789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*789Sahrens * If applicable, add the following below this CDDL HEADER, with the 17*789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 18*789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 19*789Sahrens * 20*789Sahrens * CDDL HEADER END 21*789Sahrens */ 22*789Sahrens /* 23*789Sahrens * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*789Sahrens * Use is subject to license terms. 25*789Sahrens */ 26*789Sahrens 27*789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 28*789Sahrens 29*789Sahrens /* 30*789Sahrens * The 512-byte leaf is broken into 32 16-byte chunks. 31*789Sahrens * chunk number n means l_chunk[n], even though the header precedes it. 32*789Sahrens * the names are stored null-terminated. 33*789Sahrens */ 34*789Sahrens 35*789Sahrens #include <sys/zfs_context.h> 36*789Sahrens #include <sys/zap.h> 37*789Sahrens #include <sys/zap_impl.h> 38*789Sahrens #include <sys/zap_leaf.h> 39*789Sahrens #include <sys/spa.h> 40*789Sahrens #include <sys/dmu.h> 41*789Sahrens 42*789Sahrens #define CHAIN_END 0xffff /* end of the chunk chain */ 43*789Sahrens 44*789Sahrens /* somewhat arbitrary, could go up to around 100k ... */ 45*789Sahrens #define MAX_ARRAY_BYTES (8<<10) 46*789Sahrens 47*789Sahrens #define NCHUNKS(bytes) (((bytes)+ZAP_LEAF_ARRAY_BYTES-1)/ZAP_LEAF_ARRAY_BYTES) 48*789Sahrens 49*789Sahrens /* 50*789Sahrens * XXX This will >> by a negative number when 51*789Sahrens * lh_prefix_len > 64-ZAP_LEAF_HASH_SHIFT. 52*789Sahrens */ 53*789Sahrens #define LEAF_HASH(l, h) \ 54*789Sahrens ((ZAP_LEAF_HASH_NUMENTRIES-1) & \ 55*789Sahrens ((h) >> (64 - ZAP_LEAF_HASH_SHIFT-(l)->lh_prefix_len))) 56*789Sahrens 57*789Sahrens #define LEAF_HASH_ENTPTR(l, h) (&(l)->l_phys->l_hash[LEAF_HASH(l, h)]) 58*789Sahrens 59*789Sahrens /* #define MEMCHECK */ 60*789Sahrens 61*789Sahrens 62*789Sahrens static void 63*789Sahrens zap_memset(void *a, int c, size_t n) 64*789Sahrens { 65*789Sahrens char *cp = a; 66*789Sahrens char *cpend = cp + n; 67*789Sahrens 68*789Sahrens while (cp < cpend) 69*789Sahrens *cp++ = c; 70*789Sahrens } 71*789Sahrens 72*789Sahrens static void 73*789Sahrens stv(int len, void *addr, uint64_t value) 74*789Sahrens { 75*789Sahrens switch (len) { 76*789Sahrens case 1: 77*789Sahrens *(uint8_t *)addr = value; 78*789Sahrens return; 79*789Sahrens case 2: 80*789Sahrens *(uint16_t *)addr = value; 81*789Sahrens return; 82*789Sahrens case 4: 83*789Sahrens *(uint32_t *)addr = value; 84*789Sahrens return; 85*789Sahrens case 8: 86*789Sahrens *(uint64_t *)addr = value; 87*789Sahrens return; 88*789Sahrens } 89*789Sahrens ASSERT(!"bad int len"); 90*789Sahrens } 91*789Sahrens 92*789Sahrens static uint64_t 93*789Sahrens ldv(int len, const void *addr) 94*789Sahrens { 95*789Sahrens switch (len) { 96*789Sahrens case 1: 97*789Sahrens return (*(uint8_t *)addr); 98*789Sahrens case 2: 99*789Sahrens return (*(uint16_t *)addr); 100*789Sahrens case 4: 101*789Sahrens return (*(uint32_t *)addr); 102*789Sahrens case 8: 103*789Sahrens return (*(uint64_t *)addr); 104*789Sahrens } 105*789Sahrens ASSERT(!"bad int len"); 106*789Sahrens return (0xFEEDFACEDEADBEEF); 107*789Sahrens } 108*789Sahrens 109*789Sahrens void 110*789Sahrens zap_leaf_byteswap(zap_leaf_phys_t *buf) 111*789Sahrens { 112*789Sahrens int i; 113*789Sahrens 114*789Sahrens buf->l_hdr.lhr_block_type = BSWAP_64(buf->l_hdr.lhr_block_type); 115*789Sahrens buf->l_hdr.lhr_next = BSWAP_64(buf->l_hdr.lhr_next); 116*789Sahrens buf->l_hdr.lhr_prefix = BSWAP_64(buf->l_hdr.lhr_prefix); 117*789Sahrens buf->l_hdr.lhr_magic = BSWAP_32(buf->l_hdr.lhr_magic); 118*789Sahrens buf->l_hdr.lhr_nfree = BSWAP_16(buf->l_hdr.lhr_nfree); 119*789Sahrens buf->l_hdr.lhr_nentries = BSWAP_16(buf->l_hdr.lhr_nentries); 120*789Sahrens buf->l_hdr.lhr_prefix_len = BSWAP_16(buf->l_hdr.lhr_prefix_len); 121*789Sahrens buf->l_hdr.lh_freelist = BSWAP_16(buf->l_hdr.lh_freelist); 122*789Sahrens 123*789Sahrens for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES; i++) 124*789Sahrens buf->l_hash[i] = BSWAP_16(buf->l_hash[i]); 125*789Sahrens 126*789Sahrens for (i = 0; i < ZAP_LEAF_NUMCHUNKS; i++) { 127*789Sahrens struct zap_leaf_entry *le; 128*789Sahrens 129*789Sahrens switch (buf->l_chunk[i].l_free.lf_type) { 130*789Sahrens case ZAP_LEAF_ENTRY: 131*789Sahrens le = &buf->l_chunk[i].l_entry; 132*789Sahrens 133*789Sahrens le->le_type = BSWAP_8(le->le_type); 134*789Sahrens le->le_int_size = BSWAP_8(le->le_int_size); 135*789Sahrens le->le_next = BSWAP_16(le->le_next); 136*789Sahrens le->le_name_chunk = BSWAP_16(le->le_name_chunk); 137*789Sahrens le->le_name_length = BSWAP_16(le->le_name_length); 138*789Sahrens le->le_value_chunk = BSWAP_16(le->le_value_chunk); 139*789Sahrens le->le_value_length = BSWAP_16(le->le_value_length); 140*789Sahrens le->le_cd = BSWAP_32(le->le_cd); 141*789Sahrens le->le_hash = BSWAP_64(le->le_hash); 142*789Sahrens break; 143*789Sahrens case ZAP_LEAF_FREE: 144*789Sahrens buf->l_chunk[i].l_free.lf_type = 145*789Sahrens BSWAP_8(buf->l_chunk[i].l_free.lf_type); 146*789Sahrens buf->l_chunk[i].l_free.lf_next = 147*789Sahrens BSWAP_16(buf->l_chunk[i].l_free.lf_next); 148*789Sahrens break; 149*789Sahrens case ZAP_LEAF_ARRAY: 150*789Sahrens /* zap_leaf_array */ 151*789Sahrens buf->l_chunk[i].l_array.la_type = 152*789Sahrens BSWAP_8(buf->l_chunk[i].l_array.la_type); 153*789Sahrens buf->l_chunk[i].l_array.la_next = 154*789Sahrens BSWAP_16(buf->l_chunk[i].l_array.la_next); 155*789Sahrens /* la_array doesn't need swapping */ 156*789Sahrens break; 157*789Sahrens default: 158*789Sahrens ASSERT(!"bad leaf type"); 159*789Sahrens } 160*789Sahrens } 161*789Sahrens } 162*789Sahrens 163*789Sahrens void 164*789Sahrens zap_leaf_init(zap_leaf_t *l) 165*789Sahrens { 166*789Sahrens int i; 167*789Sahrens 168*789Sahrens ASSERT3U(sizeof (zap_leaf_phys_t), ==, l->l_dbuf->db_size); 169*789Sahrens zap_memset(&l->l_phys->l_hdr, 0, sizeof (struct zap_leaf_header)); 170*789Sahrens zap_memset(&l->l_phys->l_hash, CHAIN_END, sizeof (l->l_phys->l_hash)); 171*789Sahrens for (i = 0; i < ZAP_LEAF_NUMCHUNKS; i++) { 172*789Sahrens l->l_phys->l_chunk[i].l_free.lf_type = ZAP_LEAF_FREE; 173*789Sahrens l->l_phys->l_chunk[i].l_free.lf_next = i+1; 174*789Sahrens } 175*789Sahrens l->l_phys->l_chunk[ZAP_LEAF_NUMCHUNKS-1].l_free.lf_next = CHAIN_END; 176*789Sahrens l->lh_block_type = ZBT_LEAF; 177*789Sahrens l->lh_magic = ZAP_LEAF_MAGIC; 178*789Sahrens l->lh_nfree = ZAP_LEAF_NUMCHUNKS; 179*789Sahrens } 180*789Sahrens 181*789Sahrens zap_leaf_t * 182*789Sahrens zap_leaf_chainmore(zap_leaf_t *l, zap_leaf_t *nl) 183*789Sahrens { 184*789Sahrens nl->lh_prefix = l->lh_prefix; 185*789Sahrens nl->lh_prefix_len = l->lh_prefix_len; 186*789Sahrens nl->l_next = l->l_next; 187*789Sahrens l->l_next = nl; 188*789Sahrens nl->lh_next = l->lh_next; 189*789Sahrens l->lh_next = nl->l_blkid; 190*789Sahrens return (nl); 191*789Sahrens } 192*789Sahrens 193*789Sahrens /* 194*789Sahrens * Routines which manipulate leaf chunks (l_chunk[]). 195*789Sahrens */ 196*789Sahrens 197*789Sahrens static uint16_t 198*789Sahrens zap_leaf_chunk_alloc(zap_leaf_t *l) 199*789Sahrens { 200*789Sahrens int chunk; 201*789Sahrens 202*789Sahrens ASSERT(l->lh_nfree > 0); 203*789Sahrens 204*789Sahrens chunk = l->l_phys->l_hdr.lh_freelist; 205*789Sahrens ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS); 206*789Sahrens ASSERT3U(l->l_phys->l_chunk[chunk].l_free.lf_type, ==, ZAP_LEAF_FREE); 207*789Sahrens 208*789Sahrens l->l_phys->l_hdr.lh_freelist = l->l_phys->l_chunk[chunk].l_free.lf_next; 209*789Sahrens 210*789Sahrens #ifdef MEMCHECK 211*789Sahrens zap_memset(&l->l_phys->l_chunk[chunk], 0xa1, 212*789Sahrens sizeof (l->l_phys->l_chunk[chunk])); 213*789Sahrens #endif 214*789Sahrens 215*789Sahrens l->lh_nfree--; 216*789Sahrens 217*789Sahrens return (chunk); 218*789Sahrens } 219*789Sahrens 220*789Sahrens static void 221*789Sahrens zap_leaf_chunk_free(zap_leaf_t *l, uint16_t chunk) 222*789Sahrens { 223*789Sahrens struct zap_leaf_free *zlf = &l->l_phys->l_chunk[chunk].l_free; 224*789Sahrens ASSERT3U(l->lh_nfree, <, ZAP_LEAF_NUMCHUNKS); 225*789Sahrens ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS); 226*789Sahrens ASSERT(zlf->lf_type != ZAP_LEAF_FREE); 227*789Sahrens 228*789Sahrens #ifdef MEMCHECK 229*789Sahrens zap_memset(&l->l_phys->l_chunk[chunk], 0xf4, 230*789Sahrens sizeof (l->l_phys->l_chunk[chunk])); 231*789Sahrens #endif 232*789Sahrens 233*789Sahrens zlf->lf_type = ZAP_LEAF_FREE; 234*789Sahrens zlf->lf_next = l->l_phys->l_hdr.lh_freelist; 235*789Sahrens bzero(zlf->lf_pad, sizeof (zlf->lf_pad)); /* help it to compress */ 236*789Sahrens l->l_phys->l_hdr.lh_freelist = chunk; 237*789Sahrens 238*789Sahrens l->lh_nfree++; 239*789Sahrens } 240*789Sahrens 241*789Sahrens 242*789Sahrens /* 243*789Sahrens * Routines which manipulate leaf arrays (zap_leaf_array type chunks). 244*789Sahrens */ 245*789Sahrens 246*789Sahrens static uint16_t 247*789Sahrens zap_leaf_array_create(const zap_entry_handle_t *zeh, const char *buf, 248*789Sahrens int integer_size, int num_integers) 249*789Sahrens { 250*789Sahrens uint16_t chunk_head; 251*789Sahrens uint16_t *chunkp = &chunk_head; 252*789Sahrens int byten = 0; 253*789Sahrens uint64_t value; 254*789Sahrens int shift = (integer_size-1)*8; 255*789Sahrens int len = num_integers; 256*789Sahrens zap_leaf_t *l = zeh->zeh_found_leaf; 257*789Sahrens 258*789Sahrens ASSERT3U(num_integers * integer_size, <, MAX_ARRAY_BYTES); 259*789Sahrens 260*789Sahrens while (len > 0) { 261*789Sahrens uint16_t chunk = zap_leaf_chunk_alloc(l); 262*789Sahrens struct zap_leaf_array *la = &l->l_phys->l_chunk[chunk].l_array; 263*789Sahrens int i; 264*789Sahrens 265*789Sahrens la->la_type = ZAP_LEAF_ARRAY; 266*789Sahrens for (i = 0; i < ZAP_LEAF_ARRAY_BYTES; i++) { 267*789Sahrens if (byten == 0) 268*789Sahrens value = ldv(integer_size, buf); 269*789Sahrens la->la_array[i] = (value & (0xff << shift)) >> shift; 270*789Sahrens value <<= 8; 271*789Sahrens if (++byten == integer_size) { 272*789Sahrens byten = 0; 273*789Sahrens buf += integer_size; 274*789Sahrens if (--len == 0) 275*789Sahrens break; 276*789Sahrens } 277*789Sahrens } 278*789Sahrens 279*789Sahrens *chunkp = chunk; 280*789Sahrens chunkp = &la->la_next; 281*789Sahrens } 282*789Sahrens *chunkp = CHAIN_END; 283*789Sahrens 284*789Sahrens return (chunk_head); 285*789Sahrens } 286*789Sahrens 287*789Sahrens static void 288*789Sahrens zap_leaf_array_free(zap_entry_handle_t *zeh, uint16_t *chunkp) 289*789Sahrens { 290*789Sahrens uint16_t chunk = *chunkp; 291*789Sahrens zap_leaf_t *l = zeh->zeh_found_leaf; 292*789Sahrens 293*789Sahrens *chunkp = CHAIN_END; 294*789Sahrens 295*789Sahrens while (chunk != CHAIN_END) { 296*789Sahrens int nextchunk = l->l_phys->l_chunk[chunk].l_array.la_next; 297*789Sahrens ASSERT3U(l->l_phys->l_chunk[chunk].l_array.la_type, ==, 298*789Sahrens ZAP_LEAF_ARRAY); 299*789Sahrens zap_leaf_chunk_free(l, chunk); 300*789Sahrens chunk = nextchunk; 301*789Sahrens } 302*789Sahrens } 303*789Sahrens 304*789Sahrens /* array_len and buf_len are in integers, not bytes */ 305*789Sahrens static void 306*789Sahrens zap_leaf_array_read(const zap_entry_handle_t *zeh, uint16_t chunk, 307*789Sahrens int array_int_len, int array_len, int buf_int_len, uint64_t buf_len, 308*789Sahrens char *buf) 309*789Sahrens { 310*789Sahrens int len = MIN(array_len, buf_len); 311*789Sahrens int byten = 0; 312*789Sahrens uint64_t value = 0; 313*789Sahrens zap_leaf_t *l = zeh->zeh_found_leaf; 314*789Sahrens 315*789Sahrens ASSERT3U(array_int_len, <=, buf_int_len); 316*789Sahrens 317*789Sahrens while (len > 0) { 318*789Sahrens struct zap_leaf_array *la = &l->l_phys->l_chunk[chunk].l_array; 319*789Sahrens int i; 320*789Sahrens 321*789Sahrens ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS); 322*789Sahrens for (i = 0; i < ZAP_LEAF_ARRAY_BYTES && len > 0; i++) { 323*789Sahrens value = (value << 8) | la->la_array[i]; 324*789Sahrens byten++; 325*789Sahrens if (byten == array_int_len) { 326*789Sahrens stv(buf_int_len, buf, value); 327*789Sahrens byten = 0; 328*789Sahrens len--; 329*789Sahrens if (len == 0) 330*789Sahrens return; 331*789Sahrens buf += buf_int_len; 332*789Sahrens } 333*789Sahrens } 334*789Sahrens chunk = la->la_next; 335*789Sahrens } 336*789Sahrens } 337*789Sahrens 338*789Sahrens /* 339*789Sahrens * Only to be used on 8-bit arrays. 340*789Sahrens * array_len is actual len in bytes (not encoded le_value_length). 341*789Sahrens * buf is null-terminated. 342*789Sahrens */ 343*789Sahrens static int 344*789Sahrens zap_leaf_array_equal(const zap_entry_handle_t *zeh, int chunk, 345*789Sahrens int array_len, const char *buf) 346*789Sahrens { 347*789Sahrens int bseen = 0; 348*789Sahrens zap_leaf_t *l = zeh->zeh_found_leaf; 349*789Sahrens 350*789Sahrens while (bseen < array_len) { 351*789Sahrens struct zap_leaf_array *la = &l->l_phys->l_chunk[chunk].l_array; 352*789Sahrens int toread = MIN(array_len - bseen, ZAP_LEAF_ARRAY_BYTES); 353*789Sahrens ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS); 354*789Sahrens if (bcmp(la->la_array, buf + bseen, toread)) 355*789Sahrens break; 356*789Sahrens chunk = la->la_next; 357*789Sahrens bseen += toread; 358*789Sahrens } 359*789Sahrens return (bseen == array_len); 360*789Sahrens } 361*789Sahrens 362*789Sahrens /* 363*789Sahrens * Routines which manipulate leaf entries. 364*789Sahrens */ 365*789Sahrens 366*789Sahrens int 367*789Sahrens zap_leaf_lookup(zap_leaf_t *l, 368*789Sahrens const char *name, uint64_t h, zap_entry_handle_t *zeh) 369*789Sahrens { 370*789Sahrens uint16_t *chunkp; 371*789Sahrens struct zap_leaf_entry *le; 372*789Sahrens 373*789Sahrens zeh->zeh_head_leaf = l; 374*789Sahrens 375*789Sahrens again: 376*789Sahrens ASSERT3U(l->lh_magic, ==, ZAP_LEAF_MAGIC); 377*789Sahrens 378*789Sahrens for (chunkp = LEAF_HASH_ENTPTR(l, h); 379*789Sahrens *chunkp != CHAIN_END; chunkp = &le->le_next) { 380*789Sahrens uint16_t chunk = *chunkp; 381*789Sahrens le = &l->l_phys->l_chunk[chunk].l_entry; 382*789Sahrens 383*789Sahrens ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS); 384*789Sahrens ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY); 385*789Sahrens 386*789Sahrens if (le->le_hash != h) 387*789Sahrens continue; 388*789Sahrens 389*789Sahrens zeh->zeh_found_leaf = l; 390*789Sahrens if (zap_leaf_array_equal(zeh, le->le_name_chunk, 391*789Sahrens le->le_name_length, name)) { 392*789Sahrens zeh->zeh_num_integers = le->le_value_length; 393*789Sahrens zeh->zeh_integer_size = le->le_int_size; 394*789Sahrens zeh->zeh_cd = le->le_cd; 395*789Sahrens zeh->zeh_hash = le->le_hash; 396*789Sahrens zeh->zeh_chunkp = chunkp; 397*789Sahrens zeh->zeh_found_leaf = l; 398*789Sahrens return (0); 399*789Sahrens } 400*789Sahrens } 401*789Sahrens 402*789Sahrens if (l->l_next) { 403*789Sahrens l = l->l_next; 404*789Sahrens goto again; 405*789Sahrens } 406*789Sahrens 407*789Sahrens return (ENOENT); 408*789Sahrens } 409*789Sahrens 410*789Sahrens /* Return (h1,cd1 >= h2,cd2) */ 411*789Sahrens static int 412*789Sahrens hcd_gteq(uint64_t h1, uint32_t cd1, uint64_t h2, uint32_t cd2) 413*789Sahrens { 414*789Sahrens if (h1 > h2) 415*789Sahrens return (TRUE); 416*789Sahrens if (h1 == h2 && cd1 >= cd2) 417*789Sahrens return (TRUE); 418*789Sahrens return (FALSE); 419*789Sahrens } 420*789Sahrens 421*789Sahrens int 422*789Sahrens zap_leaf_lookup_closest(zap_leaf_t *l, 423*789Sahrens uint64_t h, uint32_t cd, zap_entry_handle_t *zeh) 424*789Sahrens { 425*789Sahrens uint16_t chunk; 426*789Sahrens uint64_t besth = -1ULL; 427*789Sahrens uint32_t bestcd = ZAP_MAXCD; 428*789Sahrens uint16_t bestlh = ZAP_LEAF_HASH_NUMENTRIES-1; 429*789Sahrens uint16_t lh; 430*789Sahrens struct zap_leaf_entry *le; 431*789Sahrens 432*789Sahrens zeh->zeh_head_leaf = l; 433*789Sahrens 434*789Sahrens again: 435*789Sahrens ASSERT3U(l->lh_magic, ==, ZAP_LEAF_MAGIC); 436*789Sahrens 437*789Sahrens for (lh = LEAF_HASH(l, h); lh <= bestlh; lh++) { 438*789Sahrens for (chunk = l->l_phys->l_hash[lh]; 439*789Sahrens chunk != CHAIN_END; chunk = le->le_next) { 440*789Sahrens le = &l->l_phys->l_chunk[chunk].l_entry; 441*789Sahrens 442*789Sahrens ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS); 443*789Sahrens ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY); 444*789Sahrens 445*789Sahrens if (hcd_gteq(le->le_hash, le->le_cd, h, cd) && 446*789Sahrens hcd_gteq(besth, bestcd, le->le_hash, le->le_cd)) { 447*789Sahrens ASSERT3U(bestlh, >=, lh); 448*789Sahrens bestlh = lh; 449*789Sahrens besth = le->le_hash; 450*789Sahrens bestcd = le->le_cd; 451*789Sahrens 452*789Sahrens zeh->zeh_num_integers = le->le_value_length; 453*789Sahrens zeh->zeh_integer_size = le->le_int_size; 454*789Sahrens zeh->zeh_cd = le->le_cd; 455*789Sahrens zeh->zeh_hash = le->le_hash; 456*789Sahrens zeh->zeh_fakechunk = chunk; 457*789Sahrens zeh->zeh_chunkp = &zeh->zeh_fakechunk; 458*789Sahrens zeh->zeh_found_leaf = l; 459*789Sahrens } 460*789Sahrens } 461*789Sahrens } 462*789Sahrens 463*789Sahrens if (l->l_next) { 464*789Sahrens l = l->l_next; 465*789Sahrens goto again; 466*789Sahrens } 467*789Sahrens 468*789Sahrens return (bestcd == ZAP_MAXCD ? ENOENT : 0); 469*789Sahrens } 470*789Sahrens 471*789Sahrens int 472*789Sahrens zap_entry_read(const zap_entry_handle_t *zeh, 473*789Sahrens uint8_t integer_size, uint64_t num_integers, void *buf) 474*789Sahrens { 475*789Sahrens struct zap_leaf_entry *le; 476*789Sahrens 477*789Sahrens le = &zeh->zeh_found_leaf->l_phys->l_chunk[*zeh->zeh_chunkp].l_entry; 478*789Sahrens ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY); 479*789Sahrens 480*789Sahrens if (le->le_int_size > integer_size) 481*789Sahrens return (EINVAL); 482*789Sahrens 483*789Sahrens zap_leaf_array_read(zeh, le->le_value_chunk, le->le_int_size, 484*789Sahrens le->le_value_length, integer_size, num_integers, buf); 485*789Sahrens 486*789Sahrens if (zeh->zeh_num_integers > num_integers) 487*789Sahrens return (EOVERFLOW); 488*789Sahrens return (0); 489*789Sahrens 490*789Sahrens } 491*789Sahrens 492*789Sahrens int 493*789Sahrens zap_entry_read_name(const zap_entry_handle_t *zeh, uint16_t buflen, char *buf) 494*789Sahrens { 495*789Sahrens struct zap_leaf_entry *le; 496*789Sahrens 497*789Sahrens le = &zeh->zeh_found_leaf->l_phys->l_chunk[*zeh->zeh_chunkp].l_entry; 498*789Sahrens ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY); 499*789Sahrens 500*789Sahrens zap_leaf_array_read(zeh, le->le_name_chunk, 1, 501*789Sahrens le->le_name_length, 1, buflen, buf); 502*789Sahrens if (le->le_name_length > buflen) 503*789Sahrens return (EOVERFLOW); 504*789Sahrens return (0); 505*789Sahrens } 506*789Sahrens 507*789Sahrens int 508*789Sahrens zap_entry_update(zap_entry_handle_t *zeh, 509*789Sahrens uint8_t integer_size, uint64_t num_integers, const void *buf) 510*789Sahrens { 511*789Sahrens int delta_chunks; 512*789Sahrens struct zap_leaf_entry *le; 513*789Sahrens le = &zeh->zeh_found_leaf->l_phys->l_chunk[*zeh->zeh_chunkp].l_entry; 514*789Sahrens 515*789Sahrens delta_chunks = NCHUNKS(num_integers * integer_size) - 516*789Sahrens NCHUNKS(le->le_value_length * le->le_int_size); 517*789Sahrens 518*789Sahrens if (zeh->zeh_found_leaf->lh_nfree < delta_chunks) 519*789Sahrens return (EAGAIN); 520*789Sahrens 521*789Sahrens /* 522*789Sahrens * We should search other chained leaves (via 523*789Sahrens * zap_entry_remove,create?) otherwise returning EAGAIN will 524*789Sahrens * just send us into an infinite loop if we have to chain 525*789Sahrens * another leaf block, rather than being able to split this 526*789Sahrens * block. 527*789Sahrens */ 528*789Sahrens 529*789Sahrens zap_leaf_array_free(zeh, &le->le_value_chunk); 530*789Sahrens le->le_value_chunk = 531*789Sahrens zap_leaf_array_create(zeh, buf, integer_size, num_integers); 532*789Sahrens le->le_value_length = (num_integers*integer_size > MAX_ARRAY_BYTES) ? 533*789Sahrens (MAX_ARRAY_BYTES + 1) : (num_integers); 534*789Sahrens le->le_int_size = integer_size; 535*789Sahrens return (0); 536*789Sahrens } 537*789Sahrens 538*789Sahrens void 539*789Sahrens zap_entry_remove(zap_entry_handle_t *zeh) 540*789Sahrens { 541*789Sahrens uint16_t entry_chunk; 542*789Sahrens struct zap_leaf_entry *le; 543*789Sahrens zap_leaf_t *l = zeh->zeh_found_leaf; 544*789Sahrens 545*789Sahrens ASSERT3P(zeh->zeh_chunkp, !=, &zeh->zeh_fakechunk); 546*789Sahrens 547*789Sahrens entry_chunk = *zeh->zeh_chunkp; 548*789Sahrens le = &l->l_phys->l_chunk[entry_chunk].l_entry; 549*789Sahrens ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY); 550*789Sahrens 551*789Sahrens zap_leaf_array_free(zeh, &le->le_name_chunk); 552*789Sahrens zap_leaf_array_free(zeh, &le->le_value_chunk); 553*789Sahrens 554*789Sahrens *zeh->zeh_chunkp = le->le_next; 555*789Sahrens zap_leaf_chunk_free(l, entry_chunk); 556*789Sahrens 557*789Sahrens l->lh_nentries--; 558*789Sahrens } 559*789Sahrens 560*789Sahrens int 561*789Sahrens zap_entry_create(zap_leaf_t *l, const char *name, uint64_t h, uint32_t cd, 562*789Sahrens uint8_t integer_size, uint64_t num_integers, const void *buf, 563*789Sahrens zap_entry_handle_t *zeh) 564*789Sahrens { 565*789Sahrens uint16_t chunk; 566*789Sahrens uint16_t *chunkp; 567*789Sahrens struct zap_leaf_entry *le; 568*789Sahrens uint64_t namelen, valuelen; 569*789Sahrens int numchunks; 570*789Sahrens 571*789Sahrens valuelen = integer_size * num_integers; 572*789Sahrens namelen = strlen(name) + 1; 573*789Sahrens ASSERT(namelen >= 2); 574*789Sahrens 575*789Sahrens zeh->zeh_head_leaf = l; 576*789Sahrens 577*789Sahrens if (namelen > MAXNAMELEN) 578*789Sahrens return (ENAMETOOLONG); 579*789Sahrens /* find the first leaf in the chain that has sufficient free space */ 580*789Sahrens numchunks = 1 + NCHUNKS(namelen) + NCHUNKS(valuelen); 581*789Sahrens if (numchunks > ZAP_LEAF_NUMCHUNKS) 582*789Sahrens return (E2BIG); 583*789Sahrens 584*789Sahrens if (cd == ZAP_MAXCD) { 585*789Sahrens for (cd = 0; cd < ZAP_MAXCD; cd++) { 586*789Sahrens zap_leaf_t *ll; 587*789Sahrens for (ll = l; ll; ll = ll->l_next) { 588*789Sahrens for (chunk = *LEAF_HASH_ENTPTR(ll, h); 589*789Sahrens chunk != CHAIN_END; chunk = le->le_next) { 590*789Sahrens le = &ll->l_phys->l_chunk 591*789Sahrens [chunk].l_entry; 592*789Sahrens if (le->le_hash == h && 593*789Sahrens le->le_cd == cd) { 594*789Sahrens break; 595*789Sahrens } 596*789Sahrens } 597*789Sahrens /* 598*789Sahrens * if this cd is in use, no need to 599*789Sahrens * check more chained leafs 600*789Sahrens */ 601*789Sahrens if (chunk != CHAIN_END) 602*789Sahrens break; 603*789Sahrens } 604*789Sahrens /* If this cd is not in use, we are good. */ 605*789Sahrens if (chunk == CHAIN_END) 606*789Sahrens break; 607*789Sahrens } 608*789Sahrens /* If we tried all the cd's, we lose. */ 609*789Sahrens if (cd == ZAP_MAXCD) 610*789Sahrens return (ENOSPC); 611*789Sahrens } 612*789Sahrens 613*789Sahrens for (; l; l = l->l_next) 614*789Sahrens if (l->lh_nfree >= numchunks) 615*789Sahrens break; 616*789Sahrens if (l == NULL) 617*789Sahrens return (EAGAIN); 618*789Sahrens 619*789Sahrens zeh->zeh_found_leaf = l; 620*789Sahrens 621*789Sahrens /* make the entry */ 622*789Sahrens chunk = zap_leaf_chunk_alloc(l); 623*789Sahrens le = &l->l_phys->l_chunk[chunk].l_entry; 624*789Sahrens le->le_type = ZAP_LEAF_ENTRY; 625*789Sahrens le->le_name_chunk = zap_leaf_array_create(zeh, name, 1, namelen); 626*789Sahrens le->le_name_length = namelen; 627*789Sahrens le->le_value_chunk = 628*789Sahrens zap_leaf_array_create(zeh, buf, integer_size, num_integers); 629*789Sahrens le->le_value_length = (num_integers*integer_size > MAX_ARRAY_BYTES) ? 630*789Sahrens (MAX_ARRAY_BYTES + 1) : (num_integers); 631*789Sahrens le->le_int_size = integer_size; 632*789Sahrens le->le_hash = h; 633*789Sahrens le->le_cd = cd; 634*789Sahrens 635*789Sahrens /* link it into the hash chain */ 636*789Sahrens chunkp = LEAF_HASH_ENTPTR(l, h); 637*789Sahrens le->le_next = *chunkp; 638*789Sahrens *chunkp = chunk; 639*789Sahrens 640*789Sahrens l->lh_nentries++; 641*789Sahrens 642*789Sahrens zeh->zeh_num_integers = num_integers; 643*789Sahrens zeh->zeh_integer_size = le->le_int_size; 644*789Sahrens zeh->zeh_cd = le->le_cd; 645*789Sahrens zeh->zeh_hash = le->le_hash; 646*789Sahrens zeh->zeh_chunkp = chunkp; 647*789Sahrens 648*789Sahrens return (0); 649*789Sahrens } 650*789Sahrens 651*789Sahrens /* 652*789Sahrens * Routines for transferring entries between leafs. 653*789Sahrens */ 654*789Sahrens 655*789Sahrens static void 656*789Sahrens zap_leaf_rehash_entry(zap_leaf_t *l, uint16_t entry) 657*789Sahrens { 658*789Sahrens struct zap_leaf_entry *le = &l->l_phys->l_chunk[entry].l_entry; 659*789Sahrens uint16_t *ptr = LEAF_HASH_ENTPTR(l, le->le_hash); 660*789Sahrens le->le_next = *ptr; 661*789Sahrens *ptr = entry; 662*789Sahrens } 663*789Sahrens 664*789Sahrens static void 665*789Sahrens zap_leaf_rehash_entries(zap_leaf_t *l) 666*789Sahrens { 667*789Sahrens int i; 668*789Sahrens 669*789Sahrens if (l->lh_nentries == 0) 670*789Sahrens return; 671*789Sahrens 672*789Sahrens /* break existing hash chains */ 673*789Sahrens zap_memset(l->l_phys->l_hash, CHAIN_END, sizeof (l->l_phys->l_hash)); 674*789Sahrens 675*789Sahrens for (i = 0; i < ZAP_LEAF_NUMCHUNKS; i++) { 676*789Sahrens struct zap_leaf_entry *le = &l->l_phys->l_chunk[i].l_entry; 677*789Sahrens if (le->le_type != ZAP_LEAF_ENTRY) 678*789Sahrens continue; 679*789Sahrens zap_leaf_rehash_entry(l, i); 680*789Sahrens } 681*789Sahrens } 682*789Sahrens 683*789Sahrens static uint16_t 684*789Sahrens zap_leaf_transfer_array(zap_leaf_t *l, uint16_t chunk, zap_leaf_t *nl) 685*789Sahrens { 686*789Sahrens uint16_t new_chunk; 687*789Sahrens uint16_t *nchunkp = &new_chunk; 688*789Sahrens 689*789Sahrens while (chunk != CHAIN_END) { 690*789Sahrens uint16_t nchunk = zap_leaf_chunk_alloc(nl); 691*789Sahrens struct zap_leaf_array *nla = 692*789Sahrens &nl->l_phys->l_chunk[nchunk].l_array; 693*789Sahrens struct zap_leaf_array *la = 694*789Sahrens &l->l_phys->l_chunk[chunk].l_array; 695*789Sahrens int nextchunk = la->la_next; 696*789Sahrens 697*789Sahrens ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS); 698*789Sahrens ASSERT3U(nchunk, <, ZAP_LEAF_NUMCHUNKS); 699*789Sahrens 700*789Sahrens *nla = *la; 701*789Sahrens 702*789Sahrens zap_leaf_chunk_free(l, chunk); 703*789Sahrens chunk = nextchunk; 704*789Sahrens *nchunkp = nchunk; 705*789Sahrens nchunkp = &nla->la_next; 706*789Sahrens } 707*789Sahrens *nchunkp = CHAIN_END; 708*789Sahrens return (new_chunk); 709*789Sahrens } 710*789Sahrens 711*789Sahrens static void 712*789Sahrens zap_leaf_transfer_entry(zap_t *zap, zap_leaf_t *l, int entry, zap_leaf_t *nhl, 713*789Sahrens dmu_tx_t *tx) 714*789Sahrens { 715*789Sahrens zap_leaf_t *nl; 716*789Sahrens struct zap_leaf_entry *le, *nle; 717*789Sahrens uint16_t chunk, nchunks; 718*789Sahrens 719*789Sahrens le = &l->l_phys->l_chunk[entry].l_entry; 720*789Sahrens ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY); 721*789Sahrens 722*789Sahrens /* find a leaf in the destination leaf chain with enough free space */ 723*789Sahrens nchunks = 1 + NCHUNKS(le->le_name_length) + 724*789Sahrens NCHUNKS(le->le_value_length * le->le_int_size); 725*789Sahrens for (nl = nhl; nl; nl = nl->l_next) 726*789Sahrens if (nl->lh_nfree >= nchunks) 727*789Sahrens break; 728*789Sahrens if (nl == NULL) { 729*789Sahrens nl = zap_leaf_chainmore(nhl, zap_create_leaf(zap, tx)); 730*789Sahrens dprintf("transfer_entry: chaining leaf %x/%d\n", 731*789Sahrens nl->lh_prefix, nl->lh_prefix_len); 732*789Sahrens } 733*789Sahrens 734*789Sahrens chunk = zap_leaf_chunk_alloc(nl); 735*789Sahrens nle = &nl->l_phys->l_chunk[chunk].l_entry; 736*789Sahrens *nle = *le; 737*789Sahrens 738*789Sahrens zap_leaf_rehash_entry(nl, chunk); 739*789Sahrens 740*789Sahrens nle->le_name_chunk = zap_leaf_transfer_array(l, le->le_name_chunk, nl); 741*789Sahrens nle->le_value_chunk = 742*789Sahrens zap_leaf_transfer_array(l, le->le_value_chunk, nl); 743*789Sahrens 744*789Sahrens zap_leaf_chunk_free(l, entry); 745*789Sahrens 746*789Sahrens l->lh_nentries--; 747*789Sahrens nl->lh_nentries++; 748*789Sahrens } 749*789Sahrens 750*789Sahrens /* 751*789Sahrens * Transfer entries whose hash bit 'bit' is 1 to nl1, and 0 to nl0. 752*789Sahrens * Ignore leaf chaining in source (l), but chain in destinations. 753*789Sahrens * We'll re-chain all the entries in l as we go along. 754*789Sahrens */ 755*789Sahrens static void 756*789Sahrens zap_leaf_transfer_entries(zap_t *zap, zap_leaf_t *l, 757*789Sahrens zap_leaf_t *nl0, zap_leaf_t *nl1, int bit, dmu_tx_t *tx) 758*789Sahrens { 759*789Sahrens int i; 760*789Sahrens 761*789Sahrens ASSERT(bit < 64 && bit >= 0); 762*789Sahrens /* break existing hash chains */ 763*789Sahrens zap_memset(l->l_phys->l_hash, CHAIN_END, sizeof (l->l_phys->l_hash)); 764*789Sahrens 765*789Sahrens if (nl0 != l) 766*789Sahrens zap_leaf_rehash_entries(nl0); 767*789Sahrens if (nl1 != nl0) 768*789Sahrens zap_leaf_rehash_entries(nl1); 769*789Sahrens 770*789Sahrens for (i = 0; i < ZAP_LEAF_NUMCHUNKS; i++) { 771*789Sahrens struct zap_leaf_entry *le = &l->l_phys->l_chunk[i].l_entry; 772*789Sahrens if (le->le_type != ZAP_LEAF_ENTRY) 773*789Sahrens continue; 774*789Sahrens 775*789Sahrens /* 776*789Sahrens * We could find entries via hashtable instead. That 777*789Sahrens * would be O(hashents+numents) rather than 778*789Sahrens * O(numblks+numents), but this accesses memory more 779*789Sahrens * sequentially, and when we're called, the block is 780*789Sahrens * usually pretty full. 781*789Sahrens */ 782*789Sahrens 783*789Sahrens if (le->le_hash & (1ULL << bit)) { 784*789Sahrens zap_leaf_transfer_entry(zap, l, i, nl1, tx); 785*789Sahrens } else { 786*789Sahrens if (nl0 == l) 787*789Sahrens zap_leaf_rehash_entry(l, i); 788*789Sahrens else 789*789Sahrens zap_leaf_transfer_entry(zap, l, i, nl0, tx); 790*789Sahrens } 791*789Sahrens } 792*789Sahrens 793*789Sahrens } 794*789Sahrens 795*789Sahrens /* 796*789Sahrens * nl will contain the entries whose hash prefix ends in 1 797*789Sahrens * handles leaf chaining 798*789Sahrens */ 799*789Sahrens zap_leaf_t * 800*789Sahrens zap_leaf_split(zap_t *zap, zap_leaf_t *hl, dmu_tx_t *tx) 801*789Sahrens { 802*789Sahrens zap_leaf_t *l = hl; 803*789Sahrens int bit = 64 - 1 - hl->lh_prefix_len; 804*789Sahrens zap_leaf_t *nl = zap_create_leaf(zap, tx); 805*789Sahrens 806*789Sahrens /* set new prefix and prefix_len */ 807*789Sahrens hl->lh_prefix <<= 1; 808*789Sahrens hl->lh_prefix_len++; 809*789Sahrens nl->lh_prefix = hl->lh_prefix | 1; 810*789Sahrens nl->lh_prefix_len = hl->lh_prefix_len; 811*789Sahrens 812*789Sahrens /* transfer odd entries from first leaf in hl chain to nl */ 813*789Sahrens zap_leaf_transfer_entries(zap, hl, hl, nl, bit, tx); 814*789Sahrens 815*789Sahrens /* take rest of chain off hl */ 816*789Sahrens l = hl->l_next; 817*789Sahrens hl->l_next = NULL; 818*789Sahrens hl->lh_next = 0; 819*789Sahrens 820*789Sahrens /* transfer even entries from hl chain back to hl, odd entries to nl */ 821*789Sahrens while (l) { 822*789Sahrens zap_leaf_t *next = l->l_next; 823*789Sahrens zap_leaf_transfer_entries(zap, l, hl, nl, bit, tx); 824*789Sahrens zap_destroy_leaf(zap, l, tx); 825*789Sahrens l = next; 826*789Sahrens } 827*789Sahrens 828*789Sahrens return (nl); 829*789Sahrens } 830*789Sahrens 831*789Sahrens void 832*789Sahrens zap_stats_leaf(zap_t *zap, zap_leaf_t *l, zap_stats_t *zs) 833*789Sahrens { 834*789Sahrens int n, nchained = 0; 835*789Sahrens 836*789Sahrens n = zap->zap_f.zap_phys->zap_ptrtbl.zt_shift - l->lh_prefix_len; 837*789Sahrens n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 838*789Sahrens zs->zs_leafs_with_2n_pointers[n]++; 839*789Sahrens 840*789Sahrens do { 841*789Sahrens int i; 842*789Sahrens 843*789Sahrens n = l->lh_nentries/5; 844*789Sahrens n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 845*789Sahrens zs->zs_blocks_with_n5_entries[n]++; 846*789Sahrens 847*789Sahrens n = ((1<<ZAP_BLOCK_SHIFT) - 848*789Sahrens l->lh_nfree * (ZAP_LEAF_ARRAY_BYTES+1))*10 / 849*789Sahrens (1<<ZAP_BLOCK_SHIFT); 850*789Sahrens n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 851*789Sahrens zs->zs_blocks_n_tenths_full[n]++; 852*789Sahrens 853*789Sahrens for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES; i++) { 854*789Sahrens int nentries = 0; 855*789Sahrens int chunk = l->l_phys->l_hash[i]; 856*789Sahrens 857*789Sahrens while (chunk != CHAIN_END) { 858*789Sahrens struct zap_leaf_entry *le = 859*789Sahrens &l->l_phys->l_chunk[chunk].l_entry; 860*789Sahrens 861*789Sahrens n = 1 + NCHUNKS(le->le_name_length) + 862*789Sahrens NCHUNKS(le->le_value_length * 863*789Sahrens le->le_int_size); 864*789Sahrens n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 865*789Sahrens zs->zs_entries_using_n_chunks[n]++; 866*789Sahrens 867*789Sahrens chunk = le->le_next; 868*789Sahrens nentries++; 869*789Sahrens } 870*789Sahrens 871*789Sahrens n = nentries; 872*789Sahrens n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 873*789Sahrens zs->zs_buckets_with_n_entries[n]++; 874*789Sahrens } 875*789Sahrens 876*789Sahrens nchained++; 877*789Sahrens l = l->l_next; 878*789Sahrens } while (l); 879*789Sahrens 880*789Sahrens n = nchained-1; 881*789Sahrens n = MIN(n, ZAP_HISTOGRAM_SIZE-1); 882*789Sahrens zs->zs_leafs_with_n_chained[n]++; 883*789Sahrens } 884