zap_micro.c revision ea8dc4b6d2251b437950c0056bc626b311c73c27
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
f65e61c04bc28ffd6bda04619c84330b420450b5ahrens * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic uint64_t mzap_write_cookie(zap_t *zap, uint64_t cookie,
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < max; i++) {
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)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strlen(name) >= sizeof (mze_tofind.mze_phys.mze_name))
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (; mze && mze->mze_hash == 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens winner = dmu_buf_set_user(db, zap, &zap->zap_m.zap_phys, zap_pageout);
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));
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
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 return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = dmu_object_set_blocksize(os, obj, newsz, 0, tx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = dmu_object_set_blocksize(zap->zap_objset, zap->zap_object,
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < nchunks; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (cp = (const uint8_t *)name; (c = *cp) != '\0'; cp++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ c) & 0xFF];
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Only use 28 bits, since we need 4 bits in the cookie for the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * collision differentiator. We MUST use the high bits, since
fa9e4066f08beec538e775443c5be79dd423fcabahrens * those are the onces that we first pay attention to when
fa9e4066f08beec538e775443c5be79dd423fcabahrens * chosing the bucket.
fa9e4066f08beec538e775443c5be79dd423fcabahrensmzap_create_impl(objset_t *os, uint64_t obj, dmu_tx_t *tx)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zp->mz_salt = ((uintptr_t)db ^ (uintptr_t)tx ^ (obj << 1)) | 1ULL;
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)
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)
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t obj = dmu_object_alloc(os, ot, 0, bonustype, bonuslen, 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)
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Routines for maniplulating attributes.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_lookup(objset_t *os, uint64_t zapobj, const char *name,
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t integer_size, uint64_t num_integers, void *buf)
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_length(objset_t *os, uint64_t zapobj, const char *name,
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = fzap_length(zap, name, integer_size, num_integers);
fa9e4066f08beec538e775443c5be79dd423fcabahrensmzap_addent(zap_t *zap, const char *name, uint64_t hash, uint64_t value)
fa9e4066f08beec538e775443c5be79dd423fcabahrens dprintf("obj=%llu %s=%llu\n", zap->zap_object, name, value);
fa9e4066f08beec538e775443c5be79dd423fcabahrens mzap_ent_phys_t *mze = &zap->zap_m.zap_phys->mz_chunk[i];
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) {
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_add(objset_t *os, uint64_t zapobj, const char *name,
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = fzap_add(zap, name, integer_size, num_integers, val, tx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = fzap_add(zap, name, integer_size, num_integers, val, tx);
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)
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx)
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens bzero(&zap->zap_m.zap_phys->mz_chunk[mze->mze_chunkid],
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Routines for iterating over the attributes.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We want to keep the high 32 bits of the cursor zero if we can, so
fa9e4066f08beec538e775443c5be79dd423fcabahrens * that 32-bit programs can access this. So use a small hash value so
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we can fit 4 bits of cd into the 32-bit cursor.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * [ 4 zero bits | 32-bit collision differentiator | 28-bit hash value ]
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);
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
87e5029a3226958edab1512d6182bc74d8d80c9aahrens err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
87e5029a3226958edab1512d6182bc74d8d80c9aahrens mze = avl_find(&zc->zc_zap->zap_m.zap_avl, &mze_tofind, &idx);
87e5029a3226958edab1512d6182bc74d8d80c9aahrens &zc->zc_zap->zap_m.zap_phys->mz_chunk[mze->mze_chunkid],
fa9e4066f08beec538e775443c5be79dd423fcabahrenszap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, &zap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);