xref: /freebsd-src/sys/contrib/openzfs/module/zfs/zap_leaf.c (revision 718519f4efc71096422fc71dab90b2a3369871ff)
1eda14cbcSMatt Macy /*
2eda14cbcSMatt Macy  * CDDL HEADER START
3eda14cbcSMatt Macy  *
4eda14cbcSMatt Macy  * The contents of this file are subject to the terms of the
5eda14cbcSMatt Macy  * Common Development and Distribution License (the "License").
6eda14cbcSMatt Macy  * You may not use this file except in compliance with the License.
7eda14cbcSMatt Macy  *
8eda14cbcSMatt Macy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9271171e0SMartin Matuska  * or https://opensource.org/licenses/CDDL-1.0.
10eda14cbcSMatt Macy  * See the License for the specific language governing permissions
11eda14cbcSMatt Macy  * and limitations under the License.
12eda14cbcSMatt Macy  *
13eda14cbcSMatt Macy  * When distributing Covered Code, include this CDDL HEADER in each
14eda14cbcSMatt Macy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15eda14cbcSMatt Macy  * If applicable, add the following below this CDDL HEADER, with the
16eda14cbcSMatt Macy  * fields enclosed by brackets "[]" replaced with your own identifying
17eda14cbcSMatt Macy  * information: Portions Copyright [yyyy] [name of copyright owner]
18eda14cbcSMatt Macy  *
19eda14cbcSMatt Macy  * CDDL HEADER END
20eda14cbcSMatt Macy  */
21eda14cbcSMatt Macy 
22eda14cbcSMatt Macy /*
23eda14cbcSMatt Macy  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24eda14cbcSMatt Macy  * Copyright (c) 2013, 2016 by Delphix. All rights reserved.
25eda14cbcSMatt Macy  * Copyright 2017 Nexenta Systems, Inc.
26eda14cbcSMatt Macy  */
27eda14cbcSMatt Macy 
28eda14cbcSMatt Macy /*
29eda14cbcSMatt Macy  * The 512-byte leaf is broken into 32 16-byte chunks.
30eda14cbcSMatt Macy  * chunk number n means l_chunk[n], even though the header precedes it.
31eda14cbcSMatt Macy  * the names are stored null-terminated.
32eda14cbcSMatt Macy  */
33eda14cbcSMatt Macy 
34eda14cbcSMatt Macy #include <sys/zio.h>
35eda14cbcSMatt Macy #include <sys/spa.h>
36eda14cbcSMatt Macy #include <sys/dmu.h>
37eda14cbcSMatt Macy #include <sys/zfs_context.h>
38eda14cbcSMatt Macy #include <sys/fs/zfs.h>
39eda14cbcSMatt Macy #include <sys/zap.h>
40eda14cbcSMatt Macy #include <sys/zap_impl.h>
41eda14cbcSMatt Macy #include <sys/zap_leaf.h>
42eda14cbcSMatt Macy #include <sys/arc.h>
43eda14cbcSMatt Macy 
44783d3ff6SMartin Matuska static uint16_t *zap_leaf_rehash_entry(zap_leaf_t *l, struct zap_leaf_entry *le,
45783d3ff6SMartin Matuska     uint16_t entry);
46eda14cbcSMatt Macy 
47eda14cbcSMatt Macy #define	CHAIN_END 0xffff /* end of the chunk chain */
48eda14cbcSMatt Macy 
49eda14cbcSMatt Macy #define	LEAF_HASH(l, h) \
50eda14cbcSMatt Macy 	((ZAP_LEAF_HASH_NUMENTRIES(l)-1) & \
51eda14cbcSMatt Macy 	((h) >> \
52eda14cbcSMatt Macy 	(64 - ZAP_LEAF_HASH_SHIFT(l) - zap_leaf_phys(l)->l_hdr.lh_prefix_len)))
53eda14cbcSMatt Macy 
54eda14cbcSMatt Macy #define	LEAF_HASH_ENTPTR(l, h)	(&zap_leaf_phys(l)->l_hash[LEAF_HASH(l, h)])
55eda14cbcSMatt Macy 
56eda14cbcSMatt Macy static void
57eda14cbcSMatt Macy stv(int len, void *addr, uint64_t value)
58eda14cbcSMatt Macy {
59eda14cbcSMatt Macy 	switch (len) {
60eda14cbcSMatt Macy 	case 1:
61eda14cbcSMatt Macy 		*(uint8_t *)addr = value;
62eda14cbcSMatt Macy 		return;
63eda14cbcSMatt Macy 	case 2:
64eda14cbcSMatt Macy 		*(uint16_t *)addr = value;
65eda14cbcSMatt Macy 		return;
66eda14cbcSMatt Macy 	case 4:
67eda14cbcSMatt Macy 		*(uint32_t *)addr = value;
68eda14cbcSMatt Macy 		return;
69eda14cbcSMatt Macy 	case 8:
70eda14cbcSMatt Macy 		*(uint64_t *)addr = value;
71eda14cbcSMatt Macy 		return;
72eda14cbcSMatt Macy 	default:
73783d3ff6SMartin Matuska 		PANIC("bad int len %d", len);
74eda14cbcSMatt Macy 	}
75eda14cbcSMatt Macy }
76eda14cbcSMatt Macy 
77eda14cbcSMatt Macy static uint64_t
78eda14cbcSMatt Macy ldv(int len, const void *addr)
79eda14cbcSMatt Macy {
80eda14cbcSMatt Macy 	switch (len) {
81eda14cbcSMatt Macy 	case 1:
82eda14cbcSMatt Macy 		return (*(uint8_t *)addr);
83eda14cbcSMatt Macy 	case 2:
84eda14cbcSMatt Macy 		return (*(uint16_t *)addr);
85eda14cbcSMatt Macy 	case 4:
86eda14cbcSMatt Macy 		return (*(uint32_t *)addr);
87eda14cbcSMatt Macy 	case 8:
88eda14cbcSMatt Macy 		return (*(uint64_t *)addr);
89eda14cbcSMatt Macy 	default:
90783d3ff6SMartin Matuska 		PANIC("bad int len %d", len);
91eda14cbcSMatt Macy 	}
92eda14cbcSMatt Macy 	return (0xFEEDFACEDEADBEEFULL);
93eda14cbcSMatt Macy }
94eda14cbcSMatt Macy 
95eda14cbcSMatt Macy void
96783d3ff6SMartin Matuska zap_leaf_byteswap(zap_leaf_phys_t *buf, size_t size)
97eda14cbcSMatt Macy {
98eda14cbcSMatt Macy 	zap_leaf_t l;
99eda14cbcSMatt Macy 	dmu_buf_t l_dbuf;
100eda14cbcSMatt Macy 
101eda14cbcSMatt Macy 	l_dbuf.db_data = buf;
102eda14cbcSMatt Macy 	l.l_bs = highbit64(size) - 1;
103eda14cbcSMatt Macy 	l.l_dbuf = &l_dbuf;
104eda14cbcSMatt Macy 
105eda14cbcSMatt Macy 	buf->l_hdr.lh_block_type =	BSWAP_64(buf->l_hdr.lh_block_type);
106eda14cbcSMatt Macy 	buf->l_hdr.lh_prefix =		BSWAP_64(buf->l_hdr.lh_prefix);
107eda14cbcSMatt Macy 	buf->l_hdr.lh_magic =		BSWAP_32(buf->l_hdr.lh_magic);
108eda14cbcSMatt Macy 	buf->l_hdr.lh_nfree =		BSWAP_16(buf->l_hdr.lh_nfree);
109eda14cbcSMatt Macy 	buf->l_hdr.lh_nentries =	BSWAP_16(buf->l_hdr.lh_nentries);
110eda14cbcSMatt Macy 	buf->l_hdr.lh_prefix_len =	BSWAP_16(buf->l_hdr.lh_prefix_len);
111eda14cbcSMatt Macy 	buf->l_hdr.lh_freelist =	BSWAP_16(buf->l_hdr.lh_freelist);
112eda14cbcSMatt Macy 
113783d3ff6SMartin Matuska 	for (uint_t i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(&l); i++)
114eda14cbcSMatt Macy 		buf->l_hash[i] = BSWAP_16(buf->l_hash[i]);
115eda14cbcSMatt Macy 
116783d3ff6SMartin Matuska 	for (uint_t i = 0; i < ZAP_LEAF_NUMCHUNKS(&l); i++) {
117eda14cbcSMatt Macy 		zap_leaf_chunk_t *lc = &ZAP_LEAF_CHUNK(&l, i);
118eda14cbcSMatt Macy 		struct zap_leaf_entry *le;
119eda14cbcSMatt Macy 
120eda14cbcSMatt Macy 		switch (lc->l_free.lf_type) {
121eda14cbcSMatt Macy 		case ZAP_CHUNK_ENTRY:
122eda14cbcSMatt Macy 			le = &lc->l_entry;
123eda14cbcSMatt Macy 
124eda14cbcSMatt Macy 			le->le_type =		BSWAP_8(le->le_type);
125eda14cbcSMatt Macy 			le->le_value_intlen =	BSWAP_8(le->le_value_intlen);
126eda14cbcSMatt Macy 			le->le_next =		BSWAP_16(le->le_next);
127eda14cbcSMatt Macy 			le->le_name_chunk =	BSWAP_16(le->le_name_chunk);
128eda14cbcSMatt Macy 			le->le_name_numints =	BSWAP_16(le->le_name_numints);
129eda14cbcSMatt Macy 			le->le_value_chunk =	BSWAP_16(le->le_value_chunk);
130eda14cbcSMatt Macy 			le->le_value_numints =	BSWAP_16(le->le_value_numints);
131eda14cbcSMatt Macy 			le->le_cd =		BSWAP_32(le->le_cd);
132eda14cbcSMatt Macy 			le->le_hash =		BSWAP_64(le->le_hash);
133eda14cbcSMatt Macy 			break;
134eda14cbcSMatt Macy 		case ZAP_CHUNK_FREE:
135eda14cbcSMatt Macy 			lc->l_free.lf_type =	BSWAP_8(lc->l_free.lf_type);
136eda14cbcSMatt Macy 			lc->l_free.lf_next =	BSWAP_16(lc->l_free.lf_next);
137eda14cbcSMatt Macy 			break;
138eda14cbcSMatt Macy 		case ZAP_CHUNK_ARRAY:
139eda14cbcSMatt Macy 			lc->l_array.la_type =	BSWAP_8(lc->l_array.la_type);
140eda14cbcSMatt Macy 			lc->l_array.la_next =	BSWAP_16(lc->l_array.la_next);
141eda14cbcSMatt Macy 			/* la_array doesn't need swapping */
142eda14cbcSMatt Macy 			break;
143eda14cbcSMatt Macy 		default:
144eda14cbcSMatt Macy 			cmn_err(CE_PANIC, "bad leaf type %d",
145eda14cbcSMatt Macy 			    lc->l_free.lf_type);
146eda14cbcSMatt Macy 		}
147eda14cbcSMatt Macy 	}
148eda14cbcSMatt Macy }
149eda14cbcSMatt Macy 
150eda14cbcSMatt Macy void
151eda14cbcSMatt Macy zap_leaf_init(zap_leaf_t *l, boolean_t sort)
152eda14cbcSMatt Macy {
153eda14cbcSMatt Macy 	l->l_bs = highbit64(l->l_dbuf->db_size) - 1;
154783d3ff6SMartin Matuska 	memset(&zap_leaf_phys(l)->l_hdr, 0,
155eda14cbcSMatt Macy 	    sizeof (struct zap_leaf_header));
156783d3ff6SMartin Matuska 	memset(zap_leaf_phys(l)->l_hash, CHAIN_END,
157eda14cbcSMatt Macy 	    2*ZAP_LEAF_HASH_NUMENTRIES(l));
158783d3ff6SMartin Matuska 	for (uint_t i = 0; i < ZAP_LEAF_NUMCHUNKS(l); i++) {
159eda14cbcSMatt Macy 		ZAP_LEAF_CHUNK(l, i).l_free.lf_type = ZAP_CHUNK_FREE;
160eda14cbcSMatt Macy 		ZAP_LEAF_CHUNK(l, i).l_free.lf_next = i+1;
161eda14cbcSMatt Macy 	}
162eda14cbcSMatt Macy 	ZAP_LEAF_CHUNK(l, ZAP_LEAF_NUMCHUNKS(l)-1).l_free.lf_next = CHAIN_END;
163eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_block_type = ZBT_LEAF;
164eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_magic = ZAP_LEAF_MAGIC;
165eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_nfree = ZAP_LEAF_NUMCHUNKS(l);
166eda14cbcSMatt Macy 	if (sort)
167eda14cbcSMatt Macy 		zap_leaf_phys(l)->l_hdr.lh_flags |= ZLF_ENTRIES_CDSORTED;
168eda14cbcSMatt Macy }
169eda14cbcSMatt Macy 
170eda14cbcSMatt Macy /*
171eda14cbcSMatt Macy  * Routines which manipulate leaf chunks (l_chunk[]).
172eda14cbcSMatt Macy  */
173eda14cbcSMatt Macy 
174eda14cbcSMatt Macy static uint16_t
175eda14cbcSMatt Macy zap_leaf_chunk_alloc(zap_leaf_t *l)
176eda14cbcSMatt Macy {
177eda14cbcSMatt Macy 	ASSERT(zap_leaf_phys(l)->l_hdr.lh_nfree > 0);
178eda14cbcSMatt Macy 
179783d3ff6SMartin Matuska 	uint_t chunk = zap_leaf_phys(l)->l_hdr.lh_freelist;
180eda14cbcSMatt Macy 	ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
181eda14cbcSMatt Macy 	ASSERT3U(ZAP_LEAF_CHUNK(l, chunk).l_free.lf_type, ==, ZAP_CHUNK_FREE);
182eda14cbcSMatt Macy 
183eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_freelist =
184eda14cbcSMatt Macy 	    ZAP_LEAF_CHUNK(l, chunk).l_free.lf_next;
185eda14cbcSMatt Macy 
186eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_nfree--;
187eda14cbcSMatt Macy 
188eda14cbcSMatt Macy 	return (chunk);
189eda14cbcSMatt Macy }
190eda14cbcSMatt Macy 
191eda14cbcSMatt Macy static void
192eda14cbcSMatt Macy zap_leaf_chunk_free(zap_leaf_t *l, uint16_t chunk)
193eda14cbcSMatt Macy {
194eda14cbcSMatt Macy 	struct zap_leaf_free *zlf = &ZAP_LEAF_CHUNK(l, chunk).l_free;
195eda14cbcSMatt Macy 	ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_nfree, <, ZAP_LEAF_NUMCHUNKS(l));
196eda14cbcSMatt Macy 	ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
197eda14cbcSMatt Macy 	ASSERT(zlf->lf_type != ZAP_CHUNK_FREE);
198eda14cbcSMatt Macy 
199eda14cbcSMatt Macy 	zlf->lf_type = ZAP_CHUNK_FREE;
200eda14cbcSMatt Macy 	zlf->lf_next = zap_leaf_phys(l)->l_hdr.lh_freelist;
201da5137abSMartin Matuska 	memset(zlf->lf_pad, 0, sizeof (zlf->lf_pad)); /* help it to compress */
202eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_freelist = chunk;
203eda14cbcSMatt Macy 
204eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_nfree++;
205eda14cbcSMatt Macy }
206eda14cbcSMatt Macy 
207eda14cbcSMatt Macy /*
208eda14cbcSMatt Macy  * Routines which manipulate leaf arrays (zap_leaf_array type chunks).
209eda14cbcSMatt Macy  */
210eda14cbcSMatt Macy 
211eda14cbcSMatt Macy static uint16_t
212eda14cbcSMatt Macy zap_leaf_array_create(zap_leaf_t *l, const char *buf,
213eda14cbcSMatt Macy     int integer_size, int num_integers)
214eda14cbcSMatt Macy {
215eda14cbcSMatt Macy 	uint16_t chunk_head;
216eda14cbcSMatt Macy 	uint16_t *chunkp = &chunk_head;
217783d3ff6SMartin Matuska 	int byten = integer_size;
218eda14cbcSMatt Macy 	uint64_t value = 0;
219eda14cbcSMatt Macy 	int shift = (integer_size - 1) * 8;
220eda14cbcSMatt Macy 	int len = num_integers;
221eda14cbcSMatt Macy 
222eda14cbcSMatt Macy 	ASSERT3U(num_integers * integer_size, <=, ZAP_MAXVALUELEN);
223eda14cbcSMatt Macy 
224783d3ff6SMartin Matuska 	if (len > 0)
225783d3ff6SMartin Matuska 		value = ldv(integer_size, buf);
226eda14cbcSMatt Macy 	while (len > 0) {
227eda14cbcSMatt Macy 		uint16_t chunk = zap_leaf_chunk_alloc(l);
228eda14cbcSMatt Macy 		struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
229eda14cbcSMatt Macy 
230eda14cbcSMatt Macy 		la->la_type = ZAP_CHUNK_ARRAY;
231eda14cbcSMatt Macy 		for (int i = 0; i < ZAP_LEAF_ARRAY_BYTES; i++) {
232eda14cbcSMatt Macy 			la->la_array[i] = value >> shift;
233eda14cbcSMatt Macy 			value <<= 8;
234783d3ff6SMartin Matuska 			if (--byten == 0) {
235eda14cbcSMatt Macy 				if (--len == 0)
236eda14cbcSMatt Macy 					break;
237783d3ff6SMartin Matuska 				byten = integer_size;
238783d3ff6SMartin Matuska 				buf += integer_size;
239783d3ff6SMartin Matuska 				value = ldv(integer_size, buf);
240eda14cbcSMatt Macy 			}
241eda14cbcSMatt Macy 		}
242eda14cbcSMatt Macy 
243eda14cbcSMatt Macy 		*chunkp = chunk;
244eda14cbcSMatt Macy 		chunkp = &la->la_next;
245eda14cbcSMatt Macy 	}
246eda14cbcSMatt Macy 	*chunkp = CHAIN_END;
247eda14cbcSMatt Macy 
248eda14cbcSMatt Macy 	return (chunk_head);
249eda14cbcSMatt Macy }
250eda14cbcSMatt Macy 
251*718519f4SMartin Matuska /*
252*718519f4SMartin Matuska  * Non-destructively copy array between leaves.
253*718519f4SMartin Matuska  */
254*718519f4SMartin Matuska static uint16_t
255*718519f4SMartin Matuska zap_leaf_array_copy(zap_leaf_t *l, uint16_t chunk, zap_leaf_t *nl)
256eda14cbcSMatt Macy {
257*718519f4SMartin Matuska 	uint16_t new_chunk;
258*718519f4SMartin Matuska 	uint16_t *nchunkp = &new_chunk;
259eda14cbcSMatt Macy 
260eda14cbcSMatt Macy 	while (chunk != CHAIN_END) {
261*718519f4SMartin Matuska 		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
262*718519f4SMartin Matuska 		uint16_t nchunk = zap_leaf_chunk_alloc(nl);
263*718519f4SMartin Matuska 
264*718519f4SMartin Matuska 		struct zap_leaf_array *la =
265*718519f4SMartin Matuska 		    &ZAP_LEAF_CHUNK(l, chunk).l_array;
266*718519f4SMartin Matuska 		struct zap_leaf_array *nla =
267*718519f4SMartin Matuska 		    &ZAP_LEAF_CHUNK(nl, nchunk).l_array;
268*718519f4SMartin Matuska 		ASSERT3U(la->la_type, ==, ZAP_CHUNK_ARRAY);
269*718519f4SMartin Matuska 
270*718519f4SMartin Matuska 		*nla = *la; /* structure assignment */
271*718519f4SMartin Matuska 
272*718519f4SMartin Matuska 		chunk = la->la_next;
273*718519f4SMartin Matuska 		*nchunkp = nchunk;
274*718519f4SMartin Matuska 		nchunkp = &nla->la_next;
275eda14cbcSMatt Macy 	}
276*718519f4SMartin Matuska 	*nchunkp = CHAIN_END;
277*718519f4SMartin Matuska 	return (new_chunk);
278*718519f4SMartin Matuska }
279*718519f4SMartin Matuska 
280*718519f4SMartin Matuska /*
281*718519f4SMartin Matuska  * Free array.  Unlike trivial loop of zap_leaf_chunk_free() this does
282*718519f4SMartin Matuska  * not reverse order of chunks in the free list, reducing fragmentation.
283*718519f4SMartin Matuska  */
284*718519f4SMartin Matuska static void
285*718519f4SMartin Matuska zap_leaf_array_free(zap_leaf_t *l, uint16_t chunk)
286*718519f4SMartin Matuska {
287*718519f4SMartin Matuska 	struct zap_leaf_header *hdr = &zap_leaf_phys(l)->l_hdr;
288*718519f4SMartin Matuska 	uint16_t *tailp = &hdr->lh_freelist;
289*718519f4SMartin Matuska 	uint16_t oldfree = *tailp;
290*718519f4SMartin Matuska 
291*718519f4SMartin Matuska 	while (chunk != CHAIN_END) {
292*718519f4SMartin Matuska 		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
293*718519f4SMartin Matuska 		zap_leaf_chunk_t *c = &ZAP_LEAF_CHUNK(l, chunk);
294*718519f4SMartin Matuska 		ASSERT3U(c->l_array.la_type, ==, ZAP_CHUNK_ARRAY);
295*718519f4SMartin Matuska 
296*718519f4SMartin Matuska 		*tailp = chunk;
297*718519f4SMartin Matuska 		chunk = c->l_array.la_next;
298*718519f4SMartin Matuska 
299*718519f4SMartin Matuska 		c->l_free.lf_type = ZAP_CHUNK_FREE;
300*718519f4SMartin Matuska 		memset(c->l_free.lf_pad, 0, sizeof (c->l_free.lf_pad));
301*718519f4SMartin Matuska 		tailp = &c->l_free.lf_next;
302*718519f4SMartin Matuska 
303*718519f4SMartin Matuska 		ASSERT3U(hdr->lh_nfree, <, ZAP_LEAF_NUMCHUNKS(l));
304*718519f4SMartin Matuska 		hdr->lh_nfree++;
305*718519f4SMartin Matuska 	}
306*718519f4SMartin Matuska 
307*718519f4SMartin Matuska 	*tailp = oldfree;
308eda14cbcSMatt Macy }
309eda14cbcSMatt Macy 
310eda14cbcSMatt Macy /* array_len and buf_len are in integers, not bytes */
311eda14cbcSMatt Macy static void
312eda14cbcSMatt Macy zap_leaf_array_read(zap_leaf_t *l, uint16_t chunk,
313eda14cbcSMatt Macy     int array_int_len, int array_len, int buf_int_len, uint64_t buf_len,
314eda14cbcSMatt Macy     void *buf)
315eda14cbcSMatt Macy {
316eda14cbcSMatt Macy 	int len = MIN(array_len, buf_len);
317eda14cbcSMatt Macy 	int byten = 0;
318eda14cbcSMatt Macy 	uint64_t value = 0;
319eda14cbcSMatt Macy 	char *p = buf;
320eda14cbcSMatt Macy 
321eda14cbcSMatt Macy 	ASSERT3U(array_int_len, <=, buf_int_len);
322eda14cbcSMatt Macy 
323eda14cbcSMatt Macy 	/* Fast path for one 8-byte integer */
324eda14cbcSMatt Macy 	if (array_int_len == 8 && buf_int_len == 8 && len == 1) {
325eda14cbcSMatt Macy 		struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
326eda14cbcSMatt Macy 		uint8_t *ip = la->la_array;
327eda14cbcSMatt Macy 		uint64_t *buf64 = buf;
328eda14cbcSMatt Macy 
329eda14cbcSMatt Macy 		*buf64 = (uint64_t)ip[0] << 56 | (uint64_t)ip[1] << 48 |
330eda14cbcSMatt Macy 		    (uint64_t)ip[2] << 40 | (uint64_t)ip[3] << 32 |
331eda14cbcSMatt Macy 		    (uint64_t)ip[4] << 24 | (uint64_t)ip[5] << 16 |
332eda14cbcSMatt Macy 		    (uint64_t)ip[6] << 8 | (uint64_t)ip[7];
333eda14cbcSMatt Macy 		return;
334eda14cbcSMatt Macy 	}
335eda14cbcSMatt Macy 
336eda14cbcSMatt Macy 	/* Fast path for an array of 1-byte integers (eg. the entry name) */
337eda14cbcSMatt Macy 	if (array_int_len == 1 && buf_int_len == 1 &&
338eda14cbcSMatt Macy 	    buf_len > array_len + ZAP_LEAF_ARRAY_BYTES) {
339eda14cbcSMatt Macy 		while (chunk != CHAIN_END) {
340eda14cbcSMatt Macy 			struct zap_leaf_array *la =
341eda14cbcSMatt Macy 			    &ZAP_LEAF_CHUNK(l, chunk).l_array;
342da5137abSMartin Matuska 			memcpy(p, la->la_array, ZAP_LEAF_ARRAY_BYTES);
343eda14cbcSMatt Macy 			p += ZAP_LEAF_ARRAY_BYTES;
344eda14cbcSMatt Macy 			chunk = la->la_next;
345eda14cbcSMatt Macy 		}
346eda14cbcSMatt Macy 		return;
347eda14cbcSMatt Macy 	}
348eda14cbcSMatt Macy 
349eda14cbcSMatt Macy 	while (len > 0) {
350eda14cbcSMatt Macy 		struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
351eda14cbcSMatt Macy 
352eda14cbcSMatt Macy 		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
3532a58b312SMartin Matuska 		for (int i = 0; i < ZAP_LEAF_ARRAY_BYTES; i++) {
354eda14cbcSMatt Macy 			value = (value << 8) | la->la_array[i];
355eda14cbcSMatt Macy 			byten++;
356eda14cbcSMatt Macy 			if (byten == array_int_len) {
357eda14cbcSMatt Macy 				stv(buf_int_len, p, value);
358eda14cbcSMatt Macy 				byten = 0;
359eda14cbcSMatt Macy 				len--;
360eda14cbcSMatt Macy 				if (len == 0)
361eda14cbcSMatt Macy 					return;
362eda14cbcSMatt Macy 				p += buf_int_len;
363eda14cbcSMatt Macy 			}
364eda14cbcSMatt Macy 		}
365eda14cbcSMatt Macy 		chunk = la->la_next;
366eda14cbcSMatt Macy 	}
367eda14cbcSMatt Macy }
368eda14cbcSMatt Macy 
369eda14cbcSMatt Macy static boolean_t
370eda14cbcSMatt Macy zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn,
371783d3ff6SMartin Matuska     uint_t chunk, int array_numints)
372eda14cbcSMatt Macy {
373eda14cbcSMatt Macy 	int bseen = 0;
374eda14cbcSMatt Macy 
375eda14cbcSMatt Macy 	if (zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY) {
376eda14cbcSMatt Macy 		uint64_t *thiskey =
377eda14cbcSMatt Macy 		    kmem_alloc(array_numints * sizeof (*thiskey), KM_SLEEP);
378eda14cbcSMatt Macy 		ASSERT(zn->zn_key_intlen == sizeof (*thiskey));
379eda14cbcSMatt Macy 
380eda14cbcSMatt Macy 		zap_leaf_array_read(l, chunk, sizeof (*thiskey), array_numints,
381eda14cbcSMatt Macy 		    sizeof (*thiskey), array_numints, thiskey);
382da5137abSMartin Matuska 		boolean_t match = memcmp(thiskey, zn->zn_key_orig,
383eda14cbcSMatt Macy 		    array_numints * sizeof (*thiskey)) == 0;
384eda14cbcSMatt Macy 		kmem_free(thiskey, array_numints * sizeof (*thiskey));
385eda14cbcSMatt Macy 		return (match);
386eda14cbcSMatt Macy 	}
387eda14cbcSMatt Macy 
388eda14cbcSMatt Macy 	ASSERT(zn->zn_key_intlen == 1);
389eda14cbcSMatt Macy 	if (zn->zn_matchtype & MT_NORMALIZE) {
390eda14cbcSMatt Macy 		char *thisname = kmem_alloc(array_numints, KM_SLEEP);
391eda14cbcSMatt Macy 
392eda14cbcSMatt Macy 		zap_leaf_array_read(l, chunk, sizeof (char), array_numints,
393eda14cbcSMatt Macy 		    sizeof (char), array_numints, thisname);
394eda14cbcSMatt Macy 		boolean_t match = zap_match(zn, thisname);
395eda14cbcSMatt Macy 		kmem_free(thisname, array_numints);
396eda14cbcSMatt Macy 		return (match);
397eda14cbcSMatt Macy 	}
398eda14cbcSMatt Macy 
399eda14cbcSMatt Macy 	/*
400eda14cbcSMatt Macy 	 * Fast path for exact matching.
401eda14cbcSMatt Macy 	 * First check that the lengths match, so that we don't read
402eda14cbcSMatt Macy 	 * past the end of the zn_key_orig array.
403eda14cbcSMatt Macy 	 */
404eda14cbcSMatt Macy 	if (array_numints != zn->zn_key_orig_numints)
405eda14cbcSMatt Macy 		return (B_FALSE);
406eda14cbcSMatt Macy 	while (bseen < array_numints) {
407eda14cbcSMatt Macy 		struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
408eda14cbcSMatt Macy 		int toread = MIN(array_numints - bseen, ZAP_LEAF_ARRAY_BYTES);
409eda14cbcSMatt Macy 		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
410da5137abSMartin Matuska 		if (memcmp(la->la_array, (char *)zn->zn_key_orig + bseen,
411da5137abSMartin Matuska 		    toread))
412eda14cbcSMatt Macy 			break;
413eda14cbcSMatt Macy 		chunk = la->la_next;
414eda14cbcSMatt Macy 		bseen += toread;
415eda14cbcSMatt Macy 	}
416eda14cbcSMatt Macy 	return (bseen == array_numints);
417eda14cbcSMatt Macy }
418eda14cbcSMatt Macy 
419eda14cbcSMatt Macy /*
420eda14cbcSMatt Macy  * Routines which manipulate leaf entries.
421eda14cbcSMatt Macy  */
422eda14cbcSMatt Macy 
423eda14cbcSMatt Macy int
424eda14cbcSMatt Macy zap_leaf_lookup(zap_leaf_t *l, zap_name_t *zn, zap_entry_handle_t *zeh)
425eda14cbcSMatt Macy {
426eda14cbcSMatt Macy 	struct zap_leaf_entry *le;
427eda14cbcSMatt Macy 
428eda14cbcSMatt Macy 	ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC);
429eda14cbcSMatt Macy 
430eda14cbcSMatt Macy 	for (uint16_t *chunkp = LEAF_HASH_ENTPTR(l, zn->zn_hash);
431eda14cbcSMatt Macy 	    *chunkp != CHAIN_END; chunkp = &le->le_next) {
432eda14cbcSMatt Macy 		uint16_t chunk = *chunkp;
433eda14cbcSMatt Macy 		le = ZAP_LEAF_ENTRY(l, chunk);
434eda14cbcSMatt Macy 
435eda14cbcSMatt Macy 		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
436eda14cbcSMatt Macy 		ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
437eda14cbcSMatt Macy 
438eda14cbcSMatt Macy 		if (le->le_hash != zn->zn_hash)
439eda14cbcSMatt Macy 			continue;
440eda14cbcSMatt Macy 
441eda14cbcSMatt Macy 		/*
442eda14cbcSMatt Macy 		 * NB: the entry chain is always sorted by cd on
443eda14cbcSMatt Macy 		 * normalized zap objects, so this will find the
444eda14cbcSMatt Macy 		 * lowest-cd match for MT_NORMALIZE.
445eda14cbcSMatt Macy 		 */
446eda14cbcSMatt Macy 		ASSERT((zn->zn_matchtype == 0) ||
447eda14cbcSMatt Macy 		    (zap_leaf_phys(l)->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED));
448eda14cbcSMatt Macy 		if (zap_leaf_array_match(l, zn, le->le_name_chunk,
449eda14cbcSMatt Macy 		    le->le_name_numints)) {
450eda14cbcSMatt Macy 			zeh->zeh_num_integers = le->le_value_numints;
451eda14cbcSMatt Macy 			zeh->zeh_integer_size = le->le_value_intlen;
452eda14cbcSMatt Macy 			zeh->zeh_cd = le->le_cd;
453eda14cbcSMatt Macy 			zeh->zeh_hash = le->le_hash;
454eda14cbcSMatt Macy 			zeh->zeh_chunkp = chunkp;
455eda14cbcSMatt Macy 			zeh->zeh_leaf = l;
456eda14cbcSMatt Macy 			return (0);
457eda14cbcSMatt Macy 		}
458eda14cbcSMatt Macy 	}
459eda14cbcSMatt Macy 
460eda14cbcSMatt Macy 	return (SET_ERROR(ENOENT));
461eda14cbcSMatt Macy }
462eda14cbcSMatt Macy 
463eda14cbcSMatt Macy /* Return (h1,cd1 >= h2,cd2) */
464eda14cbcSMatt Macy #define	HCD_GTEQ(h1, cd1, h2, cd2) \
465eda14cbcSMatt Macy 	((h1 > h2) ? TRUE : ((h1 == h2 && cd1 >= cd2) ? TRUE : FALSE))
466eda14cbcSMatt Macy 
467eda14cbcSMatt Macy int
468eda14cbcSMatt Macy zap_leaf_lookup_closest(zap_leaf_t *l,
469eda14cbcSMatt Macy     uint64_t h, uint32_t cd, zap_entry_handle_t *zeh)
470eda14cbcSMatt Macy {
471eda14cbcSMatt Macy 	uint64_t besth = -1ULL;
472eda14cbcSMatt Macy 	uint32_t bestcd = -1U;
473eda14cbcSMatt Macy 	uint16_t bestlh = ZAP_LEAF_HASH_NUMENTRIES(l)-1;
474eda14cbcSMatt Macy 	struct zap_leaf_entry *le;
475eda14cbcSMatt Macy 
476eda14cbcSMatt Macy 	ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC);
477eda14cbcSMatt Macy 
478eda14cbcSMatt Macy 	for (uint16_t lh = LEAF_HASH(l, h); lh <= bestlh; lh++) {
479eda14cbcSMatt Macy 		for (uint16_t chunk = zap_leaf_phys(l)->l_hash[lh];
480eda14cbcSMatt Macy 		    chunk != CHAIN_END; chunk = le->le_next) {
481eda14cbcSMatt Macy 			le = ZAP_LEAF_ENTRY(l, chunk);
482eda14cbcSMatt Macy 
483eda14cbcSMatt Macy 			ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
484eda14cbcSMatt Macy 			ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
485eda14cbcSMatt Macy 
486eda14cbcSMatt Macy 			if (HCD_GTEQ(le->le_hash, le->le_cd, h, cd) &&
487eda14cbcSMatt Macy 			    HCD_GTEQ(besth, bestcd, le->le_hash, le->le_cd)) {
488eda14cbcSMatt Macy 				ASSERT3U(bestlh, >=, lh);
489eda14cbcSMatt Macy 				bestlh = lh;
490eda14cbcSMatt Macy 				besth = le->le_hash;
491eda14cbcSMatt Macy 				bestcd = le->le_cd;
492eda14cbcSMatt Macy 
493eda14cbcSMatt Macy 				zeh->zeh_num_integers = le->le_value_numints;
494eda14cbcSMatt Macy 				zeh->zeh_integer_size = le->le_value_intlen;
495eda14cbcSMatt Macy 				zeh->zeh_cd = le->le_cd;
496eda14cbcSMatt Macy 				zeh->zeh_hash = le->le_hash;
497eda14cbcSMatt Macy 				zeh->zeh_fakechunk = chunk;
498eda14cbcSMatt Macy 				zeh->zeh_chunkp = &zeh->zeh_fakechunk;
499eda14cbcSMatt Macy 				zeh->zeh_leaf = l;
500eda14cbcSMatt Macy 			}
501eda14cbcSMatt Macy 		}
502eda14cbcSMatt Macy 	}
503eda14cbcSMatt Macy 
504eda14cbcSMatt Macy 	return (bestcd == -1U ? SET_ERROR(ENOENT) : 0);
505eda14cbcSMatt Macy }
506eda14cbcSMatt Macy 
507eda14cbcSMatt Macy int
508eda14cbcSMatt Macy zap_entry_read(const zap_entry_handle_t *zeh,
509eda14cbcSMatt Macy     uint8_t integer_size, uint64_t num_integers, void *buf)
510eda14cbcSMatt Macy {
511eda14cbcSMatt Macy 	struct zap_leaf_entry *le =
512eda14cbcSMatt Macy 	    ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp);
513eda14cbcSMatt Macy 	ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
514eda14cbcSMatt Macy 
515eda14cbcSMatt Macy 	if (le->le_value_intlen > integer_size)
516eda14cbcSMatt Macy 		return (SET_ERROR(EINVAL));
517eda14cbcSMatt Macy 
518eda14cbcSMatt Macy 	zap_leaf_array_read(zeh->zeh_leaf, le->le_value_chunk,
519eda14cbcSMatt Macy 	    le->le_value_intlen, le->le_value_numints,
520eda14cbcSMatt Macy 	    integer_size, num_integers, buf);
521eda14cbcSMatt Macy 
522eda14cbcSMatt Macy 	if (zeh->zeh_num_integers > num_integers)
523eda14cbcSMatt Macy 		return (SET_ERROR(EOVERFLOW));
524eda14cbcSMatt Macy 	return (0);
525eda14cbcSMatt Macy 
526eda14cbcSMatt Macy }
527eda14cbcSMatt Macy 
528eda14cbcSMatt Macy int
529eda14cbcSMatt Macy zap_entry_read_name(zap_t *zap, const zap_entry_handle_t *zeh, uint16_t buflen,
530eda14cbcSMatt Macy     char *buf)
531eda14cbcSMatt Macy {
532eda14cbcSMatt Macy 	struct zap_leaf_entry *le =
533eda14cbcSMatt Macy 	    ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp);
534eda14cbcSMatt Macy 	ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
535eda14cbcSMatt Macy 
536eda14cbcSMatt Macy 	if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) {
537eda14cbcSMatt Macy 		zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 8,
538eda14cbcSMatt Macy 		    le->le_name_numints, 8, buflen / 8, buf);
539eda14cbcSMatt Macy 	} else {
540eda14cbcSMatt Macy 		zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 1,
541eda14cbcSMatt Macy 		    le->le_name_numints, 1, buflen, buf);
542eda14cbcSMatt Macy 	}
543eda14cbcSMatt Macy 	if (le->le_name_numints > buflen)
544eda14cbcSMatt Macy 		return (SET_ERROR(EOVERFLOW));
545eda14cbcSMatt Macy 	return (0);
546eda14cbcSMatt Macy }
547eda14cbcSMatt Macy 
548eda14cbcSMatt Macy int
549eda14cbcSMatt Macy zap_entry_update(zap_entry_handle_t *zeh,
550eda14cbcSMatt Macy     uint8_t integer_size, uint64_t num_integers, const void *buf)
551eda14cbcSMatt Macy {
552eda14cbcSMatt Macy 	zap_leaf_t *l = zeh->zeh_leaf;
553eda14cbcSMatt Macy 	struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, *zeh->zeh_chunkp);
554eda14cbcSMatt Macy 
555eda14cbcSMatt Macy 	int delta_chunks = ZAP_LEAF_ARRAY_NCHUNKS(num_integers * integer_size) -
556eda14cbcSMatt Macy 	    ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints * le->le_value_intlen);
557eda14cbcSMatt Macy 
558eda14cbcSMatt Macy 	if ((int)zap_leaf_phys(l)->l_hdr.lh_nfree < delta_chunks)
559eda14cbcSMatt Macy 		return (SET_ERROR(EAGAIN));
560eda14cbcSMatt Macy 
561*718519f4SMartin Matuska 	zap_leaf_array_free(l, le->le_value_chunk);
562eda14cbcSMatt Macy 	le->le_value_chunk =
563eda14cbcSMatt Macy 	    zap_leaf_array_create(l, buf, integer_size, num_integers);
564eda14cbcSMatt Macy 	le->le_value_numints = num_integers;
565eda14cbcSMatt Macy 	le->le_value_intlen = integer_size;
566eda14cbcSMatt Macy 	return (0);
567eda14cbcSMatt Macy }
568eda14cbcSMatt Macy 
569eda14cbcSMatt Macy void
570eda14cbcSMatt Macy zap_entry_remove(zap_entry_handle_t *zeh)
571eda14cbcSMatt Macy {
572eda14cbcSMatt Macy 	zap_leaf_t *l = zeh->zeh_leaf;
573eda14cbcSMatt Macy 
574eda14cbcSMatt Macy 	ASSERT3P(zeh->zeh_chunkp, !=, &zeh->zeh_fakechunk);
575eda14cbcSMatt Macy 
576eda14cbcSMatt Macy 	uint16_t entry_chunk = *zeh->zeh_chunkp;
577eda14cbcSMatt Macy 	struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, entry_chunk);
578eda14cbcSMatt Macy 	ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
579eda14cbcSMatt Macy 
580eda14cbcSMatt Macy 	*zeh->zeh_chunkp = le->le_next;
581*718519f4SMartin Matuska 
582*718519f4SMartin Matuska 	/* Free in opposite order to reduce fragmentation. */
583*718519f4SMartin Matuska 	zap_leaf_array_free(l, le->le_value_chunk);
584*718519f4SMartin Matuska 	zap_leaf_array_free(l, le->le_name_chunk);
585eda14cbcSMatt Macy 	zap_leaf_chunk_free(l, entry_chunk);
586eda14cbcSMatt Macy 
587eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_nentries--;
588eda14cbcSMatt Macy }
589eda14cbcSMatt Macy 
590eda14cbcSMatt Macy int
591eda14cbcSMatt Macy zap_entry_create(zap_leaf_t *l, zap_name_t *zn, uint32_t cd,
592eda14cbcSMatt Macy     uint8_t integer_size, uint64_t num_integers, const void *buf,
593eda14cbcSMatt Macy     zap_entry_handle_t *zeh)
594eda14cbcSMatt Macy {
595eda14cbcSMatt Macy 	uint16_t chunk;
596eda14cbcSMatt Macy 	struct zap_leaf_entry *le;
597eda14cbcSMatt Macy 	uint64_t h = zn->zn_hash;
598eda14cbcSMatt Macy 
599eda14cbcSMatt Macy 	uint64_t valuelen = integer_size * num_integers;
600eda14cbcSMatt Macy 
601783d3ff6SMartin Matuska 	uint_t numchunks = 1 + ZAP_LEAF_ARRAY_NCHUNKS(zn->zn_key_orig_numints *
602eda14cbcSMatt Macy 	    zn->zn_key_intlen) + ZAP_LEAF_ARRAY_NCHUNKS(valuelen);
603eda14cbcSMatt Macy 	if (numchunks > ZAP_LEAF_NUMCHUNKS(l))
604eda14cbcSMatt Macy 		return (SET_ERROR(E2BIG));
605eda14cbcSMatt Macy 
606eda14cbcSMatt Macy 	if (cd == ZAP_NEED_CD) {
607eda14cbcSMatt Macy 		/* find the lowest unused cd */
608eda14cbcSMatt Macy 		if (zap_leaf_phys(l)->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED) {
609eda14cbcSMatt Macy 			cd = 0;
610eda14cbcSMatt Macy 
611eda14cbcSMatt Macy 			for (chunk = *LEAF_HASH_ENTPTR(l, h);
612eda14cbcSMatt Macy 			    chunk != CHAIN_END; chunk = le->le_next) {
613eda14cbcSMatt Macy 				le = ZAP_LEAF_ENTRY(l, chunk);
614eda14cbcSMatt Macy 				if (le->le_cd > cd)
615eda14cbcSMatt Macy 					break;
616eda14cbcSMatt Macy 				if (le->le_hash == h) {
617eda14cbcSMatt Macy 					ASSERT3U(cd, ==, le->le_cd);
618eda14cbcSMatt Macy 					cd++;
619eda14cbcSMatt Macy 				}
620eda14cbcSMatt Macy 			}
621eda14cbcSMatt Macy 		} else {
622eda14cbcSMatt Macy 			/* old unsorted format; do it the O(n^2) way */
623eda14cbcSMatt Macy 			for (cd = 0; ; cd++) {
624eda14cbcSMatt Macy 				for (chunk = *LEAF_HASH_ENTPTR(l, h);
625eda14cbcSMatt Macy 				    chunk != CHAIN_END; chunk = le->le_next) {
626eda14cbcSMatt Macy 					le = ZAP_LEAF_ENTRY(l, chunk);
627eda14cbcSMatt Macy 					if (le->le_hash == h &&
628eda14cbcSMatt Macy 					    le->le_cd == cd) {
629eda14cbcSMatt Macy 						break;
630eda14cbcSMatt Macy 					}
631eda14cbcSMatt Macy 				}
632eda14cbcSMatt Macy 				/* If this cd is not in use, we are good. */
633eda14cbcSMatt Macy 				if (chunk == CHAIN_END)
634eda14cbcSMatt Macy 					break;
635eda14cbcSMatt Macy 			}
636eda14cbcSMatt Macy 		}
637eda14cbcSMatt Macy 		/*
638eda14cbcSMatt Macy 		 * We would run out of space in a block before we could
639eda14cbcSMatt Macy 		 * store enough entries to run out of CD values.
640eda14cbcSMatt Macy 		 */
641eda14cbcSMatt Macy 		ASSERT3U(cd, <, zap_maxcd(zn->zn_zap));
642eda14cbcSMatt Macy 	}
643eda14cbcSMatt Macy 
644eda14cbcSMatt Macy 	if (zap_leaf_phys(l)->l_hdr.lh_nfree < numchunks)
645eda14cbcSMatt Macy 		return (SET_ERROR(EAGAIN));
646eda14cbcSMatt Macy 
647eda14cbcSMatt Macy 	/* make the entry */
648eda14cbcSMatt Macy 	chunk = zap_leaf_chunk_alloc(l);
649eda14cbcSMatt Macy 	le = ZAP_LEAF_ENTRY(l, chunk);
650eda14cbcSMatt Macy 	le->le_type = ZAP_CHUNK_ENTRY;
651eda14cbcSMatt Macy 	le->le_name_chunk = zap_leaf_array_create(l, zn->zn_key_orig,
652eda14cbcSMatt Macy 	    zn->zn_key_intlen, zn->zn_key_orig_numints);
653eda14cbcSMatt Macy 	le->le_name_numints = zn->zn_key_orig_numints;
654eda14cbcSMatt Macy 	le->le_value_chunk =
655eda14cbcSMatt Macy 	    zap_leaf_array_create(l, buf, integer_size, num_integers);
656eda14cbcSMatt Macy 	le->le_value_numints = num_integers;
657eda14cbcSMatt Macy 	le->le_value_intlen = integer_size;
658eda14cbcSMatt Macy 	le->le_hash = h;
659eda14cbcSMatt Macy 	le->le_cd = cd;
660eda14cbcSMatt Macy 
661eda14cbcSMatt Macy 	/* link it into the hash chain */
662eda14cbcSMatt Macy 	/* XXX if we did the search above, we could just use that */
663783d3ff6SMartin Matuska 	uint16_t *chunkp = zap_leaf_rehash_entry(l, le, chunk);
664eda14cbcSMatt Macy 
665eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_nentries++;
666eda14cbcSMatt Macy 
667eda14cbcSMatt Macy 	zeh->zeh_leaf = l;
668eda14cbcSMatt Macy 	zeh->zeh_num_integers = num_integers;
669eda14cbcSMatt Macy 	zeh->zeh_integer_size = le->le_value_intlen;
670eda14cbcSMatt Macy 	zeh->zeh_cd = le->le_cd;
671eda14cbcSMatt Macy 	zeh->zeh_hash = le->le_hash;
672eda14cbcSMatt Macy 	zeh->zeh_chunkp = chunkp;
673eda14cbcSMatt Macy 
674eda14cbcSMatt Macy 	return (0);
675eda14cbcSMatt Macy }
676eda14cbcSMatt Macy 
677eda14cbcSMatt Macy /*
678eda14cbcSMatt Macy  * Determine if there is another entry with the same normalized form.
679eda14cbcSMatt Macy  * For performance purposes, either zn or name must be provided (the
680eda14cbcSMatt Macy  * other can be NULL).  Note, there usually won't be any hash
681eda14cbcSMatt Macy  * conflicts, in which case we don't need the concatenated/normalized
682eda14cbcSMatt Macy  * form of the name.  But all callers have one of these on hand anyway,
683eda14cbcSMatt Macy  * so might as well take advantage.  A cleaner but slower interface
684eda14cbcSMatt Macy  * would accept neither argument, and compute the normalized name as
685dbd5678dSMartin Matuska  * needed (using zap_name_alloc_str(zap_entry_read_name(zeh))).
686eda14cbcSMatt Macy  */
687eda14cbcSMatt Macy boolean_t
688eda14cbcSMatt Macy zap_entry_normalization_conflict(zap_entry_handle_t *zeh, zap_name_t *zn,
689eda14cbcSMatt Macy     const char *name, zap_t *zap)
690eda14cbcSMatt Macy {
691eda14cbcSMatt Macy 	struct zap_leaf_entry *le;
692eda14cbcSMatt Macy 	boolean_t allocdzn = B_FALSE;
693eda14cbcSMatt Macy 
694eda14cbcSMatt Macy 	if (zap->zap_normflags == 0)
695eda14cbcSMatt Macy 		return (B_FALSE);
696eda14cbcSMatt Macy 
697eda14cbcSMatt Macy 	for (uint16_t chunk = *LEAF_HASH_ENTPTR(zeh->zeh_leaf, zeh->zeh_hash);
698eda14cbcSMatt Macy 	    chunk != CHAIN_END; chunk = le->le_next) {
699eda14cbcSMatt Macy 		le = ZAP_LEAF_ENTRY(zeh->zeh_leaf, chunk);
700eda14cbcSMatt Macy 		if (le->le_hash != zeh->zeh_hash)
701eda14cbcSMatt Macy 			continue;
702eda14cbcSMatt Macy 		if (le->le_cd == zeh->zeh_cd)
703eda14cbcSMatt Macy 			continue;
704eda14cbcSMatt Macy 
705eda14cbcSMatt Macy 		if (zn == NULL) {
706dbd5678dSMartin Matuska 			zn = zap_name_alloc_str(zap, name, MT_NORMALIZE);
707eda14cbcSMatt Macy 			allocdzn = B_TRUE;
708eda14cbcSMatt Macy 		}
709eda14cbcSMatt Macy 		if (zap_leaf_array_match(zeh->zeh_leaf, zn,
710eda14cbcSMatt Macy 		    le->le_name_chunk, le->le_name_numints)) {
711eda14cbcSMatt Macy 			if (allocdzn)
712eda14cbcSMatt Macy 				zap_name_free(zn);
713eda14cbcSMatt Macy 			return (B_TRUE);
714eda14cbcSMatt Macy 		}
715eda14cbcSMatt Macy 	}
716eda14cbcSMatt Macy 	if (allocdzn)
717eda14cbcSMatt Macy 		zap_name_free(zn);
718eda14cbcSMatt Macy 	return (B_FALSE);
719eda14cbcSMatt Macy }
720eda14cbcSMatt Macy 
721eda14cbcSMatt Macy /*
722eda14cbcSMatt Macy  * Routines for transferring entries between leafs.
723eda14cbcSMatt Macy  */
724eda14cbcSMatt Macy 
725eda14cbcSMatt Macy static uint16_t *
726783d3ff6SMartin Matuska zap_leaf_rehash_entry(zap_leaf_t *l, struct zap_leaf_entry *le, uint16_t entry)
727eda14cbcSMatt Macy {
728eda14cbcSMatt Macy 	struct zap_leaf_entry *le2;
729eda14cbcSMatt Macy 	uint16_t *chunkp;
730eda14cbcSMatt Macy 
731eda14cbcSMatt Macy 	/*
732eda14cbcSMatt Macy 	 * keep the entry chain sorted by cd
733eda14cbcSMatt Macy 	 * NB: this will not cause problems for unsorted leafs, though
734eda14cbcSMatt Macy 	 * it is unnecessary there.
735eda14cbcSMatt Macy 	 */
736eda14cbcSMatt Macy 	for (chunkp = LEAF_HASH_ENTPTR(l, le->le_hash);
737eda14cbcSMatt Macy 	    *chunkp != CHAIN_END; chunkp = &le2->le_next) {
738eda14cbcSMatt Macy 		le2 = ZAP_LEAF_ENTRY(l, *chunkp);
739eda14cbcSMatt Macy 		if (le2->le_cd > le->le_cd)
740eda14cbcSMatt Macy 			break;
741eda14cbcSMatt Macy 	}
742eda14cbcSMatt Macy 
743eda14cbcSMatt Macy 	le->le_next = *chunkp;
744eda14cbcSMatt Macy 	*chunkp = entry;
745eda14cbcSMatt Macy 	return (chunkp);
746eda14cbcSMatt Macy }
747eda14cbcSMatt Macy 
748eda14cbcSMatt Macy static void
749783d3ff6SMartin Matuska zap_leaf_transfer_entry(zap_leaf_t *l, uint_t entry, zap_leaf_t *nl)
750eda14cbcSMatt Macy {
751eda14cbcSMatt Macy 	struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, entry);
752eda14cbcSMatt Macy 	ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
753eda14cbcSMatt Macy 
754eda14cbcSMatt Macy 	uint16_t chunk = zap_leaf_chunk_alloc(nl);
755eda14cbcSMatt Macy 	struct zap_leaf_entry *nle = ZAP_LEAF_ENTRY(nl, chunk);
756eda14cbcSMatt Macy 	*nle = *le; /* structure assignment */
757eda14cbcSMatt Macy 
758783d3ff6SMartin Matuska 	(void) zap_leaf_rehash_entry(nl, nle, chunk);
759eda14cbcSMatt Macy 
760*718519f4SMartin Matuska 	nle->le_name_chunk = zap_leaf_array_copy(l, le->le_name_chunk, nl);
761*718519f4SMartin Matuska 	nle->le_value_chunk = zap_leaf_array_copy(l, le->le_value_chunk, nl);
762eda14cbcSMatt Macy 
763*718519f4SMartin Matuska 	/* Free in opposite order to reduce fragmentation. */
764*718519f4SMartin Matuska 	zap_leaf_array_free(l, le->le_value_chunk);
765*718519f4SMartin Matuska 	zap_leaf_array_free(l, le->le_name_chunk);
766eda14cbcSMatt Macy 	zap_leaf_chunk_free(l, entry);
767eda14cbcSMatt Macy 
768eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_nentries--;
769eda14cbcSMatt Macy 	zap_leaf_phys(nl)->l_hdr.lh_nentries++;
770eda14cbcSMatt Macy }
771eda14cbcSMatt Macy 
772eda14cbcSMatt Macy /*
773eda14cbcSMatt Macy  * Transfer the entries whose hash prefix ends in 1 to the new leaf.
774eda14cbcSMatt Macy  */
775eda14cbcSMatt Macy void
776eda14cbcSMatt Macy zap_leaf_split(zap_leaf_t *l, zap_leaf_t *nl, boolean_t sort)
777eda14cbcSMatt Macy {
778783d3ff6SMartin Matuska 	uint_t bit = 64 - 1 - zap_leaf_phys(l)->l_hdr.lh_prefix_len;
779eda14cbcSMatt Macy 
780eda14cbcSMatt Macy 	/* set new prefix and prefix_len */
781eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_prefix <<= 1;
782eda14cbcSMatt Macy 	zap_leaf_phys(l)->l_hdr.lh_prefix_len++;
783eda14cbcSMatt Macy 	zap_leaf_phys(nl)->l_hdr.lh_prefix =
784eda14cbcSMatt Macy 	    zap_leaf_phys(l)->l_hdr.lh_prefix | 1;
785eda14cbcSMatt Macy 	zap_leaf_phys(nl)->l_hdr.lh_prefix_len =
786eda14cbcSMatt Macy 	    zap_leaf_phys(l)->l_hdr.lh_prefix_len;
787eda14cbcSMatt Macy 
788eda14cbcSMatt Macy 	/* break existing hash chains */
789783d3ff6SMartin Matuska 	memset(zap_leaf_phys(l)->l_hash, CHAIN_END,
790eda14cbcSMatt Macy 	    2*ZAP_LEAF_HASH_NUMENTRIES(l));
791eda14cbcSMatt Macy 
792eda14cbcSMatt Macy 	if (sort)
793eda14cbcSMatt Macy 		zap_leaf_phys(l)->l_hdr.lh_flags |= ZLF_ENTRIES_CDSORTED;
794eda14cbcSMatt Macy 
795eda14cbcSMatt Macy 	/*
796eda14cbcSMatt Macy 	 * Transfer entries whose hash bit 'bit' is set to nl; rehash
797eda14cbcSMatt Macy 	 * the remaining entries
798eda14cbcSMatt Macy 	 *
799eda14cbcSMatt Macy 	 * NB: We could find entries via the hashtable instead. That
800eda14cbcSMatt Macy 	 * would be O(hashents+numents) rather than O(numblks+numents),
801eda14cbcSMatt Macy 	 * but this accesses memory more sequentially, and when we're
802eda14cbcSMatt Macy 	 * called, the block is usually pretty full.
803eda14cbcSMatt Macy 	 */
804783d3ff6SMartin Matuska 	for (uint_t i = 0; i < ZAP_LEAF_NUMCHUNKS(l); i++) {
805eda14cbcSMatt Macy 		struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, i);
806eda14cbcSMatt Macy 		if (le->le_type != ZAP_CHUNK_ENTRY)
807eda14cbcSMatt Macy 			continue;
808eda14cbcSMatt Macy 
809eda14cbcSMatt Macy 		if (le->le_hash & (1ULL << bit))
810eda14cbcSMatt Macy 			zap_leaf_transfer_entry(l, i, nl);
811eda14cbcSMatt Macy 		else
812783d3ff6SMartin Matuska 			(void) zap_leaf_rehash_entry(l, le, i);
813eda14cbcSMatt Macy 	}
814eda14cbcSMatt Macy }
815eda14cbcSMatt Macy 
816eda14cbcSMatt Macy void
817eda14cbcSMatt Macy zap_leaf_stats(zap_t *zap, zap_leaf_t *l, zap_stats_t *zs)
818eda14cbcSMatt Macy {
819783d3ff6SMartin Matuska 	uint_t n = zap_f_phys(zap)->zap_ptrtbl.zt_shift -
820eda14cbcSMatt Macy 	    zap_leaf_phys(l)->l_hdr.lh_prefix_len;
821eda14cbcSMatt Macy 	n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
822eda14cbcSMatt Macy 	zs->zs_leafs_with_2n_pointers[n]++;
823eda14cbcSMatt Macy 
824eda14cbcSMatt Macy 
825eda14cbcSMatt Macy 	n = zap_leaf_phys(l)->l_hdr.lh_nentries/5;
826eda14cbcSMatt Macy 	n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
827eda14cbcSMatt Macy 	zs->zs_blocks_with_n5_entries[n]++;
828eda14cbcSMatt Macy 
829eda14cbcSMatt Macy 	n = ((1<<FZAP_BLOCK_SHIFT(zap)) -
830eda14cbcSMatt Macy 	    zap_leaf_phys(l)->l_hdr.lh_nfree * (ZAP_LEAF_ARRAY_BYTES+1))*10 /
831eda14cbcSMatt Macy 	    (1<<FZAP_BLOCK_SHIFT(zap));
832eda14cbcSMatt Macy 	n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
833eda14cbcSMatt Macy 	zs->zs_blocks_n_tenths_full[n]++;
834eda14cbcSMatt Macy 
835783d3ff6SMartin Matuska 	for (uint_t i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(l); i++) {
836783d3ff6SMartin Matuska 		uint_t nentries = 0;
837783d3ff6SMartin Matuska 		uint_t chunk = zap_leaf_phys(l)->l_hash[i];
838eda14cbcSMatt Macy 
839eda14cbcSMatt Macy 		while (chunk != CHAIN_END) {
840eda14cbcSMatt Macy 			struct zap_leaf_entry *le =
841eda14cbcSMatt Macy 			    ZAP_LEAF_ENTRY(l, chunk);
842eda14cbcSMatt Macy 
843eda14cbcSMatt Macy 			n = 1 + ZAP_LEAF_ARRAY_NCHUNKS(le->le_name_numints) +
844eda14cbcSMatt Macy 			    ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints *
845eda14cbcSMatt Macy 			    le->le_value_intlen);
846eda14cbcSMatt Macy 			n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
847eda14cbcSMatt Macy 			zs->zs_entries_using_n_chunks[n]++;
848eda14cbcSMatt Macy 
849eda14cbcSMatt Macy 			chunk = le->le_next;
850eda14cbcSMatt Macy 			nentries++;
851eda14cbcSMatt Macy 		}
852eda14cbcSMatt Macy 
853eda14cbcSMatt Macy 		n = nentries;
854eda14cbcSMatt Macy 		n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
855eda14cbcSMatt Macy 		zs->zs_buckets_with_n_entries[n]++;
856eda14cbcSMatt Macy 	}
857eda14cbcSMatt Macy }
858