126
127
le = &lc->l_entry;
128
129
le->le_type = BSWAP_8(le->le_type);
129
le->le_int_size = BSWAP_8(le->le_int_size);
130
le->le_value_intlen = BSWAP_8(le->le_value_intlen);
130
131
le->le_next = BSWAP_16(le->le_next);
131
132
le->le_name_chunk = BSWAP_16(le->le_name_chunk);
132
le->le_name_length = BSWAP_16(le->le_name_length);
133
le->le_name_numints = BSWAP_16(le->le_name_numints);
133
134
le->le_value_chunk = BSWAP_16(le->le_value_chunk);
134
le->le_value_length = BSWAP_16(le->le_value_length);
135
le->le_value_numints = BSWAP_16(le->le_value_numints);
135
136
le->le_cd = BSWAP_32(le->le_cd);
136
137
le->le_hash = BSWAP_64(le->le_hash);
315
317
value = (value << 8) | la->la_array[i];
317
319
if (byten == array_int_len) {
318
stv(buf_int_len, buf, value);
320
stv(buf_int_len, p, value);
326
328
chunk = la->la_next;
331
* Only to be used on 8-bit arrays.
332
* array_len is actual len in bytes (not encoded le_value_length).
333
* namenorm is null-terminated.
336
zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn, int chunk, int array_len)
333
zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn,
334
int chunk, int array_numints)
338
if (zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY) {
342
ASSERT(zn->zn_key_intlen == sizeof (*thiskey));
343
thiskey = kmem_alloc(array_numints * sizeof (*thiskey),
346
zap_leaf_array_read(l, chunk, sizeof (*thiskey), array_numints,
347
sizeof (*thiskey), array_numints, thiskey);
348
match = bcmp(thiskey, zn->zn_key_orig,
349
array_numints * sizeof (*thiskey)) == 0;
350
kmem_free(thiskey, array_numints * sizeof (*thiskey));
354
ASSERT(zn->zn_key_intlen == 1);
340
355
if (zn->zn_matchtype == MT_FIRST) {
341
char *thisname = kmem_alloc(array_len, KM_SLEEP);
356
char *thisname = kmem_alloc(array_numints, KM_SLEEP);
344
zap_leaf_array_read(l, chunk, 1, array_len, 1,
345
array_len, thisname);
359
zap_leaf_array_read(l, chunk, sizeof (char), array_numints,
360
sizeof (char), array_numints, thisname);
346
361
match = zap_match(zn, thisname);
347
kmem_free(thisname, array_len);
362
kmem_free(thisname, array_numints);
351
/* Fast path for exact matching */
352
while (bseen < array_len) {
367
* Fast path for exact matching.
368
* First check that the lengths match, so that we don't read
369
* past the end of the zn_key_orig array.
371
if (array_numints != zn->zn_key_orig_numints)
373
while (bseen < array_numints) {
353
374
struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
354
int toread = MIN(array_len - bseen, ZAP_LEAF_ARRAY_BYTES);
375
int toread = MIN(array_numints - bseen, ZAP_LEAF_ARRAY_BYTES);
355
376
ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
356
if (bcmp(la->la_array, zn->zn_name_orij + bseen, toread))
377
if (bcmp(la->la_array, (char *)zn->zn_key_orig + bseen, toread))
358
379
chunk = la->la_next;
361
return (bseen == array_len);
382
return (bseen == array_numints);
393
414
ASSERT(zn->zn_matchtype == MT_EXACT ||
394
415
(l->l_phys->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED));
395
416
if (zap_leaf_array_match(l, zn, le->le_name_chunk,
396
le->le_name_length)) {
397
zeh->zeh_num_integers = le->le_value_length;
398
zeh->zeh_integer_size = le->le_int_size;
417
le->le_name_numints)) {
418
zeh->zeh_num_integers = le->le_value_numints;
419
zeh->zeh_integer_size = le->le_value_intlen;
399
420
zeh->zeh_cd = le->le_cd;
400
421
zeh->zeh_hash = le->le_hash;
401
422
zeh->zeh_chunkp = chunkp;
470
491
ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp);
471
492
ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
473
if (le->le_int_size > integer_size)
494
if (le->le_value_intlen > integer_size)
476
zap_leaf_array_read(zeh->zeh_leaf, le->le_value_chunk, le->le_int_size,
477
le->le_value_length, integer_size, num_integers, buf);
497
zap_leaf_array_read(zeh->zeh_leaf, le->le_value_chunk,
498
le->le_value_intlen, le->le_value_numints,
499
integer_size, num_integers, buf);
479
501
if (zeh->zeh_num_integers > num_integers)
480
502
return (EOVERFLOW);
486
zap_entry_read_name(const zap_entry_handle_t *zeh, uint16_t buflen, char *buf)
508
zap_entry_read_name(zap_t *zap, const zap_entry_handle_t *zeh, uint16_t buflen,
488
511
struct zap_leaf_entry *le =
489
512
ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp);
490
513
ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
492
zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 1,
493
le->le_name_length, 1, buflen, buf);
494
if (le->le_name_length > buflen)
515
if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) {
516
zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 8,
517
le->le_name_numints, 8, buflen / 8, buf);
519
zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 1,
520
le->le_name_numints, 1, buflen, buf);
522
if (le->le_name_numints > buflen)
495
523
return (EOVERFLOW);
552
zap_entry_create(zap_leaf_t *l, const char *name, uint64_t h, uint32_t cd,
580
zap_entry_create(zap_leaf_t *l, zap_name_t *zn, uint32_t cd,
553
581
uint8_t integer_size, uint64_t num_integers, const void *buf,
554
582
zap_entry_handle_t *zeh)
557
585
uint16_t *chunkp;
558
586
struct zap_leaf_entry *le;
559
uint64_t namelen, valuelen;
589
uint64_t h = zn->zn_hash;
562
591
valuelen = integer_size * num_integers;
563
namelen = strlen(name) + 1;
564
ASSERT(namelen >= 2);
566
numchunks = 1 + ZAP_LEAF_ARRAY_NCHUNKS(namelen) +
567
ZAP_LEAF_ARRAY_NCHUNKS(valuelen);
593
numchunks = 1 + ZAP_LEAF_ARRAY_NCHUNKS(zn->zn_key_orig_numints *
594
zn->zn_key_intlen) + ZAP_LEAF_ARRAY_NCHUNKS(valuelen);
568
595
if (numchunks > ZAP_LEAF_NUMCHUNKS(l))
571
if (cd == ZAP_MAXCD) {
598
if (cd == ZAP_NEED_CD) {
572
599
/* find the lowest unused cd */
573
600
if (l->l_phys->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED) {
613
640
chunk = zap_leaf_chunk_alloc(l);
614
641
le = ZAP_LEAF_ENTRY(l, chunk);
615
642
le->le_type = ZAP_CHUNK_ENTRY;
616
le->le_name_chunk = zap_leaf_array_create(l, name, 1, namelen);
617
le->le_name_length = namelen;
643
le->le_name_chunk = zap_leaf_array_create(l, zn->zn_key_orig,
644
zn->zn_key_intlen, zn->zn_key_orig_numints);
645
le->le_name_numints = zn->zn_key_orig_numints;
618
646
le->le_value_chunk =
619
647
zap_leaf_array_create(l, buf, integer_size, num_integers);
620
le->le_value_length = num_integers;
621
le->le_int_size = integer_size;
648
le->le_value_numints = num_integers;
649
le->le_value_intlen = integer_size;