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