zap_micro.c revision b24ab6762772a3f6a89393947930c7fa61306783
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
d05ba1e6d821a370b97d38899e74cd824e81ab9cTim Haley * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickstatic int mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (zap->zap_u.zap_fat.zap_phys->zap_flags);
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 const uint8_t *cp = (const uint8_t *)zn->zn_key_norm;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Because we previously stored the terminating null on
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * disk, but didn't hash it, we need to continue to not
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * hash it. (The zn_key_*_len includes the terminating
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * null for non-binary keys.)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (!(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY))
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick h = (h >> 8) ^ zfs_crc64_table[(h ^ *cp) & 0xFF];
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);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn->zn_key_orig_len = strlen(zn->zn_key_orig) + 1;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (zap_normalize(zap, key, zn->zn_normbuf) != 0) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn->zn_key_norm_len = strlen(zn->zn_key_norm) + 1;
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);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn->zn_key_orig_len = zn->zn_key_norm_len = 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);
fa9e4066f08beec538e775443c5be79dd423fcabahrensmze_insert(zap_t *zap, int chunkid, uint64_t hash, mzap_ent_phys_t *mzep)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (; mze && mze->mze_hash == zn->zn_hash; mze = AVL_NEXT(avl, mze)) {
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);
f65e61c04bc28ffd6bda04619c84330b420450b5ahrens zap->zap_f.zap_block_shift = highbit(db->db_size) - 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Make sure that zap_ismicro is set before we let others see
fa9e4066f08beec538e775443c5be79dd423fcabahrens * it, because zap_lockdir() checks zap_ismicro without the lock
455d5089097abbf7ee4538a03c4df823497b6e68ahrens winner = dmu_buf_set_user(db, zap, &zap->zap_m.zap_phys, zap_evict);
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));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw zap->zap_normflags = zap->zap_f.zap_phys->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
c5f9e43110e1fb316fc4297c2d150b3518b80bbeahrens krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
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) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = dmu_object_set_blocksize(os, obj, newsz, 0, tx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickmzap_upgrade(zap_t **zapp, 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++) {
ad860c82b2a8ffe69f42630da73ded0c92a7a36ebonwick err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd, tx);
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,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
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,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY3U(0, ==, mzap_upgrade(&zap, 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);
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)
c5f9e43110e1fb316fc4297c2d150b3518b80bbeahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &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)) {
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)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwzap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint64_t integer_size, uint64_t num_integers, void *buf,
c5f9e43110e1fb316fc4297c2d150b3518b80bbeahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
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)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn = zap_name_alloc_uint64(zap, key, key_numints);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = fzap_lookup(zn, integer_size, num_integers, buf,
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_length(objset_t *os, uint64_t zapobj, const char *name,
c5f9e43110e1fb316fc4297c2d150b3518b80bbeahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &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)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn = zap_name_alloc_uint64(zap, key, key_numints);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = fzap_length(zn, integer_size, num_integers);
fa9e4066f08beec538e775443c5be79dd423fcabahrens mzap_ent_phys_t *mze = &zap->zap_m.zap_phys->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++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mzap_ent_phys_t *mze = &zap->zap_m.zap_phys->mz_chunk[i];
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (start != 0) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_add(objset_t *os, uint64_t zapobj, const char *key,
c5f9e43110e1fb316fc4297c2d150b3518b80bbeahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = fzap_add(zn, integer_size, num_integers, val, tx);
ad860c82b2a8ffe69f42630da73ded0c92a7a36ebonwick err = fzap_add(zn, integer_size, num_integers, val, tx);
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,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn = zap_name_alloc_uint64(zap, key, key_numints);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = fzap_add(zn, integer_size, num_integers, val, 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)
c5f9e43110e1fb316fc4297c2d150b3518b80bbeahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = fzap_update(zn, integer_size, num_integers, val, tx);
ad860c82b2a8ffe69f42630da73ded0c92a7a36ebonwick zap = zn->zn_zap; /* fzap_update() may change zap */
fa9e4066f08beec538e775443c5be79dd423fcabahrens dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
ad860c82b2a8ffe69f42630da73ded0c92a7a36ebonwick zap = zn->zn_zap; /* fzap_update() may change zap */
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)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zn = zap_name_alloc_uint64(zap, key, key_numints);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = fzap_update(zn, integer_size, num_integers, val, 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,
c5f9e43110e1fb316fc4297c2d150b3518b80bbeahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens bzero(&zap->zap_m.zap_phys->mz_chunk[mze->mze_chunkid],
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &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);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correiazap_cursor_move_to_key(zap_cursor_t *zc, const char *name, matchtype_t mt)
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia zn = zap_name_alloc(zc->zc_zap, name, mt);
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
c5f9e43110e1fb316fc4297c2d150b3518b80bbeahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadizap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
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:
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * - 2 blocks for possibly split leaves,
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * - 2 grown ptrtbl blocks
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * This also accomodates the case where an add operation to a fairly
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * large microzap results in a promotion to fatzap.
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi *towrite += (3 + (add ? 4 : 0)) * SPA_MAXBLOCKSIZE;
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * 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
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * and hence we donot want to trigger an upgrade.
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi zap_name_t *zn = zap_name_alloc(zap, name, MT_EXACT);
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi * We treat this case as similar to (name == NULL)
3d6926289465757c3da780cea696825b0d730283Sanjeev Bagewadi *towrite += (3 + (add ? 4 : 0)) * SPA_MAXBLOCKSIZE;
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