| 1550 | } |
| 1551 | |
| 1552 | int |
| 1553 | zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za) |
| 1554 | { |
| 1555 | int err; |
| 1556 | |
| 1557 | if (zc->zc_hash == -1ULL) |
| 1558 | return (SET_ERROR(ENOENT)); |
| 1559 | |
| 1560 | if (zc->zc_zap == NULL) { |
| 1561 | int hb; |
| 1562 | err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL, |
| 1563 | RW_READER, TRUE, FALSE, NULL, &zc->zc_zap); |
| 1564 | if (err != 0) |
| 1565 | return (err); |
| 1566 | |
| 1567 | /* |
| 1568 | * To support zap_cursor_init_serialized, advance, retrieve, |
| 1569 | * we must add to the existing zc_cd, which may already |
| 1570 | * be 1 due to the zap_cursor_advance. |
| 1571 | */ |
| 1572 | ASSERT(zc->zc_hash == 0); |
| 1573 | hb = zap_hashbits(zc->zc_zap); |
| 1574 | zc->zc_hash = zc->zc_serialized << (64 - hb); |
| 1575 | zc->zc_cd += zc->zc_serialized >> hb; |
| 1576 | if (zc->zc_cd >= zap_maxcd(zc->zc_zap)) /* corrupt serialized */ |
| 1577 | zc->zc_cd = 0; |
| 1578 | } else { |
| 1579 | rw_enter(&zc->zc_zap->zap_rwlock, RW_READER); |
| 1580 | } |
| 1581 | if (!zc->zc_zap->zap_ismicro) { |
| 1582 | err = fzap_cursor_retrieve(zc->zc_zap, zc, za); |
| 1583 | } else { |
| 1584 | avl_index_t idx; |
| 1585 | mzap_ent_t mze_tofind; |
| 1586 | |
| 1587 | mze_tofind.mze_hash = zc->zc_hash; |
| 1588 | mze_tofind.mze_cd = zc->zc_cd; |
| 1589 | |
| 1590 | mzap_ent_t *mze = |
| 1591 | avl_find(&zc->zc_zap->zap_m.zap_avl, &mze_tofind, &idx); |
| 1592 | if (mze == NULL) { |
| 1593 | mze = avl_nearest(&zc->zc_zap->zap_m.zap_avl, |
| 1594 | idx, AVL_AFTER); |
| 1595 | } |
| 1596 | if (mze) { |
| 1597 | mzap_ent_phys_t *mzep = MZE_PHYS(zc->zc_zap, mze); |
| 1598 | ASSERT3U(mze->mze_cd, ==, mzep->mze_cd); |
| 1599 | za->za_normalization_conflict = |
| 1600 | mzap_normalization_conflict(zc->zc_zap, NULL, mze); |
| 1601 | za->za_integer_length = 8; |
| 1602 | za->za_num_integers = 1; |
| 1603 | za->za_first_integer = mzep->mze_value; |
| 1604 | (void) strlcpy(za->za_name, mzep->mze_name, |
| 1605 | sizeof (za->za_name)); |
| 1606 | zc->zc_hash = mze->mze_hash; |
| 1607 | zc->zc_cd = mze->mze_cd; |
| 1608 | err = 0; |
| 1609 | } else { |
no test coverage detected