usr/src/uts/common/fs/zfs/zap_micro.c
author eschrock
Tue, 05 Sep 2006 11:37:36 -0700
changeset 2676 5cee47eddab6
parent 2641 967ea438b194
child 2856 6f4d5ee1906a
permissions -rw-r--r--
PSARC 2006/486 ZFS canmount property PSARC 2006/497 ZFS create time properties PSARC 2006/502 ZFS get all datasets PSARC 2006/504 ZFS user properties 6269805 properties should be set via an nvlist. 6281585 user defined properties 6349494 'zfs list' output annoying for even moderately long dataset names 6366244 'canmount' option for container-like functionality 6367103 create-time properties 6416639 RFE: provide zfs get -a 6437808 ZFS module version should match on-disk version 6454551 'zfs create -b blocksize filesystem' should fail. 6457478 unrecognized character in error message with 'zpool create -R' command 6457865 missing device name in the error message of 'zpool clear' command 6458571 zfs_ioc_set_prop() doesn't validate input 6458614 zfs ACL #defines should use prefix 6458638 get_configs() accesses bogus memory 6458678 zvol functions should be moved out of zfs_ioctl.h 6458683 zfs_cmd_t could use more cleanup 6458691 common routines to manage zfs_cmd_t nvlists 6460398 zpool import cores on zfs_prop_get 6461029 zpool status -x noexisting-pool has incorrect error message. 6461223 index translations should live with property definitions 6461424 zpool_unmount_datasets() has some busted logic 6461427 zfs_realloc() would be useful 6461757 'zpool status' can report the wrong number of persistent errors 6461784 recursive zfs_snapshot() leaks memory
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
     5
 * Common Development and Distribution License (the "License").
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/dmu.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/zap.h>
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
    32
#include <sys/refcount.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/zap_impl.h>
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
    34
