fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
f65e61c04bc28ffd6bda04619c84330b420450b5ahrens * Common Development and Distribution License (the "License").
f65e61c04bc28ffd6bda04619c84330b420450b5ahrens * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
47cb52daa729f19e298c85a84e8df069365c5232Jeff Bonwick * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
bc9014e6a81272073b9854d9f65dd59e18d18c35Justin Gibbs * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
c3d26abc9ee97b4f60233556aadeb57e0bd30bb9Matthew Ahrens * Copyright (c) 2014 Integros [integros.com]
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbsextern inline mzap_phys_t *zap_m_phys(zap_t *zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (48);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (28);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (-1U);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (zap_getflags(zap) & ZAP_FLAG_PRE_HASHED_KEY) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) {
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens for (i = 0; i < zn->zn_key_norm_numints; wp++, i++) {
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens h = (h >> 8) ^
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens * We previously stored the terminating null on
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens * disk, but didn't hash it, so we need to
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens * continue to not hash it. (The
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens * zn_key_*_numints includes the terminating
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens * null for non-binary keys.)
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens h = (h >> 8) ^
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Don't use all 64 bits, since we need some in the cookie for
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * the collision differentiator. We MUST use the high bits,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * since those are the ones that we first pay attention to when
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * chosing the bucket.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick h &= ~((1ULL << (64 - zap_hashbits(zap))) - 1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwzap_normalize(zap_t *zap, const char *name, char *namenorm)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(!(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) u8_textprep_str((char *)name, &inlen, namenorm, &outlen,
d05ba1e6d821a370b97d38899e74cd824e81ab9cTim Haley U8_TEXTPREP_IGNORE_INVALID, U8_UNICODE_LATEST, &err);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(!(zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* MT_BEST or MT_EXACT */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (strcmp(zn->zn_key_orig, matchname) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_name_alloc(zap_t *zap, const char *key, matchtype_t mt)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw zap_name_t *zn = kmem_alloc(sizeof (zap_name_t), KM_SLEEP);
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens zn->zn_key_orig_numints = strlen(zn->zn_key_orig) + 1;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (zap_normalize(zap, key, zn->zn_normbuf) != 0) {
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1;
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens zn->zn_key_norm_numints = zn->zn_key_orig_numints;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_name_alloc_uint64(zap_t *zap, const uint64_t *key, int numints)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zap_name_t *zn = kmem_alloc(sizeof (zap_name_t), KM_SLEEP);
486ae710326c477d7237ab803b67abb9119c0799Matthew Ahrens zn->zn_key_orig_numints = zn->zn_key_norm_numints = numints;
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < max; i++) {
5ad820458efd0fdb914baff9c1447c22b819fa23nd if (block_type == ZBT_MICRO || block_type == BSWAP_64(ZBT_MICRO)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* ASSERT(magic == ZAP_LEAF_MAGIC); */
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (+1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (+1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (; mze && mze->mze_hash == zn->zn_hash; mze = AVL_NEXT(avl, mze)) {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling ASSERT3U(mze->mze_cd, ==, MZE_PHYS(zn->zn_zap, mze)->mze_cd);
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling if (zap_match(zn, MZE_PHYS(zn->zn_zap, mze)->mze_name))
fa9e4066f08beec538e775443c5be79dd423fcabahrens mze && mze->mze_hash == hash; mze = AVL_NEXT(avl, mze)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (mze = avl_destroy_nodes(&zap->zap_m.zap_avl, &avlcookie))
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT3U(MZAP_ENT_LEN, ==, sizeof (mzap_ent_phys_t));
fa9e4066f08beec538e775443c5be79dd423fcabahrens mutex_init(&zap->zap_f.zap_num_entries_mtx, 0, 0, 0);
bf16b11e8deb633dd6c4296d46e92399d1582df4Matthew Ahrens zap->zap_f.zap_block_shift = highbit64(db->db_size) - 1;
02525cd08fb3730fff3a69cb5376443d481f7839Chunwei Chen if (zap_block_type != ZBT_HEADER || zap_magic != ZAP_MAGIC) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Make sure that zap_ismicro is set before we let others see
fa9e4066f08beec538e775443c5be79dd423fcabahrens * it, because zap_lockdir() checks zap_ismicro without the lock
40510e8eba18690b9a9843b26393725eeb0f1dacJosef 'Jeff' Sipek dmu_buf_init_user(&zap->zap_dbu, zap_evict_sync, NULL, &zap->zap_dbuf);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs zap->zap_normflags = zap_m_phys(zap)->mz_normflags;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zap->zap_m.zap_num_chunks = db->db_size / MZAP_ENT_LEN - 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens sizeof (mzap_ent_t), offsetof(mzap_ent_t, mze_node));
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs zap->zap_normflags = zap_f_phys(zap)->zap_normflags;
f65e61c04bc28ffd6bda04619c84330b420450b5ahrens * The embedded pointer table should not overlap the
f65e61c04bc28ffd6bda04619c84330b420450b5ahrens * other members.
f65e61c04bc28ffd6bda04619c84330b420450b5ahrens * The embedded pointer table should end at the end of
f65e61c04bc28ffd6bda04619c84330b420450b5ahrens * the block
02525cd08fb3730fff3a69cb5376443d481f7839Chunwei Chen mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrenszap_lockdir_impl(dmu_buf_t *db, void *tag, dmu_tx_t *tx,
c5f9e43110e1fb316fc4297c2d150b3518b80bbeahrens krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
02525cd08fb3730fff3a69cb5376443d481f7839Chunwei Chen * mzap_open() didn't like what it saw on-disk.
02525cd08fb3730fff3a69cb5376443d481f7839Chunwei Chen * Check for corruption!
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We're checking zap_ismicro without the lock held, in order to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * tell what type of lock we want. Once we have some sort of
fa9e4066f08beec538e775443c5be79dd423fcabahrens * lock, see if it really is the right type. In practice this
fa9e4066f08beec538e775443c5be79dd423fcabahrens * can only be different if it was upgraded from micro to fat,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and micro wanted WRITER but fat only needs READER.
fa9e4066f08beec538e775443c5be79dd423fcabahrens lt = (!zap->zap_ismicro && fatreader) ? RW_READER : lti;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (lt != ((!zap->zap_ismicro && fatreader) ? RW_READER : lti)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* it was upgraded, now we only need reader */
fa9e4066f08beec538e775443c5be79dd423fcabahrens zap->zap_m.zap_num_entries <= zap->zap_m.zap_num_chunks);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zap->zap_m.zap_num_entries == zap->zap_m.zap_num_chunks) {
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens VERIFY0(dmu_object_set_blocksize(os, obj, newsz, 0, tx));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrenszap_lockdir_by_dnode(dnode_t *dn, dmu_tx_t *tx,
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp)
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens err = dmu_buf_hold_by_dnode(dn, 0, tag, &db, DMU_READ_NO_PREFETCH);
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens err = zap_lockdir_impl(db, tag, tx, lti, fatreader, adding, zapp);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrenszap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp)
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = dmu_buf_hold(os, obj, 0, tag, &db, DMU_READ_NO_PREFETCH);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir_impl(db, tag, tx, lti, fatreader, adding, zapp);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrensmzap_upgrade(zap_t **zapp, void *tag, dmu_tx_t *tx, zap_flags_t flags)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = dmu_object_set_blocksize(zap->zap_objset, zap->zap_object,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* XXX destroy the avl later, so we can use the stored hash value */
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < nchunks; i++) {
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd,
ad860c82b2a8ffe69f42630da73ded0c92a7a36ebonwick zap = zn->zn_zap; /* fzap_add_cd() may change zap */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickmzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags,
47cb52daa729f19e298c85a84e8df069365c5232Jeff Bonwick VERIFY(0 == dmu_buf_hold(os, obj, 0, FTAG, &db, DMU_READ_NO_PREFETCH));
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zp->mz_salt = ((uintptr_t)db ^ (uintptr_t)tx ^ (obj << 1)) | 1ULL;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick /* Only fat zap supports flags; upgrade immediately. */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens VERIFY3U(0, ==, mzap_upgrade(&zap, FTAG, tx, flags));
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_create_claim(objset_t *os, uint64_t obj, dmu_object_type_t ot,
fa9e4066f08beec538e775443c5be79dd423fcabahrens dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwzap_create_claim_norm(objset_t *os, uint64_t obj, int normflags,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = dmu_object_claim(os, obj, ot, 0, bonustype, bonuslen, tx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (zap_create_norm(os, 0, ot, bonustype, bonuslen, tx));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwzap_create_norm(objset_t *os, int normflags, dmu_object_type_t ot,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t obj = dmu_object_alloc(os, ot, 0, bonustype, bonuslen, tx);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_create_flags(objset_t *os, int normflags, zap_flags_t flags,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t obj = dmu_object_alloc(os, ot, 0, bonustype, bonuslen, tx);
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens indirect_blockshift <= SPA_OLD_MAXBLOCKSHIFT);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick 1ULL << leaf_blockshift, indirect_blockshift, tx) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick mzap_create_impl(os, obj, normflags, flags, tx);
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_destroy(objset_t *os, uint64_t zapobj, dmu_tx_t *tx)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * dmu_object_free will free the object number and free the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * data. Freeing the data will cause our pageout function to be
fa9e4066f08beec538e775443c5be79dd423fcabahrens * called, which will destroy our data (zap_leaf_t's and zap_t).
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * zn may be NULL; if not specified, it will be computed if needed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See also the comment above zap_entry_normalization_conflict().
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwmzap_normalization_conflict(zap_t *zap, zap_name_t *zn, mzap_ent_t *mze)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (other = avl_walk(&zap->zap_m.zap_avl, mze, direction);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw other = avl_walk(&zap->zap_m.zap_avl, other, direction)) {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling zn = zap_name_alloc(zap, MZE_PHYS(zap, mze)->mze_name,
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling if (zap_match(zn, MZE_PHYS(zap, other)->mze_name)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Routines for manipulating attributes.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_lookup(objset_t *os, uint64_t zapobj, const char *name,
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t integer_size, uint64_t num_integers, void *buf)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint64_t integer_size, uint64_t num_integers, void *buf,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrenszap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens uint64_t integer_size, uint64_t num_integers, void *buf,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lookup_impl(zap, name, integer_size,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens num_integers, buf, mt, realname, rn_len, ncp);
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrenszap_lookup_by_dnode(dnode_t *dn, const char *name,
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens uint64_t integer_size, uint64_t num_integers, void *buf)
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens return (zap_lookup_norm_by_dnode(dn, name, integer_size,
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens num_integers, buf, MT_EXACT, NULL, 0, NULL));
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrenszap_lookup_norm_by_dnode(dnode_t *dn, const char *name,
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens uint64_t integer_size, uint64_t num_integers, void *buf,
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens err = zap_lockdir_by_dnode(dn, NULL, RW_READER, TRUE, FALSE,
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens err = zap_lookup_impl(zap, name, integer_size,
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens num_integers, buf, mt, realname, rn_len, ncp);
c7cd242109c82107ec2e50013369e92be9d77702George Wilsonzap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
c7cd242109c82107ec2e50013369e92be9d77702George Wilson zn = zap_name_alloc_uint64(zap, key, key_numints);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf)
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn = zap_name_alloc_uint64(zap, key, key_numints);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = fzap_lookup(zn, integer_size, num_integers, buf,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Ericksonzap_contains(objset_t *os, uint64_t zapobj, const char *name)
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrens int err = zap_lookup_norm(os, zapobj, name, 0,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson err = 0; /* found, but skipped reading the value */
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_length(objset_t *os, uint64_t zapobj, const char *name,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick int key_numints, uint64_t *integer_size, uint64_t *num_integers)
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn = zap_name_alloc_uint64(zap, key, key_numints);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = fzap_length(zn, integer_size, num_integers);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs mzap_ent_phys_t *mze = &zap_m_phys(zap)->mz_chunk[i];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(strcmp(zn->zn_key_orig, mze->mze_name) != 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* given the limited size of the microzap, this can't happen */
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = start; i < zap->zap_m.zap_num_chunks; i++) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs mzap_ent_phys_t *mze = &zap_m_phys(zap)->mz_chunk[i];
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (start != 0) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_add(objset_t *os, uint64_t zapobj, const char *key,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = fzap_add(zn, integer_size, num_integers, val, FTAG, tx);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = fzap_add(zn, integer_size, num_integers, val,
ad860c82b2a8ffe69f42630da73ded0c92a7a36ebonwick if (zap != NULL) /* may be NULL if fzap_add() failed */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_add_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick int key_numints, int integer_size, uint64_t num_integers,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn = zap_name_alloc_uint64(zap, key, key_numints);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = fzap_add(zn, integer_size, num_integers, val, FTAG, tx);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zap = zn->zn_zap; /* fzap_add() may change zap */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (zap != NULL) /* may be NULL if fzap_add() failed */
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_update(objset_t *os, uint64_t zapobj, const char *name,
fa9e4066f08beec538e775443c5be79dd423fcabahrens int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * If there is an old value, it shouldn't change across the
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * lockdir (eg, due to bprewrite's xlation).
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling (void) zap_lookup(os, zapobj, name, 8, 1, &oldval);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = fzap_update(zn, integer_size, num_integers, val,
ad860c82b2a8ffe69f42630da73ded0c92a7a36ebonwick zap = zn->zn_zap; /* fzap_update() may change zap */
fa9e4066f08beec538e775443c5be79dd423fcabahrens dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0);
ad860c82b2a8ffe69f42630da73ded0c92a7a36ebonwick zap = zn->zn_zap; /* fzap_update() may change zap */
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling ASSERT3U(MZE_PHYS(zap, mze)->mze_value, ==, oldval);
ad860c82b2a8ffe69f42630da73ded0c92a7a36ebonwick if (zap != NULL) /* may be NULL if fzap_upgrade() failed */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_update_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn = zap_name_alloc_uint64(zap, key, key_numints);
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = fzap_update(zn, integer_size, num_integers, val, FTAG, tx);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zap = zn->zn_zap; /* fzap_update() may change zap */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (zap != NULL) /* may be NULL if fzap_upgrade() failed */
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (zap_remove_norm(os, zapobj, name, MT_EXACT, tx));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwzap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs bzero(&zap_m_phys(zap)->mz_chunk[mze->mze_chunkid],
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn = zap_name_alloc_uint64(zap, key, key_numints);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Routines for iterating over the attributes.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, uint64_t zapobj,
87e5029a3226958edab1512d6182bc74d8d80c9aahrenszap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1ULL);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT((zc->zc_hash & zap_maxcd(zc->zc_zap)) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * We want to keep the high 32 bits of the cursor zero if we can, so
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * that 32-bit programs can access this. So usually use a small
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * (28-bit) hash value so we can fit 4 bits of cd into the low 32-bits
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * of the cursor.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * [ collision differentiator | zap_hashbits()-bit hash value ]
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return ((zc->zc_hash >> (64 - zap_hashbits(zc->zc_zap))) |
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ((uint64_t)zc->zc_cd << zap_hashbits(zc->zc_zap)));
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
87e5029a3226958edab1512d6182bc74d8d80c9aahrens err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * To support zap_cursor_init_serialized, advance, retrieve,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * we must add to the existing zc_cd, which may already
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * be 1 due to the zap_cursor_advance.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (zc->zc_cd >= zap_maxcd(zc->zc_zap)) /* corrupt serialized */
87e5029a3226958edab1512d6182bc74d8d80c9aahrens mze = avl_find(&zc->zc_zap->zap_m.zap_avl, &mze_tofind, &idx);
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrenszap_count_write_by_dnode(dnode_t *dn, const char *name, int add,
0c779ad424a92a84d1e07d47cab7f8009189202bMatthew Ahrens refcount_t *towrite, refcount_t *tooverwrite)
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * Since, we don't have a name, we cannot figure out which blocks will
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * be affected in this operation. So, account for the worst case :
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * - 3 blocks overwritten: target leaf, ptrtbl block, header block
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * - 4 new blocks written if adding:
0c779ad424a92a84d1e07d47cab7f8009189202bMatthew Ahrens * - 2 blocks for possibly split leaves,
0c779ad424a92a84d1e07d47cab7f8009189202bMatthew Ahrens * - 2 grown ptrtbl blocks
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens * This also accommodates the case where an add operation to a fairly
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * large microzap results in a promotion to fatzap.
0c779ad424a92a84d1e07d47cab7f8009189202bMatthew Ahrens (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE, FTAG);
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * We lock the zap with adding == FALSE. Because, if we pass
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * the actual value of add, it could trigger a mzap_upgrade().
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * At present we are just evaluating the possibility of this operation
ae9727953cac4bd427aafd9f27458e401590bcb5Matthew Ahrens * and hence we do not want to trigger an upgrade.
79d728325e257b05859d2eef4a4dfbefdce05a76Matthew Ahrens err = zap_lockdir_by_dnode(dn, NULL, RW_READER, TRUE, FALSE,
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi zap_name_t *zn = zap_name_alloc(zap, name, MT_EXACT);
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * We treat this case as similar to (name == NULL)
0c779ad424a92a84d1e07d47cab7f8009189202bMatthew Ahrens (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE, FTAG);
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * We are here if (name != NULL) and this is a micro-zap.
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * We account for the header block depending on whether it
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * is freeable.
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * Incase of an add-operation it is hard to find out
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * if this add will promote this microzap to fatzap.
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * Hence, we consider the worst case and account for the
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * blocks assuming this microzap would be promoted to a
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * 1 block overwritten : header block
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * 4 new blocks written : 2 new split leaf, 2 grown
720d1aa11ffe42c822fb6151fb4ae83194389942Sanjeev Bagewadi * ptrtbl blocks