xref: /onnv-gate/usr/src/uts/common/fs/zfs/zap_leaf.c (revision 789:b348f31ed315)
1*789Sahrens /*
2*789Sahrens  * CDDL HEADER START
3*789Sahrens  *
4*789Sahrens  * The contents of this file are subject to the terms of the
5*789Sahrens  * Common Development and Distribution License, Version 1.0 only
6*789Sahrens  * (the "License").  You may not use this file except in compliance
7*789Sahrens  * with the License.
8*789Sahrens  *
9*789Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*789Sahrens  * or http://www.opensolaris.org/os/licensing.
11*789Sahrens  * See the License for the specific language governing permissions
12*789Sahrens  * and limitations under the License.
13*789Sahrens  *
14*789Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
15*789Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*789Sahrens  * If applicable, add the following below this CDDL HEADER, with the
17*789Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
18*789Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
19*789Sahrens  *
20*789Sahrens  * CDDL HEADER END
21*789Sahrens  */
22*789Sahrens /*
23*789Sahrens  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*789Sahrens  * Use is subject to license terms.
25*789Sahrens  */
26*789Sahrens 
27*789Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*789Sahrens 
29*789Sahrens /*
30*789Sahrens  * The 512-byte leaf is broken into 32 16-byte chunks.
31*789Sahrens  * chunk number n means l_chunk[n], even though the header precedes it.
32*789Sahrens  * the names are stored null-terminated.
33*789Sahrens  */
34*789Sahrens 
35*789Sahrens #include <sys/zfs_context.h>
36*789Sahrens #include <sys/zap.h>
37*789Sahrens #include <sys/zap_impl.h>
38*789Sahrens #include <sys/zap_leaf.h>
39*789Sahrens #include <sys/spa.h>
40*789Sahrens #include <sys/dmu.h>
41*789Sahrens 
42*789Sahrens #define	CHAIN_END 0xffff /* end of the chunk chain */
43*789Sahrens 
44*789Sahrens /* somewhat arbitrary, could go up to around 100k ... */
45*789Sahrens #define	MAX_ARRAY_BYTES (8<<10)
46*789Sahrens 
47*789Sahrens #define	NCHUNKS(bytes) (((bytes)+ZAP_LEAF_ARRAY_BYTES-1)/ZAP_LEAF_ARRAY_BYTES)
48*789Sahrens 
49*789Sahrens /*
50*789Sahrens  * XXX This will >> by a negative number when
51*789Sahrens  * lh_prefix_len > 64-ZAP_LEAF_HASH_SHIFT.
52*789Sahrens  */
53*789Sahrens #define	LEAF_HASH(l, h) \
54*789Sahrens 	((ZAP_LEAF_HASH_NUMENTRIES-1) & \
55*789Sahrens 		((h) >> (64 - ZAP_LEAF_HASH_SHIFT-(l)->lh_prefix_len)))
56*789Sahrens 
57*789Sahrens #define	LEAF_HASH_ENTPTR(l, h) (&(l)->l_phys->l_hash[LEAF_HASH(l, h)])
58*789Sahrens 
59*789Sahrens /* #define	MEMCHECK */
60*789Sahrens 
61*789Sahrens 
62*789Sahrens static void
63*789Sahrens zap_memset(void *a, int c, size_t n)
64*789Sahrens {
65*789Sahrens 	char *cp = a;
66*789Sahrens 	char *cpend = cp + n;
67*789Sahrens 
68*789Sahrens 	while (cp < cpend)
69*789Sahrens 		*cp++ = c;
70*789Sahrens }
71*789Sahrens 
72*789Sahrens static void
73*789Sahrens stv(int len, void *addr, uint64_t value)
74*789Sahrens {
75*789Sahrens 	switch (len) {
76*789Sahrens 	case 1:
77*789Sahrens 		*(uint8_t *)addr = value;
78*789Sahrens 		return;
79*789Sahrens 	case 2:
80*789Sahrens 		*(uint16_t *)addr = value;
81*789Sahrens 		return;
82*789Sahrens 	case 4:
83*789Sahrens 		*(uint32_t *)addr = value;
84*789Sahrens 		return;
85*789Sahrens 	case 8:
86*789Sahrens 		*(uint64_t *)addr = value;
87*789Sahrens 		return;
88*789Sahrens 	}
89*789Sahrens 	ASSERT(!"bad int len");
90*789Sahrens }
91*789Sahrens 
92*789Sahrens static uint64_t
93*789Sahrens ldv(int len, const void *addr)
94*789Sahrens {
95*789Sahrens 	switch (len) {
96*789Sahrens 	case 1:
97*789Sahrens 		return (*(uint8_t *)addr);
98*789Sahrens 	case 2:
99*789Sahrens 		return (*(uint16_t *)addr);
100*789Sahrens 	case 4:
101*789Sahrens 		return (*(uint32_t *)addr);
102*789Sahrens 	case 8:
103*789Sahrens 		return (*(uint64_t *)addr);
104*789Sahrens 	}
105*789Sahrens 	ASSERT(!"bad int len");
106*789Sahrens 	return (0xFEEDFACEDEADBEEF);
107*789Sahrens }
108*789Sahrens 
109*789Sahrens void
110*789Sahrens zap_leaf_byteswap(zap_leaf_phys_t *buf)
111*789Sahrens {
112*789Sahrens 	int i;
113*789Sahrens 
114*789Sahrens 	buf->l_hdr.lhr_block_type = 	BSWAP_64(buf->l_hdr.lhr_block_type);
115*789Sahrens 	buf->l_hdr.lhr_next = 		BSWAP_64(buf->l_hdr.lhr_next);
116*789Sahrens 	buf->l_hdr.lhr_prefix = 	BSWAP_64(buf->l_hdr.lhr_prefix);
117*789Sahrens 	buf->l_hdr.lhr_magic = 		BSWAP_32(buf->l_hdr.lhr_magic);
118*789Sahrens 	buf->l_hdr.lhr_nfree = 		BSWAP_16(buf->l_hdr.lhr_nfree);
119*789Sahrens 	buf->l_hdr.lhr_nentries = 	BSWAP_16(buf->l_hdr.lhr_nentries);
120*789Sahrens 	buf->l_hdr.lhr_prefix_len = 	BSWAP_16(buf->l_hdr.lhr_prefix_len);
121*789Sahrens 	buf->l_hdr.lh_freelist = 	BSWAP_16(buf->l_hdr.lh_freelist);
122*789Sahrens 
123*789Sahrens 	for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES; i++)
124*789Sahrens 		buf->l_hash[i] = BSWAP_16(buf->l_hash[i]);
125*789Sahrens 
126*789Sahrens 	for (i = 0; i < ZAP_LEAF_NUMCHUNKS; i++) {
127*789Sahrens 		struct zap_leaf_entry *le;
128*789Sahrens 
129*789Sahrens 		switch (buf->l_chunk[i].l_free.lf_type) {
130*789Sahrens 		case ZAP_LEAF_ENTRY:
131*789Sahrens 			le = &buf->l_chunk[i].l_entry;
132*789Sahrens 
133*789Sahrens 			le->le_type = BSWAP_8(le->le_type);
134*789Sahrens 			le->le_int_size = BSWAP_8(le->le_int_size);
135*789Sahrens 			le->le_next = BSWAP_16(le->le_next);
136*789Sahrens 			le->le_name_chunk = BSWAP_16(le->le_name_chunk);
137*789Sahrens 			le->le_name_length = BSWAP_16(le->le_name_length);
138*789Sahrens 			le->le_value_chunk = BSWAP_16(le->le_value_chunk);
139*789Sahrens 			le->le_value_length = BSWAP_16(le->le_value_length);
140*789Sahrens 			le->le_cd = BSWAP_32(le->le_cd);
141*789Sahrens 			le->le_hash = BSWAP_64(le->le_hash);
142*789Sahrens 			break;
143*789Sahrens 		case ZAP_LEAF_FREE:
144*789Sahrens 			buf->l_chunk[i].l_free.lf_type =
145*789Sahrens 			    BSWAP_8(buf->l_chunk[i].l_free.lf_type);
146*789Sahrens 			buf->l_chunk[i].l_free.lf_next =
147*789Sahrens 			    BSWAP_16(buf->l_chunk[i].l_free.lf_next);
148*789Sahrens 			break;
149*789Sahrens 		case ZAP_LEAF_ARRAY:
150*789Sahrens 			/* zap_leaf_array */
151*789Sahrens 			buf->l_chunk[i].l_array.la_type =
152*789Sahrens 			    BSWAP_8(buf->l_chunk[i].l_array.la_type);
153*789Sahrens 			buf->l_chunk[i].l_array.la_next =
154*789Sahrens 			    BSWAP_16(buf->l_chunk[i].l_array.la_next);
155*789Sahrens 			/* la_array doesn't need swapping */
156*789Sahrens 			break;
157*789Sahrens 		default:
158*789Sahrens 			ASSERT(!"bad leaf type");
159*789Sahrens 		}
160*789Sahrens 	}
161*789Sahrens }
162*789Sahrens 
163*789Sahrens void
164*789Sahrens zap_leaf_init(zap_leaf_t *l)
165*789Sahrens {
166*789Sahrens 	int i;
167*789Sahrens 
168*789Sahrens 	ASSERT3U(sizeof (zap_leaf_phys_t), ==, l->l_dbuf->db_size);
169*789Sahrens 	zap_memset(&l->l_phys->l_hdr, 0, sizeof (struct zap_leaf_header));
170*789Sahrens 	zap_memset(&l->l_phys->l_hash, CHAIN_END, sizeof (l->l_phys->l_hash));
171*789Sahrens 	for (i = 0; i < ZAP_LEAF_NUMCHUNKS; i++) {
172*789Sahrens 		l->l_phys->l_chunk[i].l_free.lf_type = ZAP_LEAF_FREE;
173*789Sahrens 		l->l_phys->l_chunk[i].l_free.lf_next = i+1;
174*789Sahrens 	}
175*789Sahrens 	l->l_phys->l_chunk[ZAP_LEAF_NUMCHUNKS-1].l_free.lf_next = CHAIN_END;
176*789Sahrens 	l->lh_block_type = ZBT_LEAF;
177*789Sahrens 	l->lh_magic = ZAP_LEAF_MAGIC;
178*789Sahrens 	l->lh_nfree = ZAP_LEAF_NUMCHUNKS;
179*789Sahrens }
180*789Sahrens 
181*789Sahrens zap_leaf_t *
182*789Sahrens zap_leaf_chainmore(zap_leaf_t *l, zap_leaf_t *nl)
183*789Sahrens {
184*789Sahrens 	nl->lh_prefix = l->lh_prefix;
185*789Sahrens 	nl->lh_prefix_len = l->lh_prefix_len;
186*789Sahrens 	nl->l_next = l->l_next;
187*789Sahrens 	l->l_next = nl;
188*789Sahrens 	nl->lh_next = l->lh_next;
189*789Sahrens 	l->lh_next = nl->l_blkid;
190*789Sahrens 	return (nl);
191*789Sahrens }
192*789Sahrens 
193*789Sahrens /*
194*789Sahrens  * Routines which manipulate leaf chunks (l_chunk[]).
195*789Sahrens  */
196*789Sahrens 
197*789Sahrens static uint16_t
198*789Sahrens zap_leaf_chunk_alloc(zap_leaf_t *l)
199*789Sahrens {
200*789Sahrens 	int chunk;
201*789Sahrens 
202*789Sahrens 	ASSERT(l->lh_nfree > 0);
203*789Sahrens 
204*789Sahrens 	chunk = l->l_phys->l_hdr.lh_freelist;
205*789Sahrens 	ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS);
206*789Sahrens 	ASSERT3U(l->l_phys->l_chunk[chunk].l_free.lf_type, ==, ZAP_LEAF_FREE);
207*789Sahrens 
208*789Sahrens 	l->l_phys->l_hdr.lh_freelist = l->l_phys->l_chunk[chunk].l_free.lf_next;
209*789Sahrens 
210*789Sahrens #ifdef MEMCHECK
211*789Sahrens 	zap_memset(&l->l_phys->l_chunk[chunk], 0xa1,
212*789Sahrens 	    sizeof (l->l_phys->l_chunk[chunk]));
213*789Sahrens #endif
214*789Sahrens 
215*789Sahrens 	l->lh_nfree--;
216*789Sahrens 
217*789Sahrens 	return (chunk);
218*789Sahrens }
219*789Sahrens 
220*789Sahrens static void
221*789Sahrens zap_leaf_chunk_free(zap_leaf_t *l, uint16_t chunk)
222*789Sahrens {
223*789Sahrens 	struct zap_leaf_free *zlf = &l->l_phys->l_chunk[chunk].l_free;
224*789Sahrens 	ASSERT3U(l->lh_nfree, <, ZAP_LEAF_NUMCHUNKS);
225*789Sahrens 	ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS);
226*789Sahrens 	ASSERT(zlf->lf_type != ZAP_LEAF_FREE);
227*789Sahrens 
228*789Sahrens #ifdef MEMCHECK
229*789Sahrens 	zap_memset(&l->l_phys->l_chunk[chunk], 0xf4,
230*789Sahrens 	    sizeof (l->l_phys->l_chunk[chunk]));
231*789Sahrens #endif
232*789Sahrens 
233*789Sahrens 	zlf->lf_type = ZAP_LEAF_FREE;
234*789Sahrens 	zlf->lf_next = l->l_phys->l_hdr.lh_freelist;
235*789Sahrens 	bzero(zlf->lf_pad, sizeof (zlf->lf_pad)); /* help it to compress */
236*789Sahrens 	l->l_phys->l_hdr.lh_freelist = chunk;
237*789Sahrens 
238*789Sahrens 	l->lh_nfree++;
239*789Sahrens }
240*789Sahrens 
241*789Sahrens 
242*789Sahrens /*
243*789Sahrens  * Routines which manipulate leaf arrays (zap_leaf_array type chunks).
244*789Sahrens  */
245*789Sahrens 
246*789Sahrens static uint16_t
247*789Sahrens zap_leaf_array_create(const zap_entry_handle_t *zeh, const char *buf,
248*789Sahrens 	int integer_size, int num_integers)
249*789Sahrens {
250*789Sahrens 	uint16_t chunk_head;
251*789Sahrens 	uint16_t *chunkp = &chunk_head;
252*789Sahrens 	int byten = 0;
253*789Sahrens 	uint64_t value;
254*789Sahrens 	int shift = (integer_size-1)*8;
255*789Sahrens 	int len = num_integers;
256*789Sahrens 	zap_leaf_t *l = zeh->zeh_found_leaf;
257*789Sahrens 
258*789Sahrens 	ASSERT3U(num_integers * integer_size, <, MAX_ARRAY_BYTES);
259*789Sahrens 
260*789Sahrens 	while (len > 0) {
261*789Sahrens 		uint16_t chunk = zap_leaf_chunk_alloc(l);
262*789Sahrens 		struct zap_leaf_array *la = &l->l_phys->l_chunk[chunk].l_array;
263*789Sahrens 		int i;
264*789Sahrens 
265*789Sahrens 		la->la_type = ZAP_LEAF_ARRAY;
266*789Sahrens 		for (i = 0; i < ZAP_LEAF_ARRAY_BYTES; i++) {
267*789Sahrens 			if (byten == 0)
268*789Sahrens 				value = ldv(integer_size, buf);
269*789Sahrens 			la->la_array[i] = (value & (0xff << shift)) >> shift;
270*789Sahrens 			value <<= 8;
271*789Sahrens 			if (++byten == integer_size) {
272*789Sahrens 				byten = 0;
273*789Sahrens 				buf += integer_size;
274*789Sahrens 				if (--len == 0)
275*789Sahrens 					break;
276*789Sahrens 			}
277*789Sahrens 		}
278*789Sahrens 
279*789Sahrens 		*chunkp = chunk;
280*789Sahrens 		chunkp = &la->la_next;
281*789Sahrens 	}
282*789Sahrens 	*chunkp = CHAIN_END;
283*789Sahrens 
284*789Sahrens 	return (chunk_head);
285*789Sahrens }
286*789Sahrens 
287*789Sahrens static void
288*789Sahrens zap_leaf_array_free(zap_entry_handle_t *zeh, uint16_t *chunkp)
289*789Sahrens {
290*789Sahrens 	uint16_t chunk = *chunkp;
291*789Sahrens 	zap_leaf_t *l = zeh->zeh_found_leaf;
292*789Sahrens 
293*789Sahrens 	*chunkp = CHAIN_END;
294*789Sahrens 
295*789Sahrens 	while (chunk != CHAIN_END) {
296*789Sahrens 		int nextchunk = l->l_phys->l_chunk[chunk].l_array.la_next;
297*789Sahrens 		ASSERT3U(l->l_phys->l_chunk[chunk].l_array.la_type, ==,
298*789Sahrens 		    ZAP_LEAF_ARRAY);
299*789Sahrens 		zap_leaf_chunk_free(l, chunk);
300*789Sahrens 		chunk = nextchunk;
301*789Sahrens 	}
302*789Sahrens }
303*789Sahrens 
304*789Sahrens /* array_len and buf_len are in integers, not bytes */
305*789Sahrens static void
306*789Sahrens zap_leaf_array_read(const zap_entry_handle_t *zeh, uint16_t chunk,
307*789Sahrens     int array_int_len, int array_len, int buf_int_len, uint64_t buf_len,
308*789Sahrens     char *buf)
309*789Sahrens {
310*789Sahrens 	int len = MIN(array_len, buf_len);
311*789Sahrens 	int byten = 0;
312*789Sahrens 	uint64_t value = 0;
313*789Sahrens 	zap_leaf_t *l = zeh->zeh_found_leaf;
314*789Sahrens 
315*789Sahrens 	ASSERT3U(array_int_len, <=, buf_int_len);
316*789Sahrens 
317*789Sahrens 	while (len > 0) {
318*789Sahrens 		struct zap_leaf_array *la = &l->l_phys->l_chunk[chunk].l_array;
319*789Sahrens 		int i;
320*789Sahrens 
321*789Sahrens 		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS);
322*789Sahrens 		for (i = 0; i < ZAP_LEAF_ARRAY_BYTES && len > 0; i++) {
323*789Sahrens 			value = (value << 8) | la->la_array[i];
324*789Sahrens 			byten++;
325*789Sahrens 			if (byten == array_int_len) {
326*789Sahrens 				stv(buf_int_len, buf, value);
327*789Sahrens 				byten = 0;
328*789Sahrens 				len--;
329*789Sahrens 				if (len == 0)
330*789Sahrens 					return;
331*789Sahrens 				buf += buf_int_len;
332*789Sahrens 			}
333*789Sahrens 		}
334*789Sahrens 		chunk = la->la_next;
335*789Sahrens 	}
336*789Sahrens }
337*789Sahrens 
338*789Sahrens /*
339*789Sahrens  * Only to be used on 8-bit arrays.
340*789Sahrens  * array_len is actual len in bytes (not encoded le_value_length).
341*789Sahrens  * buf is null-terminated.
342*789Sahrens  */
343*789Sahrens static int
344*789Sahrens zap_leaf_array_equal(const zap_entry_handle_t *zeh, int chunk,
345*789Sahrens     int array_len, const char *buf)
346*789Sahrens {
347*789Sahrens 	int bseen = 0;
348*789Sahrens 	zap_leaf_t *l = zeh->zeh_found_leaf;
349*789Sahrens 
350*789Sahrens 	while (bseen < array_len) {
351*789Sahrens 		struct zap_leaf_array *la = &l->l_phys->l_chunk[chunk].l_array;
352*789Sahrens 		int toread = MIN(array_len - bseen, ZAP_LEAF_ARRAY_BYTES);
353*789Sahrens 		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS);
354*789Sahrens 		if (bcmp(la->la_array, buf + bseen, toread))
355*789Sahrens 			break;
356*789Sahrens 		chunk = la->la_next;
357*789Sahrens 		bseen += toread;
358*789Sahrens 	}
359*789Sahrens 	return (bseen == array_len);
360*789Sahrens }
361*789Sahrens 
362*789Sahrens /*
363*789Sahrens  * Routines which manipulate leaf entries.
364*789Sahrens  */
365*789Sahrens 
366*789Sahrens int
367*789Sahrens zap_leaf_lookup(zap_leaf_t *l,
368*789Sahrens     const char *name, uint64_t h, zap_entry_handle_t *zeh)
369*789Sahrens {
370*789Sahrens 	uint16_t *chunkp;
371*789Sahrens 	struct zap_leaf_entry *le;
372*789Sahrens 
373*789Sahrens 	zeh->zeh_head_leaf = l;
374*789Sahrens 
375*789Sahrens again:
376*789Sahrens 	ASSERT3U(l->lh_magic, ==, ZAP_LEAF_MAGIC);
377*789Sahrens 
378*789Sahrens 	for (chunkp = LEAF_HASH_ENTPTR(l, h);
379*789Sahrens 	    *chunkp != CHAIN_END; chunkp = &le->le_next) {
380*789Sahrens 		uint16_t chunk = *chunkp;
381*789Sahrens 		le = &l->l_phys->l_chunk[chunk].l_entry;
382*789Sahrens 
383*789Sahrens 		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS);
384*789Sahrens 		ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY);
385*789Sahrens 
386*789Sahrens 		if (le->le_hash != h)
387*789Sahrens 			continue;
388*789Sahrens 
389*789Sahrens 		zeh->zeh_found_leaf = l;
390*789Sahrens 		if (zap_leaf_array_equal(zeh, le->le_name_chunk,
391*789Sahrens 		    le->le_name_length, name)) {
392*789Sahrens 			zeh->zeh_num_integers = le->le_value_length;
393*789Sahrens 			zeh->zeh_integer_size = le->le_int_size;
394*789Sahrens 			zeh->zeh_cd = le->le_cd;
395*789Sahrens 			zeh->zeh_hash = le->le_hash;
396*789Sahrens 			zeh->zeh_chunkp = chunkp;
397*789Sahrens 			zeh->zeh_found_leaf = l;
398*789Sahrens 			return (0);
399*789Sahrens 		}
400*789Sahrens 	}
401*789Sahrens 
402*789Sahrens 	if (l->l_next) {
403*789Sahrens 		l = l->l_next;
404*789Sahrens 		goto again;
405*789Sahrens 	}
406*789Sahrens 
407*789Sahrens 	return (ENOENT);
408*789Sahrens }
409*789Sahrens 
410*789Sahrens /* Return (h1,cd1 >= h2,cd2) */
411*789Sahrens static int
412*789Sahrens hcd_gteq(uint64_t h1, uint32_t cd1, uint64_t h2, uint32_t cd2)
413*789Sahrens {
414*789Sahrens 	if (h1 > h2)
415*789Sahrens 		return (TRUE);
416*789Sahrens 	if (h1 == h2 && cd1 >= cd2)
417*789Sahrens 		return (TRUE);
418*789Sahrens 	return (FALSE);
419*789Sahrens }
420*789Sahrens 
421*789Sahrens int
422*789Sahrens zap_leaf_lookup_closest(zap_leaf_t *l,
423*789Sahrens     uint64_t h, uint32_t cd, zap_entry_handle_t *zeh)
424*789Sahrens {
425*789Sahrens 	uint16_t chunk;
426*789Sahrens 	uint64_t besth = -1ULL;
427*789Sahrens 	uint32_t bestcd = ZAP_MAXCD;
428*789Sahrens 	uint16_t bestlh = ZAP_LEAF_HASH_NUMENTRIES-1;
429*789Sahrens 	uint16_t lh;
430*789Sahrens 	struct zap_leaf_entry *le;
431*789Sahrens 
432*789Sahrens 	zeh->zeh_head_leaf = l;
433*789Sahrens 
434*789Sahrens again:
435*789Sahrens 	ASSERT3U(l->lh_magic, ==, ZAP_LEAF_MAGIC);
436*789Sahrens 
437*789Sahrens 	for (lh = LEAF_HASH(l, h); lh <= bestlh; lh++) {
438*789Sahrens 		for (chunk = l->l_phys->l_hash[lh];
439*789Sahrens 		    chunk != CHAIN_END; chunk = le->le_next) {
440*789Sahrens 			le = &l->l_phys->l_chunk[chunk].l_entry;
441*789Sahrens 
442*789Sahrens 			ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS);
443*789Sahrens 			ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY);
444*789Sahrens 
445*789Sahrens 			if (hcd_gteq(le->le_hash, le->le_cd, h, cd) &&
446*789Sahrens 			    hcd_gteq(besth, bestcd, le->le_hash, le->le_cd)) {
447*789Sahrens 				ASSERT3U(bestlh, >=, lh);
448*789Sahrens 				bestlh = lh;
449*789Sahrens 				besth = le->le_hash;
450*789Sahrens 				bestcd = le->le_cd;
451*789Sahrens 
452*789Sahrens 				zeh->zeh_num_integers = le->le_value_length;
453*789Sahrens 				zeh->zeh_integer_size = le->le_int_size;
454*789Sahrens 				zeh->zeh_cd = le->le_cd;
455*789Sahrens 				zeh->zeh_hash = le->le_hash;
456*789Sahrens 				zeh->zeh_fakechunk = chunk;
457*789Sahrens 				zeh->zeh_chunkp = &zeh->zeh_fakechunk;
458*789Sahrens 				zeh->zeh_found_leaf = l;
459*789Sahrens 			}
460*789Sahrens 		}
461*789Sahrens 	}
462*789Sahrens 
463*789Sahrens 	if (l->l_next) {
464*789Sahrens 		l = l->l_next;
465*789Sahrens 		goto again;
466*789Sahrens 	}
467*789Sahrens 
468*789Sahrens 	return (bestcd == ZAP_MAXCD ? ENOENT : 0);
469*789Sahrens }
470*789Sahrens 
471*789Sahrens int
472*789Sahrens zap_entry_read(const zap_entry_handle_t *zeh,
473*789Sahrens     uint8_t integer_size, uint64_t num_integers, void *buf)
474*789Sahrens {
475*789Sahrens 	struct zap_leaf_entry *le;
476*789Sahrens 
477*789Sahrens 	le = &zeh->zeh_found_leaf->l_phys->l_chunk[*zeh->zeh_chunkp].l_entry;
478*789Sahrens 	ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY);
479*789Sahrens 
480*789Sahrens 	if (le->le_int_size > integer_size)
481*789Sahrens 		return (EINVAL);
482*789Sahrens 
483*789Sahrens 	zap_leaf_array_read(zeh, le->le_value_chunk, le->le_int_size,
484*789Sahrens 	    le->le_value_length, integer_size, num_integers, buf);
485*789Sahrens 
486*789Sahrens 	if (zeh->zeh_num_integers > num_integers)
487*789Sahrens 		return (EOVERFLOW);
488*789Sahrens 	return (0);
489*789Sahrens 
490*789Sahrens }
491*789Sahrens 
492*789Sahrens int
493*789Sahrens zap_entry_read_name(const zap_entry_handle_t *zeh, uint16_t buflen, char *buf)
494*789Sahrens {
495*789Sahrens 	struct zap_leaf_entry *le;
496*789Sahrens 
497*789Sahrens 	le = &zeh->zeh_found_leaf->l_phys->l_chunk[*zeh->zeh_chunkp].l_entry;
498*789Sahrens 	ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY);
499*789Sahrens 
500*789Sahrens 	zap_leaf_array_read(zeh, le->le_name_chunk, 1,
501*789Sahrens 	    le->le_name_length, 1, buflen, buf);
502*789Sahrens 	if (le->le_name_length > buflen)
503*789Sahrens 		return (EOVERFLOW);
504*789Sahrens 	return (0);
505*789Sahrens }
506*789Sahrens 
507*789Sahrens int
508*789Sahrens zap_entry_update(zap_entry_handle_t *zeh,
509*789Sahrens 	uint8_t integer_size, uint64_t num_integers, const void *buf)
510*789Sahrens {
511*789Sahrens 	int delta_chunks;
512*789Sahrens 	struct zap_leaf_entry *le;
513*789Sahrens 	le = &zeh->zeh_found_leaf->l_phys->l_chunk[*zeh->zeh_chunkp].l_entry;
514*789Sahrens 
515*789Sahrens 	delta_chunks = NCHUNKS(num_integers * integer_size) -
516*789Sahrens 	    NCHUNKS(le->le_value_length * le->le_int_size);
517*789Sahrens 
518*789Sahrens 	if (zeh->zeh_found_leaf->lh_nfree < delta_chunks)
519*789Sahrens 		return (EAGAIN);
520*789Sahrens 
521*789Sahrens 	/*
522*789Sahrens 	 * We should search other chained leaves (via
523*789Sahrens 	 * zap_entry_remove,create?) otherwise returning EAGAIN will
524*789Sahrens 	 * just send us into an infinite loop if we have to chain
525*789Sahrens 	 * another leaf block, rather than being able to split this
526*789Sahrens 	 * block.
527*789Sahrens 	 */
528*789Sahrens 
529*789Sahrens 	zap_leaf_array_free(zeh, &le->le_value_chunk);
530*789Sahrens 	le->le_value_chunk =
531*789Sahrens 	    zap_leaf_array_create(zeh, buf, integer_size, num_integers);
532*789Sahrens 	le->le_value_length = (num_integers*integer_size > MAX_ARRAY_BYTES) ?
533*789Sahrens 	    (MAX_ARRAY_BYTES + 1) : (num_integers);
534*789Sahrens 	le->le_int_size = integer_size;
535*789Sahrens 	return (0);
536*789Sahrens }
537*789Sahrens 
538*789Sahrens void
539*789Sahrens zap_entry_remove(zap_entry_handle_t *zeh)
540*789Sahrens {
541*789Sahrens 	uint16_t entry_chunk;
542*789Sahrens 	struct zap_leaf_entry *le;
543*789Sahrens 	zap_leaf_t *l = zeh->zeh_found_leaf;
544*789Sahrens 
545*789Sahrens 	ASSERT3P(zeh->zeh_chunkp, !=, &zeh->zeh_fakechunk);
546*789Sahrens 
547*789Sahrens 	entry_chunk = *zeh->zeh_chunkp;
548*789Sahrens 	le = &l->l_phys->l_chunk[entry_chunk].l_entry;
549*789Sahrens 	ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY);
550*789Sahrens 
551*789Sahrens 	zap_leaf_array_free(zeh, &le->le_name_chunk);
552*789Sahrens 	zap_leaf_array_free(zeh, &le->le_value_chunk);
553*789Sahrens 
554*789Sahrens 	*zeh->zeh_chunkp = le->le_next;
555*789Sahrens 	zap_leaf_chunk_free(l, entry_chunk);
556*789Sahrens 
557*789Sahrens 	l->lh_nentries--;
558*789Sahrens }
559*789Sahrens 
560*789Sahrens int
561*789Sahrens zap_entry_create(zap_leaf_t *l, const char *name, uint64_t h, uint32_t cd,
562*789Sahrens     uint8_t integer_size, uint64_t num_integers, const void *buf,
563*789Sahrens     zap_entry_handle_t *zeh)
564*789Sahrens {
565*789Sahrens 	uint16_t chunk;
566*789Sahrens 	uint16_t *chunkp;
567*789Sahrens 	struct zap_leaf_entry *le;
568*789Sahrens 	uint64_t namelen, valuelen;
569*789Sahrens 	int numchunks;
570*789Sahrens 
571*789Sahrens 	valuelen = integer_size * num_integers;
572*789Sahrens 	namelen = strlen(name) + 1;
573*789Sahrens 	ASSERT(namelen >= 2);
574*789Sahrens 
575*789Sahrens 	zeh->zeh_head_leaf = l;
576*789Sahrens 
577*789Sahrens 	if (namelen > MAXNAMELEN)
578*789Sahrens 		return (ENAMETOOLONG);
579*789Sahrens 	/* find the first leaf in the chain that has sufficient free space */
580*789Sahrens 	numchunks = 1 + NCHUNKS(namelen) + NCHUNKS(valuelen);
581*789Sahrens 	if (numchunks > ZAP_LEAF_NUMCHUNKS)
582*789Sahrens 		return (E2BIG);
583*789Sahrens 
584*789Sahrens 	if (cd == ZAP_MAXCD) {
585*789Sahrens 		for (cd = 0; cd < ZAP_MAXCD; cd++) {
586*789Sahrens 			zap_leaf_t *ll;
587*789Sahrens 			for (ll = l; ll; ll = ll->l_next) {
588*789Sahrens 				for (chunk = *LEAF_HASH_ENTPTR(ll, h);
589*789Sahrens 				    chunk != CHAIN_END; chunk = le->le_next) {
590*789Sahrens 					le = &ll->l_phys->l_chunk
591*789Sahrens 					    [chunk].l_entry;
592*789Sahrens 					if (le->le_hash == h &&
593*789Sahrens 					    le->le_cd == cd) {
594*789Sahrens 						break;
595*789Sahrens 					}
596*789Sahrens 				}
597*789Sahrens 				/*
598*789Sahrens 				 * if this cd is in use, no need to
599*789Sahrens 				 * check more chained leafs
600*789Sahrens 				 */
601*789Sahrens 				if (chunk != CHAIN_END)
602*789Sahrens 					break;
603*789Sahrens 			}
604*789Sahrens 			/* If this cd is not in use, we are good. */
605*789Sahrens 			if (chunk == CHAIN_END)
606*789Sahrens 				break;
607*789Sahrens 		}
608*789Sahrens 		/* If we tried all the cd's, we lose. */
609*789Sahrens 		if (cd == ZAP_MAXCD)
610*789Sahrens 			return (ENOSPC);
611*789Sahrens 	}
612*789Sahrens 
613*789Sahrens 	for (; l; l = l->l_next)
614*789Sahrens 		if (l->lh_nfree >= numchunks)
615*789Sahrens 			break;
616*789Sahrens 	if (l == NULL)
617*789Sahrens 		return (EAGAIN);
618*789Sahrens 
619*789Sahrens 	zeh->zeh_found_leaf = l;
620*789Sahrens 
621*789Sahrens 	/* make the entry */
622*789Sahrens 	chunk = zap_leaf_chunk_alloc(l);
623*789Sahrens 	le = &l->l_phys->l_chunk[chunk].l_entry;
624*789Sahrens 	le->le_type = ZAP_LEAF_ENTRY;
625*789Sahrens 	le->le_name_chunk = zap_leaf_array_create(zeh, name, 1, namelen);
626*789Sahrens 	le->le_name_length = namelen;
627*789Sahrens 	le->le_value_chunk =
628*789Sahrens 	    zap_leaf_array_create(zeh, buf, integer_size, num_integers);
629*789Sahrens 	le->le_value_length = (num_integers*integer_size > MAX_ARRAY_BYTES) ?
630*789Sahrens 	    (MAX_ARRAY_BYTES + 1) : (num_integers);
631*789Sahrens 	le->le_int_size = integer_size;
632*789Sahrens 	le->le_hash = h;
633*789Sahrens 	le->le_cd = cd;
634*789Sahrens 
635*789Sahrens 	/* link it into the hash chain */
636*789Sahrens 	chunkp = LEAF_HASH_ENTPTR(l, h);
637*789Sahrens 	le->le_next = *chunkp;
638*789Sahrens 	*chunkp = chunk;
639*789Sahrens 
640*789Sahrens 	l->lh_nentries++;
641*789Sahrens 
642*789Sahrens 	zeh->zeh_num_integers = num_integers;
643*789Sahrens 	zeh->zeh_integer_size = le->le_int_size;
644*789Sahrens 	zeh->zeh_cd = le->le_cd;
645*789Sahrens 	zeh->zeh_hash = le->le_hash;
646*789Sahrens 	zeh->zeh_chunkp = chunkp;
647*789Sahrens 
648*789Sahrens 	return (0);
649*789Sahrens }
650*789Sahrens 
651*789Sahrens /*
652*789Sahrens  * Routines for transferring entries between leafs.
653*789Sahrens  */
654*789Sahrens 
655*789Sahrens static void
656*789Sahrens zap_leaf_rehash_entry(zap_leaf_t *l, uint16_t entry)
657*789Sahrens {
658*789Sahrens 	struct zap_leaf_entry *le = &l->l_phys->l_chunk[entry].l_entry;
659*789Sahrens 	uint16_t *ptr = LEAF_HASH_ENTPTR(l, le->le_hash);
660*789Sahrens 	le->le_next = *ptr;
661*789Sahrens 	*ptr = entry;
662*789Sahrens }
663*789Sahrens 
664*789Sahrens static void
665*789Sahrens zap_leaf_rehash_entries(zap_leaf_t *l)
666*789Sahrens {
667*789Sahrens 	int i;
668*789Sahrens 
669*789Sahrens 	if (l->lh_nentries == 0)
670*789Sahrens 		return;
671*789Sahrens 
672*789Sahrens 	/* break existing hash chains */
673*789Sahrens 	zap_memset(l->l_phys->l_hash, CHAIN_END, sizeof (l->l_phys->l_hash));
674*789Sahrens 
675*789Sahrens 	for (i = 0; i < ZAP_LEAF_NUMCHUNKS; i++) {
676*789Sahrens 		struct zap_leaf_entry *le = &l->l_phys->l_chunk[i].l_entry;
677*789Sahrens 		if (le->le_type != ZAP_LEAF_ENTRY)
678*789Sahrens 			continue;
679*789Sahrens 		zap_leaf_rehash_entry(l, i);
680*789Sahrens 	}
681*789Sahrens }
682*789Sahrens 
683*789Sahrens static uint16_t
684*789Sahrens zap_leaf_transfer_array(zap_leaf_t *l, uint16_t chunk, zap_leaf_t *nl)
685*789Sahrens {
686*789Sahrens 	uint16_t new_chunk;
687*789Sahrens 	uint16_t *nchunkp = &new_chunk;
688*789Sahrens 
689*789Sahrens 	while (chunk != CHAIN_END) {
690*789Sahrens 		uint16_t nchunk = zap_leaf_chunk_alloc(nl);
691*789Sahrens 		struct zap_leaf_array *nla =
692*789Sahrens 		    &nl->l_phys->l_chunk[nchunk].l_array;
693*789Sahrens 		struct zap_leaf_array *la =
694*789Sahrens 		    &l->l_phys->l_chunk[chunk].l_array;
695*789Sahrens 		int nextchunk = la->la_next;
696*789Sahrens 
697*789Sahrens 		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS);
698*789Sahrens 		ASSERT3U(nchunk, <, ZAP_LEAF_NUMCHUNKS);
699*789Sahrens 
700*789Sahrens 		*nla = *la;
701*789Sahrens 
702*789Sahrens 		zap_leaf_chunk_free(l, chunk);
703*789Sahrens 		chunk = nextchunk;
704*789Sahrens 		*nchunkp = nchunk;
705*789Sahrens 		nchunkp = &nla->la_next;
706*789Sahrens 	}
707*789Sahrens 	*nchunkp = CHAIN_END;
708*789Sahrens 	return (new_chunk);
709*789Sahrens }
710*789Sahrens 
711*789Sahrens static void
712*789Sahrens zap_leaf_transfer_entry(zap_t *zap, zap_leaf_t *l, int entry, zap_leaf_t *nhl,
713*789Sahrens     dmu_tx_t *tx)
714*789Sahrens {
715*789Sahrens 	zap_leaf_t *nl;
716*789Sahrens 	struct zap_leaf_entry *le, *nle;
717*789Sahrens 	uint16_t chunk, nchunks;
718*789Sahrens 
719*789Sahrens 	le = &l->l_phys->l_chunk[entry].l_entry;
720*789Sahrens 	ASSERT3U(le->le_type, ==, ZAP_LEAF_ENTRY);
721*789Sahrens 
722*789Sahrens 	/* find a leaf in the destination leaf chain with enough free space */
723*789Sahrens 	nchunks = 1 + NCHUNKS(le->le_name_length) +
724*789Sahrens 	    NCHUNKS(le->le_value_length * le->le_int_size);
725*789Sahrens 	for (nl = nhl; nl; nl = nl->l_next)
726*789Sahrens 		if (nl->lh_nfree >= nchunks)
727*789Sahrens 			break;
728*789Sahrens 	if (nl == NULL) {
729*789Sahrens 		nl = zap_leaf_chainmore(nhl, zap_create_leaf(zap, tx));
730*789Sahrens 		dprintf("transfer_entry: chaining leaf %x/%d\n",
731*789Sahrens 		    nl->lh_prefix, nl->lh_prefix_len);
732*789Sahrens 	}
733*789Sahrens 
734*789Sahrens 	chunk = zap_leaf_chunk_alloc(nl);
735*789Sahrens 	nle = &nl->l_phys->l_chunk[chunk].l_entry;
736*789Sahrens 	*nle = *le;
737*789Sahrens 
738*789Sahrens 	zap_leaf_rehash_entry(nl, chunk);
739*789Sahrens 
740*789Sahrens 	nle->le_name_chunk = zap_leaf_transfer_array(l, le->le_name_chunk, nl);
741*789Sahrens 	nle->le_value_chunk =
742*789Sahrens 	    zap_leaf_transfer_array(l, le->le_value_chunk, nl);
743*789Sahrens 
744*789Sahrens 	zap_leaf_chunk_free(l, entry);
745*789Sahrens 
746*789Sahrens 	l->lh_nentries--;
747*789Sahrens 	nl->lh_nentries++;
748*789Sahrens }
749*789Sahrens 
750*789Sahrens /*
751*789Sahrens  * Transfer entries whose hash bit 'bit' is 1 to nl1, and 0 to nl0.
752*789Sahrens  * Ignore leaf chaining in source (l), but chain in destinations.
753*789Sahrens  * We'll re-chain all the entries in l as we go along.
754*789Sahrens  */
755*789Sahrens static void
756*789Sahrens zap_leaf_transfer_entries(zap_t *zap, zap_leaf_t *l,
757*789Sahrens     zap_leaf_t *nl0, zap_leaf_t *nl1, int bit, dmu_tx_t *tx)
758*789Sahrens {
759*789Sahrens 	int i;
760*789Sahrens 
761*789Sahrens 	ASSERT(bit < 64 && bit >= 0);
762*789Sahrens 	/* break existing hash chains */
763*789Sahrens 	zap_memset(l->l_phys->l_hash, CHAIN_END, sizeof (l->l_phys->l_hash));
764*789Sahrens 
765*789Sahrens 	if (nl0 != l)
766*789Sahrens 		zap_leaf_rehash_entries(nl0);
767*789Sahrens 	if (nl1 != nl0)
768*789Sahrens 		zap_leaf_rehash_entries(nl1);
769*789Sahrens 
770*789Sahrens 	for (i = 0; i < ZAP_LEAF_NUMCHUNKS; i++) {
771*789Sahrens 		struct zap_leaf_entry *le = &l->l_phys->l_chunk[i].l_entry;
772*789Sahrens 		if (le->le_type != ZAP_LEAF_ENTRY)
773*789Sahrens 			continue;
774*789Sahrens 
775*789Sahrens 		/*
776*789Sahrens 		 * We could find entries via hashtable instead. That
777*789Sahrens 		 * would be O(hashents+numents) rather than
778*789Sahrens 		 * O(numblks+numents), but this accesses memory more
779*789Sahrens 		 * sequentially, and when we're called, the block is
780*789Sahrens 		 * usually pretty full.
781*789Sahrens 		 */
782*789Sahrens 
783*789Sahrens 		if (le->le_hash & (1ULL << bit)) {
784*789Sahrens 			zap_leaf_transfer_entry(zap, l, i, nl1, tx);
785*789Sahrens 		} else {
786*789Sahrens 			if (nl0 == l)
787*789Sahrens 				zap_leaf_rehash_entry(l, i);
788*789Sahrens 			else
789*789Sahrens 				zap_leaf_transfer_entry(zap, l, i, nl0, tx);
790*789Sahrens 		}
791*789Sahrens 	}
792*789Sahrens 
793*789Sahrens }
794*789Sahrens 
795*789Sahrens /*
796*789Sahrens  * nl will contain the entries whose hash prefix ends in 1
797*789Sahrens  * handles leaf chaining
798*789Sahrens  */
799*789Sahrens zap_leaf_t *
800*789Sahrens zap_leaf_split(zap_t *zap, zap_leaf_t *hl, dmu_tx_t *tx)
801*789Sahrens {
802*789Sahrens 	zap_leaf_t *l = hl;
803*789Sahrens 	int bit = 64 - 1 - hl->lh_prefix_len;
804*789Sahrens 	zap_leaf_t *nl = zap_create_leaf(zap, tx);
805*789Sahrens 
806*789Sahrens 	/* set new prefix and prefix_len */
807*789Sahrens 	hl->lh_prefix <<= 1;
808*789Sahrens 	hl->lh_prefix_len++;
809*789Sahrens 	nl->lh_prefix = hl->lh_prefix | 1;
810*789Sahrens 	nl->lh_prefix_len = hl->lh_prefix_len;
811*789Sahrens 
812*789Sahrens 	/* transfer odd entries from first leaf in hl chain to nl */
813*789Sahrens 	zap_leaf_transfer_entries(zap, hl, hl, nl, bit, tx);
814*789Sahrens 
815*789Sahrens 	/* take rest of chain off hl */
816*789Sahrens 	l = hl->l_next;
817*789Sahrens 	hl->l_next = NULL;
818*789Sahrens 	hl->lh_next = 0;
819*789Sahrens 
820*789Sahrens 	/* transfer even entries from hl chain back to hl, odd entries to nl */
821*789Sahrens 	while (l) {
822*789Sahrens 		zap_leaf_t *next = l->l_next;
823*789Sahrens 		zap_leaf_transfer_entries(zap, l, hl, nl, bit, tx);
824*789Sahrens 		zap_destroy_leaf(zap, l, tx);
825*789Sahrens 		l = next;
826*789Sahrens 	}
827*789Sahrens 
828*789Sahrens 	return (nl);
829*789Sahrens }
830*789Sahrens 
831*789Sahrens void
832*789Sahrens zap_stats_leaf(zap_t *zap, zap_leaf_t *l, zap_stats_t *zs)
833*789Sahrens {
834*789Sahrens 	int n, nchained = 0;
835*789Sahrens 
836*789Sahrens 	n = zap->zap_f.zap_phys->zap_ptrtbl.zt_shift - l->lh_prefix_len;
837*789Sahrens 	n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
838*789Sahrens 	zs->zs_leafs_with_2n_pointers[n]++;
839*789Sahrens 
840*789Sahrens 	do {
841*789Sahrens 		int i;
842*789Sahrens 
843*789Sahrens 		n = l->lh_nentries/5;
844*789Sahrens 		n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
845*789Sahrens 		zs->zs_blocks_with_n5_entries[n]++;
846*789Sahrens 
847*789Sahrens 		n = ((1<<ZAP_BLOCK_SHIFT) -
848*789Sahrens 		    l->lh_nfree * (ZAP_LEAF_ARRAY_BYTES+1))*10 /
849*789Sahrens 		    (1<<ZAP_BLOCK_SHIFT);
850*789Sahrens 		n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
851*789Sahrens 		zs->zs_blocks_n_tenths_full[n]++;
852*789Sahrens 
853*789Sahrens 		for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES; i++) {
854*789Sahrens 			int nentries = 0;
855*789Sahrens 			int chunk = l->l_phys->l_hash[i];
856*789Sahrens 
857*789Sahrens 			while (chunk != CHAIN_END) {
858*789Sahrens 				struct zap_leaf_entry *le =
859*789Sahrens 				    &l->l_phys->l_chunk[chunk].l_entry;
860*789Sahrens 
861*789Sahrens 				n = 1 + NCHUNKS(le->le_name_length) +
862*789Sahrens 				    NCHUNKS(le->le_value_length *
863*789Sahrens 					le->le_int_size);
864*789Sahrens 				n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
865*789Sahrens 				zs->zs_entries_using_n_chunks[n]++;
866*789Sahrens 
867*789Sahrens 				chunk = le->le_next;
868*789Sahrens 				nentries++;
869*789Sahrens 			}
870*789Sahrens 
871*789Sahrens 			n = nentries;
872*789Sahrens 			n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
873*789Sahrens 			zs->zs_buckets_with_n_entries[n]++;
874*789Sahrens 		}
875*789Sahrens 
876*789Sahrens 		nchained++;
877*789Sahrens 		l = l->l_next;
878*789Sahrens 	} while (l);
879*789Sahrens 
880*789Sahrens 	n = nchained-1;
881*789Sahrens 	n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
882*789Sahrens 	zs->zs_leafs_with_n_chained[n]++;
883*789Sahrens }
884