| 553 | } |
| 554 | |
| 555 | int |
| 556 | zap_entry_create(zap_leaf_t *l, zap_name_t *zn, uint32_t cd, |
| 557 | uint8_t integer_size, uint64_t num_integers, const void *buf, |
| 558 | zap_entry_handle_t *zeh) |
| 559 | { |
| 560 | uint16_t chunk; |
| 561 | struct zap_leaf_entry *le; |
| 562 | uint64_t h = zn->zn_hash; |
| 563 | |
| 564 | uint64_t valuelen = integer_size * num_integers; |
| 565 | |
| 566 | int numchunks = 1 + ZAP_LEAF_ARRAY_NCHUNKS(zn->zn_key_orig_numints * |
| 567 | zn->zn_key_intlen) + ZAP_LEAF_ARRAY_NCHUNKS(valuelen); |
| 568 | if (numchunks > ZAP_LEAF_NUMCHUNKS(l)) |
| 569 | return (SET_ERROR(E2BIG)); |
| 570 | |
| 571 | if (cd == ZAP_NEED_CD) { |
| 572 | /* find the lowest unused cd */ |
| 573 | if (zap_leaf_phys(l)->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED) { |
| 574 | cd = 0; |
| 575 | |
| 576 | for (chunk = *LEAF_HASH_ENTPTR(l, h); |
| 577 | chunk != CHAIN_END; chunk = le->le_next) { |
| 578 | le = ZAP_LEAF_ENTRY(l, chunk); |
| 579 | if (le->le_cd > cd) |
| 580 | break; |
| 581 | if (le->le_hash == h) { |
| 582 | ASSERT3U(cd, ==, le->le_cd); |
| 583 | cd++; |
| 584 | } |
| 585 | } |
| 586 | } else { |
| 587 | /* old unsorted format; do it the O(n^2) way */ |
| 588 | for (cd = 0; ; cd++) { |
| 589 | for (chunk = *LEAF_HASH_ENTPTR(l, h); |
| 590 | chunk != CHAIN_END; chunk = le->le_next) { |
| 591 | le = ZAP_LEAF_ENTRY(l, chunk); |
| 592 | if (le->le_hash == h && |
| 593 | le->le_cd == cd) { |
| 594 | break; |
| 595 | } |
| 596 | } |
| 597 | /* If this cd is not in use, we are good. */ |
| 598 | if (chunk == CHAIN_END) |
| 599 | break; |
| 600 | } |
| 601 | } |
| 602 | /* |
| 603 | * We would run out of space in a block before we could |
| 604 | * store enough entries to run out of CD values. |
| 605 | */ |
| 606 | ASSERT3U(cd, <, zap_maxcd(zn->zn_zap)); |
| 607 | } |
| 608 | |
| 609 | if (zap_leaf_phys(l)->l_hdr.lh_nfree < numchunks) |
| 610 | return (SET_ERROR(EAGAIN)); |
| 611 | |
| 612 | /* make the entry */ |
no test coverage detected