#include <sys/zap_leaf.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/avl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
static uint64_t mzap_write_cookie(zap_t *zap, uint64_t cookie,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
    uint64_t entptr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
static void mzap_upgrade(zap_t *zap, dmu_tx_t *tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
mzap_byteswap(mzap_phys_t *buf, size_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
	int i, max;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
	buf->mz_block_type = BSWAP_64(buf->mz_block_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
	buf->mz_salt = BSWAP_64(buf->mz_salt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
	max = (size / MZAP_ENT_LEN) - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
	for (i = 0; i < max; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
		buf->mz_chunk[i].mze_value =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
		    BSWAP_64(buf->mz_chunk[i].mze_value);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
		buf->mz_chunk[i].mze_cd =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
		    BSWAP_32(buf->mz_chunk[i].mze_cd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
zap_byteswap(void *buf, size_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
	uint64_t block_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
	block_type = *(uint64_t *)buf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
	switch (block_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
	case ZBT_MICRO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
	case BSWAP_64(ZBT_MICRO):
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
		/* ASSERT(magic == ZAP_LEAF_MAGIC); */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
		mzap_byteswap(buf, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
	default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
		fzap_byteswap(buf, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
mze_compare(const void *arg1, const void *arg2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
	const mzap_ent_t *mze1 = arg1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
	const mzap_ent_t *mze2 = arg2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
	if (mze1->mze_hash > mze2->mze_hash)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
		return (+1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
	if (mze1->mze_hash < mze2->mze_hash)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
	if (mze1->mze_phys.mze_cd > mze2->mze_phys.mze_cd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
		return (+1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
	if (mze1->mze_phys.mze_cd < mze2->mze_phys.mze_cd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
mze_insert(zap_t *zap, int chunkid, uint64_t hash, mzap_ent_phys_t *mzep)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
	ASSERT(zap->zap_ismicro);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
	ASSERT(mzep->mze_cd < ZAP_MAXCD);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
	ASSERT3U(zap_hash(zap, mzep->mze_name), ==, hash);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
	mze = kmem_alloc(sizeof (mzap_ent_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
	mze->mze_chunkid = chunkid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
	mze->mze_hash = hash;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
	mze->mze_phys = *mzep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
	avl_add(&zap->zap_m.zap_avl, mze);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
static mzap_ent_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
mze_find(zap_t *zap, const char *name, uint64_t hash)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
	mzap_ent_t mze_tofind;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
	avl_index_t idx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
	avl_tree_t *avl = &zap->zap_m.zap_avl;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
	ASSERT(zap->zap_ismicro);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
	ASSERT3U(zap_hash(zap, name), ==, hash);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
	if (strlen(name) >= sizeof (mze_tofind.mze_phys.mze_name))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
	mze_tofind.mze_hash = hash;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
	mze_tofind.mze_phys.mze_cd = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
	mze = avl_find(avl, &mze_tofind, &idx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
	if (mze == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
		mze = avl_nearest(avl, idx, AVL_AFTER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
	for (; mze && mze->mze_hash == hash; mze = AVL_NEXT(avl, mze)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
		if (strcmp(name, mze->mze_phys.mze_name) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
			return (mze);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
static uint32_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
mze_find_unused_cd(zap_t *zap, uint64_t hash)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
	mzap_ent_t mze_tofind;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
	avl_index_t idx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
	avl_tree_t *avl = &zap->zap_m.zap_avl;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
	uint32_t cd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
	ASSERT(zap->zap_ismicro);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	mze_tofind.mze_hash = hash;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
	mze_tofind.mze_phys.mze_cd = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
	cd = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
	for (mze = avl_find(avl, &mze_tofind, &idx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
	    mze && mze->mze_hash == hash; mze = AVL_NEXT(avl, mze)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
		if (mze->mze_phys.mze_cd != cd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
		cd++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	return (cd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
mze_remove(zap_t *zap, mzap_ent_t *mze)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
	ASSERT(zap->zap_ismicro);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	avl_remove(&zap->zap_m.zap_avl, mze);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
	kmem_free(mze, sizeof (mzap_ent_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
mze_destroy(zap_t *zap)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
	void *avlcookie = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
	while (mze = avl_destroy_nodes(&zap->zap_m.zap_avl, &avlcookie))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
		kmem_free(mze, sizeof (mzap_ent_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	avl_destroy(&zap->zap_m.zap_avl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
static zap_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
	zap_t *winner;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
	zap_t *zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
	ASSERT3U(MZAP_ENT_LEN, ==, sizeof (mzap_ent_phys_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
	zap = kmem_zalloc(sizeof (zap_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
	rw_init(&zap->zap_rwlock, 0, 0, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
	rw_enter(&zap->zap_rwlock, RW_WRITER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
	zap->zap_objset = os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
	zap->zap_object = obj;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
	zap->zap_dbuf = db;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
	if (((uint64_t *)db->db_data)[0] != ZBT_MICRO) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
		mutex_init(&zap->zap_f.zap_num_entries_mtx, 0, 0, 0);
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   204
		zap->zap_f.zap_block_shift = highbit(db->db_size) - 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
		zap->zap_ismicro = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	 * Make sure that zap_ismicro is set before we let others see
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
	 * it, because zap_lockdir() checks zap_ismicro without the lock
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
	 * held.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
	 */
2641
967ea438b194 6462174 zap_update() likes to return 0
ahrens
parents: 1544
diff changeset
   214
	winner = dmu_buf_set_user(db, zap, &zap->zap_m.zap_phys, zap_evict);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
	if (winner != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
		kmem_free(zap, sizeof (zap_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
		return (winner);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
	if (zap->zap_ismicro) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
		zap->zap_salt = zap->zap_m.zap_phys->mz_salt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
		zap->zap_m.zap_num_chunks = db->db_size / MZAP_ENT_LEN - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
		avl_create(&zap->zap_m.zap_avl, mze_compare,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
		    sizeof (mzap_ent_t), offsetof(mzap_ent_t, mze_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
		for (i = 0; i < zap->zap_m.zap_num_chunks; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
			mzap_ent_phys_t *mze =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
			    &zap->zap_m.zap_phys->mz_chunk[i];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
			if (mze->mze_name[0]) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
				zap->zap_m.zap_num_entries++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
				mze_insert(zap, i,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
				    zap_hash(zap, mze->mze_name), mze);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
		zap->zap_salt = zap->zap_f.zap_phys->zap_salt;
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   238
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   239
		ASSERT3U(sizeof (struct zap_leaf_header), ==,
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   240
		    2*ZAP_LEAF_CHUNKSIZE);
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   241
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   242
		/*
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   243
		 * The embedded pointer table should not overlap the
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   244
		 * other members.
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   245
		 */
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   246
		ASSERT3P(&ZAP_EMBEDDED_PTRTBL_ENT(zap, 0), >,
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   247
		    &zap->zap_f.zap_phys->zap_salt);
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   248
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   249
		/*
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   250
		 * The embedded pointer table should end at the end of
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   251
		 * the block
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   252
		 */
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   253
		ASSERT3U((uintptr_t)&ZAP_EMBEDDED_PTRTBL_ENT(zap,
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   254
		    1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap)) -
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   255
		    (uintptr_t)zap->zap_f.zap_phys, ==,
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   256
		    zap->zap_dbuf->db_size);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	rw_exit(&zap->zap_rwlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	return (zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
    krw_t lti, int fatreader, zap_t **zapp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
	zap_t *zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
	dmu_buf_t *db;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
	krw_t lt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
	*zapp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   273
	err = dmu_buf_hold(os, obj, 0, NULL, &db);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   274
	if (err)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   275
		return (err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
#ifdef ZFS_DEBUG
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
		dmu_object_info_t doi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
		dmu_object_info_from_db(db, &doi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
		ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
	zap = dmu_buf_get_user(db);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
	if (zap == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
		zap = mzap_open(os, obj, db);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
	 * We're checking zap_ismicro without the lock held, in order to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
	 * tell what type of lock we want.  Once we have some sort of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
	 * lock, see if it really is the right type.  In practice this
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
	 * can only be different if it was upgraded from micro to fat,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
	 * and micro wanted WRITER but fat only needs READER.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
	lt = (!zap->zap_ismicro && fatreader) ? RW_READER : lti;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	rw_enter(&zap->zap_rwlock, lt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
	if (lt != ((!zap->zap_ismicro && fatreader) ? RW_READER : lti)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
		/* it was upgraded, now we only need reader */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
		ASSERT(lt == RW_WRITER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
		ASSERT(RW_READER ==
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
		    (!zap->zap_ismicro && fatreader) ? RW_READER : lti);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
		rw_downgrade(&zap->zap_rwlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
		lt = RW_READER;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
	zap->zap_objset = os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
	if (lt == RW_WRITER)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
		dmu_buf_will_dirty(db, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
	ASSERT3P(zap->zap_dbuf, ==, db);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
	ASSERT(!zap->zap_ismicro ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
	    zap->zap_m.zap_num_entries <= zap->zap_m.zap_num_chunks);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
	if (zap->zap_ismicro && tx &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
	    zap->zap_m.zap_num_entries == zap->zap_m.zap_num_chunks) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
		uint64_t newsz = db->db_size + SPA_MINBLOCKSIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
		if (newsz > MZAP_MAX_BLKSZ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
			dprintf("upgrading obj %llu: num_entries=%u\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
			    obj, zap->zap_m.zap_num_entries);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
			mzap_upgrade(zap, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
			*zapp = zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
			return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
		err = dmu_object_set_blocksize(os, obj, newsz, 0, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
		ASSERT3U(err, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
		zap->zap_m.zap_num_chunks =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
		    db->db_size / MZAP_ENT_LEN - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	*zapp = zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
zap_unlockdir(zap_t *zap)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
	rw_exit(&zap->zap_rwlock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   340
	dmu_buf_rele(zap->zap_dbuf, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
mzap_upgrade(zap_t *zap, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	mzap_phys_t *mzp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
	int i, sz, nchunks, err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	sz = zap->zap_dbuf->db_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
	mzp = kmem_alloc(sz, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	bcopy(zap->zap_dbuf->db_data, mzp, sz);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
	nchunks = zap->zap_m.zap_num_chunks;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
	err = dmu_object_set_blocksize(zap->zap_objset, zap->zap_object,
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   357
	    1ULL << fzap_default_block_shift, 0, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
	ASSERT(err == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
	dprintf("upgrading obj=%llu with %u chunks\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
	    zap->zap_object, nchunks);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
	mze_destroy(zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
	fzap_upgrade(zap, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
	for (i = 0; i < nchunks; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
		int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
		mzap_ent_phys_t *mze = &mzp->mz_chunk[i];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
		if (mze->mze_name[0] == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
		dprintf("adding %s=%llu\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
		    mze->mze_name, mze->mze_value);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
		err = fzap_add_cd(zap,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
		    mze->mze_name, 8, 1, &mze->mze_value,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   375
		    mze->mze_cd, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
		ASSERT3U(err, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
	kmem_free(mzp, sz);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
zap_hash(zap_t *zap, const char *name)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
	const uint8_t *cp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
	uint8_t c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
	uint64_t crc = zap->zap_salt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
	ASSERT(crc != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
	ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
	for (cp = (const uint8_t *)name; (c = *cp) != '\0'; cp++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
		crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ c) & 0xFF];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
	 * Only use 28 bits, since we need 4 bits in the cookie for the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
	 * collision differentiator.  We MUST use the high bits, since
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	 * those are the onces that we first pay attention to when
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
	 * chosing the bucket.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
	crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
	return (crc);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
mzap_create_impl(objset_t *os, uint64_t obj, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
	dmu_buf_t *db;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
	mzap_phys_t *zp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   411
	VERIFY(0 == dmu_buf_hold(os, obj, 0, FTAG, &db));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
#ifdef ZFS_DEBUG
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
		dmu_object_info_t doi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
		dmu_object_info_from_db(db, &doi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
		ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
	dmu_buf_will_dirty(db, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
	zp = db->db_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
	zp->mz_block_type = ZBT_MICRO;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
	zp->mz_salt = ((uintptr_t)db ^ (uintptr_t)tx ^ (obj << 1)) | 1ULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
	ASSERT(zp->mz_salt != 0);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1491
diff changeset
   426
	dmu_buf_rele(db, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
zap_create_claim(objset_t *os, uint64_t obj, dmu_object_type_t ot,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
	err = dmu_object_claim(os, obj, ot, 0, bonustype, bonuslen, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
	if (err != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
	mzap_create_impl(os, obj, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   442
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   443
zap_create(objset_t *os, dmu_object_type_t ot,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   444
    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
	uint64_t obj = dmu_object_alloc(os, ot, 0, bonustype, bonuslen, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
	mzap_create_impl(os, obj, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
	return (obj);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
zap_destroy(objset_t *os, uint64_t zapobj, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
	 * dmu_object_free will free the object number and free the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
	 * data.  Freeing the data will cause our pageout function to be
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
	 * called, which will destroy our data (zap_leaf_t's and zap_t).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
	return (dmu_object_free(os, zapobj, tx));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
_NOTE(ARGSUSED(0))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
void
2641
967ea438b194 6462174 zap_update() likes to return 0
ahrens
parents: 1544
diff changeset
   466
zap_evict(dmu_buf_t *db, void *vzap)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
{
2641
967ea438b194 6462174 zap_update() likes to return 0
ahrens
parents: 1544
diff changeset
   468
	zap_t *zap = vzap;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
	rw_destroy(&zap->zap_rwlock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
1491
bdcb30e07e7d 6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents: 885
diff changeset
   472
	if (zap->zap_ismicro)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
		mze_destroy(zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
	kmem_free(zap, sizeof (zap_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
	zap_t *zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, &zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
	if (err)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
	if (!zap->zap_ismicro) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
		err = fzap_count(zap, count);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
		*count = zap->zap_m.zap_num_entries;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
	zap_unlockdir(zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
 * Routines for maniplulating attributes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
zap_lookup(objset_t *os, uint64_t zapobj, const char *name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
    uint64_t integer_size, uint64_t num_integers, void *buf)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
	zap_t *zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, &zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
	if (err)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
	if (!zap->zap_ismicro) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
		err = fzap_lookup(zap, name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
		    integer_size, num_integers, buf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
		mze = mze_find(zap, name, zap_hash(zap, name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
		if (mze == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
			err = ENOENT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
			if (num_integers < 1)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
				err = EOVERFLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
			else if (integer_size != 8)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
				err = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
				*(uint64_t *)buf = mze->mze_phys.mze_value;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
	zap_unlockdir(zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
zap_length(objset_t *os, uint64_t zapobj, const char *name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
    uint64_t *integer_size, uint64_t *num_integers)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
	zap_t *zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, &zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
	if (err)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
	if (!zap->zap_ismicro) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
		err = fzap_length(zap, name, integer_size, num_integers);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
		mze = mze_find(zap, name, zap_hash(zap, name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
		if (mze == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
			err = ENOENT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
			if (integer_size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
				*integer_size = 8;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
			if (num_integers)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
				*num_integers = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
	zap_unlockdir(zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
mzap_addent(zap_t *zap, const char *name, uint64_t hash, uint64_t value)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
	int start = zap->zap_m.zap_alloc_next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
	uint32_t cd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
	dprintf("obj=%llu %s=%llu\n", zap->zap_object, name, value);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
#ifdef ZFS_DEBUG
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
	for (i = 0; i < zap->zap_m.zap_num_chunks; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
		mzap_ent_phys_t *mze = &zap->zap_m.zap_phys->mz_chunk[i];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
		ASSERT(strcmp(name, mze->mze_name) != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
#endif
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
	cd = mze_find_unused_cd(zap, hash);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
	/* given the limited size of the microzap, this can't happen */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
	ASSERT(cd != ZAP_MAXCD);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
again:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
	for (i = start; i < zap->zap_m.zap_num_chunks; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
		mzap_ent_phys_t *mze = &zap->zap_m.zap_phys->mz_chunk[i];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
		if (mze->mze_name[0] == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
			mze->mze_value = value;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
			mze->mze_cd = cd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
			(void) strcpy(mze->mze_name, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
			zap->zap_m.zap_num_entries++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
			zap->zap_m.zap_alloc_next = i+1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
			if (zap->zap_m.zap_alloc_next ==
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
			    zap->zap_m.zap_num_chunks)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
				zap->zap_m.zap_alloc_next = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
			mze_insert(zap, i, hash, mze);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
			return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
	if (start != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
		start = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
		goto again;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
	ASSERT(!"out of entries!");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
zap_add(objset_t *os, uint64_t zapobj, const char *name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
    int integer_size, uint64_t num_integers,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
    const void *val, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
	zap_t *zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
	const uint64_t *intval = val;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
	uint64_t hash;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, &zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
	if (err)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
	if (!zap->zap_ismicro) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
		err = fzap_add(zap, name, integer_size, num_integers, val, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
	} else if (integer_size != 8 || num_integers != 1 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
	    strlen(name) >= MZAP_NAME_LEN) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
		dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
		    zapobj, integer_size, num_integers, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
		mzap_upgrade(zap, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
		err = fzap_add(zap, name, integer_size, num_integers, val, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
		hash = zap_hash(zap, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
		mze = mze_find(zap, name, hash);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
		if (mze != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
			err = EEXIST;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
			mzap_addent(zap, name, hash, *intval);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
	zap_unlockdir(zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
zap_update(objset_t *os, uint64_t zapobj, const char *name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
    int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
	zap_t *zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
	const uint64_t *intval = val;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
	uint64_t hash;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, &zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
	if (err)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
	if (!zap->zap_ismicro) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
		err = fzap_update(zap, name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
		    integer_size, num_integers, val, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
	} else if (integer_size != 8 || num_integers != 1 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
	    strlen(name) >= MZAP_NAME_LEN) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
		dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
		    zapobj, integer_size, num_integers, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
		mzap_upgrade(zap, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
		err = fzap_update(zap, name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
		    integer_size, num_integers, val, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
		hash = zap_hash(zap, name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
		mze = mze_find(zap, name, hash);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
		if (mze != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
			mze->mze_phys.mze_value = *intval;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
			zap->zap_m.zap_phys->mz_chunk
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
			    [mze->mze_chunkid].mze_value = *intval;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
			mzap_addent(zap, name, hash, *intval);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   671
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   672
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   673
	zap_unlockdir(zap);
2641
967ea438b194 6462174 zap_update() likes to return 0
ahrens
parents: 1544
diff changeset
   674
	return (err);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   678
zap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
	zap_t *zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, &zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
	if (err)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   686
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
	if (!zap->zap_ismicro) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
		err = fzap_remove(zap, name, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   690
		mze = mze_find(zap, name, zap_hash(zap, name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
		if (mze == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
			dprintf("fail: %s\n", name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
			err = ENOENT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   695
			dprintf("success: %s\n", name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
			zap->zap_m.zap_num_entries--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
			bzero(&zap->zap_m.zap_phys->mz_chunk[mze->mze_chunkid],
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   698
			    sizeof (mzap_ent_phys_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   699
			mze_remove(zap, mze);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   700
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   701
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
	zap_unlockdir(zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
 * Routines for iterating over the attributes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   709
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   710
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   711
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   712
 * We want to keep the high 32 bits of the cursor zero if we can, so
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   713
 * that 32-bit programs can access this.  So use a small hash value so
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   714
 * we can fit 4 bits of cd into the 32-bit cursor.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   715
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   716
 * [ 4 zero bits | 32-bit collision differentiator | 28-bit hash value ]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   718
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   719
zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, uint64_t zapobj,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
    uint64_t serialized)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   721
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   722
	zc->zc_objset = os;
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   723
	zc->zc_zap = NULL;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   724
	zc->zc_leaf = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   725
	zc->zc_zapobj = zapobj;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
	if (serialized == -1ULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
		zc->zc_hash = -1ULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
		zc->zc_cd = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
		zc->zc_hash = serialized << (64-ZAP_HASHBITS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
		zc->zc_cd = serialized >> ZAP_HASHBITS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
		if (zc->zc_cd >= ZAP_MAXCD) /* corrupt serialized */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
			zc->zc_cd = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   736
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   737
void
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   738
zap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj)
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   739
{
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   740
	zap_cursor_init_serialized(zc, os, zapobj, 0);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   741
}
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   742
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   743
void
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   744
zap_cursor_fini(zap_cursor_t *zc)
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   745
{
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   746
	if (zc->zc_zap) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   747
		rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   748
		zap_unlockdir(zc->zc_zap);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   749
		zc->zc_zap = NULL;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   750
	}
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   751
	if (zc->zc_leaf) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   752
		rw_enter(&zc->zc_leaf->l_rwlock, RW_READER);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   753
		zap_put_leaf(zc->zc_leaf);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   754
		zc->zc_leaf = NULL;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   755
	}
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   756
	zc->zc_objset = NULL;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   757
}
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   758
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   759
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
zap_cursor_serialize(zap_cursor_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
	if (zc->zc_hash == -1ULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
		return (-1ULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
	ASSERT((zc->zc_hash & (ZAP_MAXCD-1)) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
	ASSERT(zc->zc_cd < ZAP_MAXCD);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
	return ((zc->zc_hash >> (64-ZAP_HASHBITS)) |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   767
	    ((uint64_t)zc->zc_cd << ZAP_HASHBITS));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   770
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   772
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
	avl_index_t idx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   775
	mzap_ent_t mze_tofind;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   776
	mzap_ent_t *mze;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   777
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   778
	if (zc->zc_hash == -1ULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   779
		return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   780
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   781
	if (zc->zc_zap == NULL) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   782
		err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   783
		    RW_READER, TRUE, &zc->zc_zap);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   784
		if (err)
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   785
			return (err);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   786
	} else {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   787
		rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   788
	}
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   789
	if (!zc->zc_zap->zap_ismicro) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   790
		err = fzap_cursor_retrieve(zc->zc_zap, zc, za);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
		err = ENOENT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
		mze_tofind.mze_hash = zc->zc_hash;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
		mze_tofind.mze_phys.mze_cd = zc->zc_cd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   796
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   797
		mze = avl_find(&zc->zc_zap->zap_m.zap_avl, &mze_tofind, &idx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
		ASSERT(mze == NULL || 0 == bcmp(&mze->mze_phys,
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   799
		    &zc->zc_zap->zap_m.zap_phys->mz_chunk[mze->mze_chunkid],
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
		    sizeof (mze->mze_phys)));
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   801
		if (mze == NULL) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   802
			mze = avl_nearest(&zc->zc_zap->zap_m.zap_avl,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   803
			    idx, AVL_AFTER);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   804
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
		if (mze) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   806
			za->za_integer_length = 8;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
			za->za_num_integers = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
			za->za_first_integer = mze->mze_phys.mze_value;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
			(void) strcpy(za->za_name, mze->mze_phys.mze_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
			zc->zc_hash = mze->mze_hash;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
			zc->zc_cd = mze->mze_phys.mze_cd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
			err = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
			zc->zc_hash = -1ULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
	}
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   817
	rw_exit(&zc->zc_zap->zap_rwlock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   821
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
zap_cursor_advance(zap_cursor_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
	if (zc->zc_hash == -1ULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
	zc->zc_cd++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
	if (zc->zc_cd >= ZAP_MAXCD) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
		zc->zc_cd = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
		zc->zc_hash += 1ULL<<(64-ZAP_HASHBITS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
		if (zc->zc_hash == 0) /* EOF */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   831
			zc->zc_hash = -1ULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
	zap_t *zap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, &zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
	if (err)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
	bzero(zs, sizeof (zap_stats_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
	if (zap->zap_ismicro) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
		zs->zs_blocksize = zap->zap_dbuf->db_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
		zs->zs_num_entries = zap->zap_m.zap_num_entries;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
		zs->zs_num_blocks = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
		fzap_get_stats(zap, zs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
	zap_unlockdir(zap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
}