xref: /titanic_51/usr/src/uts/common/fs/zfs/zap_micro.c (revision b8201470142151ac3303d2d0b875fc282299de45)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/spa.h>
27 #include <sys/dmu.h>
28 #include <sys/zfs_context.h>
29 #include <sys/zap.h>
30 #include <sys/refcount.h>
31 #include <sys/zap_impl.h>
32 #include <sys/zap_leaf.h>
33 #include <sys/avl.h>
34 
35 #ifdef _KERNEL
36 #include <sys/sunddi.h>
37 #endif
38 
39 static int mzap_upgrade(zap_t **zapp, dmu_tx_t *tx);
40 
41 
42 static uint64_t
43 zap_hash(zap_t *zap, const char *normname)
44 {
45 	const uint8_t *cp;
46 	uint8_t c;
47 	uint64_t crc = zap->zap_salt;
48 
49 	/* NB: name must already be normalized, if necessary */
50 
51 	ASSERT(crc != 0);
52 	ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);
53 	for (cp = (const uint8_t *)normname; (c = *cp) != '\0'; cp++) {
54 		crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ c) & 0xFF];
55 	}
56 
57 	/*
58 	 * Only use 28 bits, since we need 4 bits in the cookie for the
59 	 * collision differentiator.  We MUST use the high bits, since
60 	 * those are the ones that we first pay attention to when
61 	 * chosing the bucket.
62 	 */
63 	crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1);
64 
65 	return (crc);
66 }
67 
68 static int
69 zap_normalize(zap_t *zap, const char *name, char *namenorm)
70 {
71 	size_t inlen, outlen;
72 	int err;
73 
74 	inlen = strlen(name) + 1;
75 	outlen = ZAP_MAXNAMELEN;
76 
77 	err = 0;
78 	(void) u8_textprep_str((char *)name, &inlen, namenorm, &outlen,
79 	    zap->zap_normflags | U8_TEXTPREP_IGNORE_NULL |
80 	    U8_TEXTPREP_IGNORE_INVALID, U8_UNICODE_LATEST, &err);
81 
82 	return (err);
83 }
84 
85 boolean_t
86 zap_match(zap_name_t *zn, const char *matchname)
87 {
88 	if (zn->zn_matchtype == MT_FIRST) {
89 		char norm[ZAP_MAXNAMELEN];
90 
91 		if (zap_normalize(zn->zn_zap, matchname, norm) != 0)
92 			return (B_FALSE);
93 
94 		return (strcmp(zn->zn_name_norm, norm) == 0);
95 	} else {
96 		/* MT_BEST or MT_EXACT */
97 		return (strcmp(zn->zn_name_orij, matchname) == 0);
98 	}
99 }
100 
101 void
102 zap_name_free(zap_name_t *zn)
103 {
104 	kmem_free(zn, sizeof (zap_name_t));
105 }
106 
107 /* XXX combine this with zap_lockdir()? */
108 zap_name_t *
109 zap_name_alloc(zap_t *zap, const char *name, matchtype_t mt)
110 {
111 	zap_name_t *zn = kmem_alloc(sizeof (zap_name_t), KM_SLEEP);
112 
113 	zn->zn_zap = zap;
114 	zn->zn_name_orij = name;
115 	zn->zn_matchtype = mt;
116 	if (zap->zap_normflags) {
117 		if (zap_normalize(zap, name, zn->zn_normbuf) != 0) {
118 			zap_name_free(zn);
119 			return (NULL);
120 		}
121 		zn->zn_name_norm = zn->zn_normbuf;
122 	} else {
123 		if (mt != MT_EXACT) {
124 			zap_name_free(zn);
125 			return (NULL);
126 		}
127 		zn->zn_name_norm = zn->zn_name_orij;
128 	}
129 
130 	zn->zn_hash = zap_hash(zap, zn->zn_name_norm);
131 	return (zn);
132 }
133 
134 static void
135 mzap_byteswap(mzap_phys_t *buf, size_t size)
136 {
137 	int i, max;
138 	buf->mz_block_type = BSWAP_64(buf->mz_block_type);
139 	buf->mz_salt = BSWAP_64(buf->mz_salt);
140 	buf->mz_normflags = BSWAP_64(buf->mz_normflags);
141 	max = (size / MZAP_ENT_LEN) - 1;
142 	for (i = 0; i < max; i++) {
143 		buf->mz_chunk[i].mze_value =
144 		    BSWAP_64(buf->mz_chunk[i].mze_value);
145 		buf->mz_chunk[i].mze_cd =
146 		    BSWAP_32(buf->mz_chunk[i].mze_cd);
147 	}
148 }
149 
150 void
151 zap_byteswap(void *buf, size_t size)
152 {
153 	uint64_t block_type;
154 
155 	block_type = *(uint64_t *)buf;
156 
157 	if (block_type == ZBT_MICRO || block_type == BSWAP_64(ZBT_MICRO)) {
158 		/* ASSERT(magic == ZAP_LEAF_MAGIC); */
159 		mzap_byteswap(buf, size);
160 	} else {
161 		fzap_byteswap(buf, size);
162 	}
163 }
164 
165 static int
166 mze_compare(const void *arg1, const void *arg2)
167 {
168 	const mzap_ent_t *mze1 = arg1;
169 	const mzap_ent_t *mze2 = arg2;
170 
171 	if (mze1->mze_hash > mze2->mze_hash)
172 		return (+1);
173 	if (mze1->mze_hash < mze2->mze_hash)
174 		return (-1);
175 	if (mze1->mze_phys.mze_cd > mze2->mze_phys.mze_cd)
176 		return (+1);
177 	if (mze1->mze_phys.mze_cd < mze2->mze_phys.mze_cd)
178 		return (-1);
179 	return (0);
180 }
181 
182 static void
183 mze_insert(zap_t *zap, int chunkid, uint64_t hash, mzap_ent_phys_t *mzep)
184 {
185 	mzap_ent_t *mze;
186 
187 	ASSERT(zap->zap_ismicro);
188 	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
189 	ASSERT(mzep->mze_cd < ZAP_MAXCD);
190 
191 	mze = kmem_alloc(sizeof (mzap_ent_t), KM_SLEEP);
192 	mze->mze_chunkid = chunkid;
193 	mze->mze_hash = hash;
194 	mze->mze_phys = *mzep;
195 	avl_add(&zap->zap_m.zap_avl, mze);
196 }
197 
198 static mzap_ent_t *
199 mze_find(zap_name_t *zn)
200 {
201 	mzap_ent_t mze_tofind;
202 	mzap_ent_t *mze;
203 	avl_index_t idx;
204 	avl_tree_t *avl = &zn->zn_zap->zap_m.zap_avl;
205 
206 	ASSERT(zn->zn_zap->zap_ismicro);
207 	ASSERT(RW_LOCK_HELD(&zn->zn_zap->zap_rwlock));
208 
209 	if (strlen(zn->zn_name_norm) >= sizeof (mze_tofind.mze_phys.mze_name))
210 		return (NULL);
211 
212 	mze_tofind.mze_hash = zn->zn_hash;
213 	mze_tofind.mze_phys.mze_cd = 0;
214 
215 again:
216 	mze = avl_find(avl, &mze_tofind, &idx);
217 	if (mze == NULL)
218 		mze = avl_nearest(avl, idx, AVL_AFTER);
219 	for (; mze && mze->mze_hash == zn->zn_hash; mze = AVL_NEXT(avl, mze)) {
220 		if (zap_match(zn, mze->mze_phys.mze_name))
221 			return (mze);
222 	}
223 	if (zn->zn_matchtype == MT_BEST) {
224 		zn->zn_matchtype = MT_FIRST;
225 		goto again;
226 	}
227 	return (NULL);
228 }
229 
230 static uint32_t
231 mze_find_unused_cd(zap_t *zap, uint64_t hash)
232 {
233 	mzap_ent_t mze_tofind;
234 	mzap_ent_t *mze;
235 	avl_index_t idx;
236 	avl_tree_t *avl = &zap->zap_m.zap_avl;
237 	uint32_t cd;
238 
239 	ASSERT(zap->zap_ismicro);
240 	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
241 
242 	mze_tofind.mze_hash = hash;
243 	mze_tofind.mze_phys.mze_cd = 0;
244 
245 	cd = 0;
246 	for (mze = avl_find(avl, &mze_tofind, &idx);
247 	    mze && mze->mze_hash == hash; mze = AVL_NEXT(avl, mze)) {
248 		if (mze->mze_phys.mze_cd != cd)
249 			break;
250 		cd++;
251 	}
252 
253 	return (cd);
254 }
255 
256 static void
257 mze_remove(zap_t *zap, mzap_ent_t *mze)
258 {
259 	ASSERT(zap->zap_ismicro);
260 	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
261 
262 	avl_remove(&zap->zap_m.zap_avl, mze);
263 	kmem_free(mze, sizeof (mzap_ent_t));
264 }
265 
266 static void
267 mze_destroy(zap_t *zap)
268 {
269 	mzap_ent_t *mze;
270 	void *avlcookie = NULL;
271 
272 	while (mze = avl_destroy_nodes(&zap->zap_m.zap_avl, &avlcookie))
273 		kmem_free(mze, sizeof (mzap_ent_t));
274 	avl_destroy(&zap->zap_m.zap_avl);
275 }
276 
277 static zap_t *
278 mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
279 {
280 	zap_t *winner;
281 	zap_t *zap;
282 	int i;
283 
284 	ASSERT3U(MZAP_ENT_LEN, ==, sizeof (mzap_ent_phys_t));
285 
286 	zap = kmem_zalloc(sizeof (zap_t), KM_SLEEP);
287 	rw_init(&zap->zap_rwlock, 0, 0, 0);
288 	rw_enter(&zap->zap_rwlock, RW_WRITER);
289 	zap->zap_objset = os;
290 	zap->zap_object = obj;
291 	zap->zap_dbuf = db;
292 
293 	if (*(uint64_t *)db->db_data != ZBT_MICRO) {
294 		mutex_init(&zap->zap_f.zap_num_entries_mtx, 0, 0, 0);
295 		zap->zap_f.zap_block_shift = highbit(db->db_size) - 1;
296 	} else {
297 		zap->zap_ismicro = TRUE;
298 	}
299 
300 	/*
301 	 * Make sure that zap_ismicro is set before we let others see
302 	 * it, because zap_lockdir() checks zap_ismicro without the lock
303 	 * held.
304 	 */
305 	winner = dmu_buf_set_user(db, zap, &zap->zap_m.zap_phys, zap_evict);
306 
307 	if (winner != NULL) {
308 		rw_exit(&zap->zap_rwlock);
309 		rw_destroy(&zap->zap_rwlock);
310 		if (!zap->zap_ismicro)
311 			mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
312 		kmem_free(zap, sizeof (zap_t));
313 		return (winner);
314 	}
315 
316 	if (zap->zap_ismicro) {
317 		zap->zap_salt = zap->zap_m.zap_phys->mz_salt;
318 		zap->zap_normflags = zap->zap_m.zap_phys->mz_normflags;
319 		zap->zap_m.zap_num_chunks = db->db_size / MZAP_ENT_LEN - 1;
320 		avl_create(&zap->zap_m.zap_avl, mze_compare,
321 		    sizeof (mzap_ent_t), offsetof(mzap_ent_t, mze_node));
322 
323 		for (i = 0; i < zap->zap_m.zap_num_chunks; i++) {
324 			mzap_ent_phys_t *mze =
325 			    &zap->zap_m.zap_phys->mz_chunk[i];
326 			if (mze->mze_name[0]) {
327 				zap_name_t *zn;
328 
329 				zap->zap_m.zap_num_entries++;
330 				zn = zap_name_alloc(zap, mze->mze_name,
331 				    MT_EXACT);
332 				mze_insert(zap, i, zn->zn_hash, mze);
333 				zap_name_free(zn);
334 			}
335 		}
336 	} else {
337 		zap->zap_salt = zap->zap_f.zap_phys->zap_salt;
338 		zap->zap_normflags = zap->zap_f.zap_phys->zap_normflags;
339 
340 		ASSERT3U(sizeof (struct zap_leaf_header), ==,
341 		    2*ZAP_LEAF_CHUNKSIZE);
342 
343 		/*
344 		 * The embedded pointer table should not overlap the
345 		 * other members.
346 		 */
347 		ASSERT3P(&ZAP_EMBEDDED_PTRTBL_ENT(zap, 0), >,
348 		    &zap->zap_f.zap_phys->zap_salt);
349 
350 		/*
351 		 * The embedded pointer table should end at the end of
352 		 * the block
353 		 */
354 		ASSERT3U((uintptr_t)&ZAP_EMBEDDED_PTRTBL_ENT(zap,
355 		    1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap)) -
356 		    (uintptr_t)zap->zap_f.zap_phys, ==,
357 		    zap->zap_dbuf->db_size);
358 	}
359 	rw_exit(&zap->zap_rwlock);
360 	return (zap);
361 }
362 
363 int
364 zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
365     krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp)
366 {
367 	zap_t *zap;
368 	dmu_buf_t *db;
369 	krw_t lt;
370 	int err;
371 
372 	*zapp = NULL;
373 
374 	err = dmu_buf_hold(os, obj, 0, NULL, &db);
375 	if (err)
376 		return (err);
377 
378 #ifdef ZFS_DEBUG
379 	{
380 		dmu_object_info_t doi;
381 		dmu_object_info_from_db(db, &doi);
382 		ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
383 	}
384 #endif
385 
386 	zap = dmu_buf_get_user(db);
387 	if (zap == NULL)
388 		zap = mzap_open(os, obj, db);
389 
390 	/*
391 	 * We're checking zap_ismicro without the lock held, in order to
392 	 * tell what type of lock we want.  Once we have some sort of
393 	 * lock, see if it really is the right type.  In practice this
394 	 * can only be different if it was upgraded from micro to fat,
395 	 * and micro wanted WRITER but fat only needs READER.
396 	 */
397 	lt = (!zap->zap_ismicro && fatreader) ? RW_READER : lti;
398 	rw_enter(&zap->zap_rwlock, lt);
399 	if (lt != ((!zap->zap_ismicro && fatreader) ? RW_READER : lti)) {
400 		/* it was upgraded, now we only need reader */
401 		ASSERT(lt == RW_WRITER);
402 		ASSERT(RW_READER ==
403 		    (!zap->zap_ismicro && fatreader) ? RW_READER : lti);
404 		rw_downgrade(&zap->zap_rwlock);
405 		lt = RW_READER;
406 	}
407 
408 	zap->zap_objset = os;
409 
410 	if (lt == RW_WRITER)
411 		dmu_buf_will_dirty(db, tx);
412 
413 	ASSERT3P(zap->zap_dbuf, ==, db);
414 
415 	ASSERT(!zap->zap_ismicro ||
416 	    zap->zap_m.zap_num_entries <= zap->zap_m.zap_num_chunks);
417 	if (zap->zap_ismicro && tx && adding &&
418 	    zap->zap_m.zap_num_entries == zap->zap_m.zap_num_chunks) {
419 		uint64_t newsz = db->db_size + SPA_MINBLOCKSIZE;
420 		if (newsz > MZAP_MAX_BLKSZ) {
421 			dprintf("upgrading obj %llu: num_entries=%u\n",
422 			    obj, zap->zap_m.zap_num_entries);
423 			*zapp = zap;
424 			return (mzap_upgrade(zapp, tx));
425 		}
426 		err = dmu_object_set_blocksize(os, obj, newsz, 0, tx);
427 		ASSERT3U(err, ==, 0);
428 		zap->zap_m.zap_num_chunks =
429 		    db->db_size / MZAP_ENT_LEN - 1;
430 	}
431 
432 	*zapp = zap;
433 	return (0);
434 }
435 
436 void
437 zap_unlockdir(zap_t *zap)
438 {
439 	rw_exit(&zap->zap_rwlock);
440 	dmu_buf_rele(zap->zap_dbuf, NULL);
441 }
442 
443 static int
444 mzap_upgrade(zap_t **zapp, dmu_tx_t *tx)
445 {
446 	mzap_phys_t *mzp;
447 	int i, sz, nchunks, err;
448 	zap_t *zap = *zapp;
449 
450 	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
451 
452 	sz = zap->zap_dbuf->db_size;
453 	mzp = kmem_alloc(sz, KM_SLEEP);
454 	bcopy(zap->zap_dbuf->db_data, mzp, sz);
455 	nchunks = zap->zap_m.zap_num_chunks;
456 
457 	err = dmu_object_set_blocksize(zap->zap_objset, zap->zap_object,
458 	    1ULL << fzap_default_block_shift, 0, tx);
459 	if (err) {
460 		kmem_free(mzp, sz);
461 		return (err);
462 	}
463 
464 	dprintf("upgrading obj=%llu with %u chunks\n",
465 	    zap->zap_object, nchunks);
466 	/* XXX destroy the avl later, so we can use the stored hash value */
467 	mze_destroy(zap);
468 
469 	fzap_upgrade(zap, tx);
470 
471 	for (i = 0; i < nchunks; i++) {
472 		int err;
473 		mzap_ent_phys_t *mze = &mzp->mz_chunk[i];
474 		zap_name_t *zn;
475 		if (mze->mze_name[0] == 0)
476 			continue;
477 		dprintf("adding %s=%llu\n",
478 		    mze->mze_name, mze->mze_value);
479 		zn = zap_name_alloc(zap, mze->mze_name, MT_EXACT);
480 		err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd, tx);
481 		zap = zn->zn_zap;	/* fzap_add_cd() may change zap */
482 		zap_name_free(zn);
483 		if (err)
484 			break;
485 	}
486 	kmem_free(mzp, sz);
487 	*zapp = zap;
488 	return (err);
489 }
490 
491 static void
492 mzap_create_impl(objset_t *os, uint64_t obj, int normflags, dmu_tx_t *tx)
493 {
494 	dmu_buf_t *db;
495 	mzap_phys_t *zp;
496 
497 	VERIFY(0 == dmu_buf_hold(os, obj, 0, FTAG, &db));
498 
499 #ifdef ZFS_DEBUG
500 	{
501 		dmu_object_info_t doi;
502 		dmu_object_info_from_db(db, &doi);
503 		ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
504 	}
505 #endif
506 
507 	dmu_buf_will_dirty(db, tx);
508 	zp = db->db_data;
509 	zp->mz_block_type = ZBT_MICRO;
510 	zp->mz_salt = ((uintptr_t)db ^ (uintptr_t)tx ^ (obj << 1)) | 1ULL;
511 	zp->mz_normflags = normflags;
512 	dmu_buf_rele(db, FTAG);
513 }
514 
515 int
516 zap_create_claim(objset_t *os, uint64_t obj, dmu_object_type_t ot,
517     dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
518 {
519 	return (zap_create_claim_norm(os, obj,
520 	    0, ot, bonustype, bonuslen, tx));
521 }
522 
523 int
524 zap_create_claim_norm(objset_t *os, uint64_t obj, int normflags,
525     dmu_object_type_t ot,
526     dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
527 {
528 	int err;
529 
530 	err = dmu_object_claim(os, obj, ot, 0, bonustype, bonuslen, tx);
531 	if (err != 0)
532 		return (err);
533 	mzap_create_impl(os, obj, normflags, tx);
534 	return (0);
535 }
536 
537 uint64_t
538 zap_create(objset_t *os, dmu_object_type_t ot,
539     dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
540 {
541 	return (zap_create_norm(os, 0, ot, bonustype, bonuslen, tx));
542 }
543 
544 uint64_t
545 zap_create_norm(objset_t *os, int normflags, dmu_object_type_t ot,
546     dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
547 {
548 	uint64_t obj = dmu_object_alloc(os, ot, 0, bonustype, bonuslen, tx);
549 
550 	mzap_create_impl(os, obj, normflags, tx);
551 	return (obj);
552 }
553 
554 int
555 zap_destroy(objset_t *os, uint64_t zapobj, dmu_tx_t *tx)
556 {
557 	/*
558 	 * dmu_object_free will free the object number and free the
559 	 * data.  Freeing the data will cause our pageout function to be
560 	 * called, which will destroy our data (zap_leaf_t's and zap_t).
561 	 */
562 
563 	return (dmu_object_free(os, zapobj, tx));
564 }
565 
566 _NOTE(ARGSUSED(0))
567 void
568 zap_evict(dmu_buf_t *db, void *vzap)
569 {
570 	zap_t *zap = vzap;
571 
572 	rw_destroy(&zap->zap_rwlock);
573 
574 	if (zap->zap_ismicro)
575 		mze_destroy(zap);
576 	else
577 		mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
578 
579 	kmem_free(zap, sizeof (zap_t));
580 }
581 
582 int
583 zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
584 {
585 	zap_t *zap;
586 	int err;
587 
588 	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
589 	if (err)
590 		return (err);
591 	if (!zap->zap_ismicro) {
592 		err = fzap_count(zap, count);
593 	} else {
594 		*count = zap->zap_m.zap_num_entries;
595 	}
596 	zap_unlockdir(zap);
597 	return (err);
598 }
599 
600 /*
601  * zn may be NULL; if not specified, it will be computed if needed.
602  * See also the comment above zap_entry_normalization_conflict().
603  */
604 static boolean_t
605 mzap_normalization_conflict(zap_t *zap, zap_name_t *zn, mzap_ent_t *mze)
606 {
607 	mzap_ent_t *other;
608 	int direction = AVL_BEFORE;
609 	boolean_t allocdzn = B_FALSE;
610 
611 	if (zap->zap_normflags == 0)
612 		return (B_FALSE);
613 
614 again:
615 	for (other = avl_walk(&zap->zap_m.zap_avl, mze, direction);
616 	    other && other->mze_hash == mze->mze_hash;
617 	    other = avl_walk(&zap->zap_m.zap_avl, other, direction)) {
618 
619 		if (zn == NULL) {
620 			zn = zap_name_alloc(zap, mze->mze_phys.mze_name,
621 			    MT_FIRST);
622 			allocdzn = B_TRUE;
623 		}
624 		if (zap_match(zn, other->mze_phys.mze_name)) {
625 			if (allocdzn)
626 				zap_name_free(zn);
627 			return (B_TRUE);
628 		}
629 	}
630 
631 	if (direction == AVL_BEFORE) {
632 		direction = AVL_AFTER;
633 		goto again;
634 	}
635 
636 	if (allocdzn)
637 		zap_name_free(zn);
638 	return (B_FALSE);
639 }
640 
641 /*
642  * Routines for manipulating attributes.
643  */
644 
645 int
646 zap_lookup(objset_t *os, uint64_t zapobj, const char *name,
647     uint64_t integer_size, uint64_t num_integers, void *buf)
648 {
649 	return (zap_lookup_norm(os, zapobj, name, integer_size,
650 	    num_integers, buf, MT_EXACT, NULL, 0, NULL));
651 }
652 
653 int
654 zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
655     uint64_t integer_size, uint64_t num_integers, void *buf,
656     matchtype_t mt, char *realname, int rn_len,
657     boolean_t *ncp)
658 {
659 	zap_t *zap;
660 	int err;
661 	mzap_ent_t *mze;
662 	zap_name_t *zn;
663 
664 	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
665 	if (err)
666 		return (err);
667 	zn = zap_name_alloc(zap, name, mt);
668 	if (zn == NULL) {
669 		zap_unlockdir(zap);
670 		return (ENOTSUP);
671 	}
672 
673 	if (!zap->zap_ismicro) {
674 		err = fzap_lookup(zn, integer_size, num_integers, buf,
675 		    realname, rn_len, ncp);
676 	} else {
677 		mze = mze_find(zn);
678 		if (mze == NULL) {
679 			err = ENOENT;
680 		} else {
681 			if (num_integers < 1) {
682 				err = EOVERFLOW;
683 			} else if (integer_size != 8) {
684 				err = EINVAL;
685 			} else {
686 				*(uint64_t *)buf = mze->mze_phys.mze_value;
687 				(void) strlcpy(realname,
688 				    mze->mze_phys.mze_name, rn_len);
689 				if (ncp) {
690 					*ncp = mzap_normalization_conflict(zap,
691 					    zn, mze);
692 				}
693 			}
694 		}
695 	}
696 	zap_name_free(zn);
697 	zap_unlockdir(zap);
698 	return (err);
699 }
700 
701 int
702 zap_length(objset_t *os, uint64_t zapobj, const char *name,
703     uint64_t *integer_size, uint64_t *num_integers)
704 {
705 	zap_t *zap;
706 	int err;
707 	mzap_ent_t *mze;
708 	zap_name_t *zn;
709 
710 	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
711 	if (err)
712 		return (err);
713 	zn = zap_name_alloc(zap, name, MT_EXACT);
714 	if (zn == NULL) {
715 		zap_unlockdir(zap);
716 		return (ENOTSUP);
717 	}
718 	if (!zap->zap_ismicro) {
719 		err = fzap_length(zn, integer_size, num_integers);
720 	} else {
721 		mze = mze_find(zn);
722 		if (mze == NULL) {
723 			err = ENOENT;
724 		} else {
725 			if (integer_size)
726 				*integer_size = 8;
727 			if (num_integers)
728 				*num_integers = 1;
729 		}
730 	}
731 	zap_name_free(zn);
732 	zap_unlockdir(zap);
733 	return (err);
734 }
735 
736 static void
737 mzap_addent(zap_name_t *zn, uint64_t value)
738 {
739 	int i;
740 	zap_t *zap = zn->zn_zap;
741 	int start = zap->zap_m.zap_alloc_next;
742 	uint32_t cd;
743 
744 	dprintf("obj=%llu %s=%llu\n", zap->zap_object,
745 	    zn->zn_name_orij, value);
746 	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
747 
748 #ifdef ZFS_DEBUG
749 	for (i = 0; i < zap->zap_m.zap_num_chunks; i++) {
750 		mzap_ent_phys_t *mze = &zap->zap_m.zap_phys->mz_chunk[i];
751 		ASSERT(strcmp(zn->zn_name_orij, mze->mze_name) != 0);
752 	}
753 #endif
754 
755 	cd = mze_find_unused_cd(zap, zn->zn_hash);
756 	/* given the limited size of the microzap, this can't happen */
757 	ASSERT(cd != ZAP_MAXCD);
758 
759 again:
760 	for (i = start; i < zap->zap_m.zap_num_chunks; i++) {
761 		mzap_ent_phys_t *mze = &zap->zap_m.zap_phys->mz_chunk[i];
762 		if (mze->mze_name[0] == 0) {
763 			mze->mze_value = value;
764 			mze->mze_cd = cd;
765 			(void) strcpy(mze->mze_name, zn->zn_name_orij);
766 			zap->zap_m.zap_num_entries++;
767 			zap->zap_m.zap_alloc_next = i+1;
768 			if (zap->zap_m.zap_alloc_next ==
769 			    zap->zap_m.zap_num_chunks)
770 				zap->zap_m.zap_alloc_next = 0;
771 			mze_insert(zap, i, zn->zn_hash, mze);
772 			return;
773 		}
774 	}
775 	if (start != 0) {
776 		start = 0;
777 		goto again;
778 	}
779 	ASSERT(!"out of entries!");
780 }
781 
782 int
783 zap_add(objset_t *os, uint64_t zapobj, const char *name,
784     int integer_size, uint64_t num_integers,
785     const void *val, dmu_tx_t *tx)
786 {
787 	zap_t *zap;
788 	int err;
789 	mzap_ent_t *mze;
790 	const uint64_t *intval = val;
791 	zap_name_t *zn;
792 
793 	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
794 	if (err)
795 		return (err);
796 	zn = zap_name_alloc(zap, name, MT_EXACT);
797 	if (zn == NULL) {
798 		zap_unlockdir(zap);
799 		return (ENOTSUP);
800 	}
801 	if (!zap->zap_ismicro) {
802 		err = fzap_add(zn, integer_size, num_integers, val, tx);
803 		zap = zn->zn_zap;	/* fzap_add() may change zap */
804 	} else if (integer_size != 8 || num_integers != 1 ||
805 	    strlen(name) >= MZAP_NAME_LEN) {
806 		dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
807 		    zapobj, integer_size, num_integers, name);
808 		err = mzap_upgrade(&zn->zn_zap, tx);
809 		if (err == 0)
810 			err = fzap_add(zn, integer_size, num_integers, val, tx);
811 		zap = zn->zn_zap;	/* fzap_add() may change zap */
812 	} else {
813 		mze = mze_find(zn);
814 		if (mze != NULL) {
815 			err = EEXIST;
816 		} else {
817 			mzap_addent(zn, *intval);
818 		}
819 	}
820 	ASSERT(zap == zn->zn_zap);
821 	zap_name_free(zn);
822 	if (zap != NULL)	/* may be NULL if fzap_add() failed */
823 		zap_unlockdir(zap);
824 	return (err);
825 }
826 
827 int
828 zap_update(objset_t *os, uint64_t zapobj, const char *name,
829     int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
830 {
831 	zap_t *zap;
832 	mzap_ent_t *mze;
833 	const uint64_t *intval = val;
834 	zap_name_t *zn;
835 	int err;
836 
837 	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
838 	if (err)
839 		return (err);
840 	zn = zap_name_alloc(zap, name, MT_EXACT);
841 	if (zn == NULL) {
842 		zap_unlockdir(zap);
843 		return (ENOTSUP);
844 	}
845 	if (!zap->zap_ismicro) {
846 		err = fzap_update(zn, integer_size, num_integers, val, tx);
847 		zap = zn->zn_zap;	/* fzap_update() may change zap */
848 	} else if (integer_size != 8 || num_integers != 1 ||
849 	    strlen(name) >= MZAP_NAME_LEN) {
850 		dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
851 		    zapobj, integer_size, num_integers, name);
852 		err = mzap_upgrade(&zn->zn_zap, tx);
853 		if (err == 0)
854 			err = fzap_update(zn, integer_size, num_integers,
855 			    val, tx);
856 		zap = zn->zn_zap;	/* fzap_update() may change zap */
857 	} else {
858 		mze = mze_find(zn);
859 		if (mze != NULL) {
860 			mze->mze_phys.mze_value = *intval;
861 			zap->zap_m.zap_phys->mz_chunk
862 			    [mze->mze_chunkid].mze_value = *intval;
863 		} else {
864 			mzap_addent(zn, *intval);
865 		}
866 	}
867 	ASSERT(zap == zn->zn_zap);
868 	zap_name_free(zn);
869 	if (zap != NULL)	/* may be NULL if fzap_upgrade() failed */
870 		zap_unlockdir(zap);
871 	return (err);
872 }
873 
874 int
875 zap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx)
876 {
877 	return (zap_remove_norm(os, zapobj, name, MT_EXACT, tx));
878 }
879 
880 int
881 zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
882     matchtype_t mt, dmu_tx_t *tx)
883 {
884 	zap_t *zap;
885 	int err;
886 	mzap_ent_t *mze;
887 	zap_name_t *zn;
888 
889 	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap);
890 	if (err)
891 		return (err);
892 	zn = zap_name_alloc(zap, name, mt);
893 	if (zn == NULL) {
894 		zap_unlockdir(zap);
895 		return (ENOTSUP);
896 	}
897 	if (!zap->zap_ismicro) {
898 		err = fzap_remove(zn, tx);
899 	} else {
900 		mze = mze_find(zn);
901 		if (mze == NULL) {
902 			err = ENOENT;
903 		} else {
904 			zap->zap_m.zap_num_entries--;
905 			bzero(&zap->zap_m.zap_phys->mz_chunk[mze->mze_chunkid],
906 			    sizeof (mzap_ent_phys_t));
907 			mze_remove(zap, mze);
908 		}
909 	}
910 	zap_name_free(zn);
911 	zap_unlockdir(zap);
912 	return (err);
913 }
914 
915 /*
916  * Routines for iterating over the attributes.
917  */
918 
919 /*
920  * We want to keep the high 32 bits of the cursor zero if we can, so
921  * that 32-bit programs can access this.  So use a small hash value so
922  * we can fit 4 bits of cd into the 32-bit cursor.
923  *
924  * [ 4 zero bits | 32-bit collision differentiator | 28-bit hash value ]
925  */
926 void
927 zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, uint64_t zapobj,
928     uint64_t serialized)
929 {
930 	zc->zc_objset = os;
931 	zc->zc_zap = NULL;
932 	zc->zc_leaf = NULL;
933 	zc->zc_zapobj = zapobj;
934 	if (serialized == -1ULL) {
935 		zc->zc_hash = -1ULL;
936 		zc->zc_cd = 0;
937 	} else {
938 		zc->zc_hash = serialized << (64-ZAP_HASHBITS);
939 		zc->zc_cd = serialized >> ZAP_HASHBITS;
940 		if (zc->zc_cd >= ZAP_MAXCD) /* corrupt serialized */
941 			zc->zc_cd = 0;
942 	}
943 }
944 
945 void
946 zap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj)
947 {
948 	zap_cursor_init_serialized(zc, os, zapobj, 0);
949 }
950 
951 void
952 zap_cursor_fini(zap_cursor_t *zc)
953 {
954 	if (zc->zc_zap) {
955 		rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
956 		zap_unlockdir(zc->zc_zap);
957 		zc->zc_zap = NULL;
958 	}
959 	if (zc->zc_leaf) {
960 		rw_enter(&zc->zc_leaf->l_rwlock, RW_READER);
961 		zap_put_leaf(zc->zc_leaf);
962 		zc->zc_leaf = NULL;
963 	}
964 	zc->zc_objset = NULL;
965 }
966 
967 uint64_t
968 zap_cursor_serialize(zap_cursor_t *zc)
969 {
970 	if (zc->zc_hash == -1ULL)
971 		return (-1ULL);
972 	ASSERT((zc->zc_hash & (ZAP_MAXCD-1)) == 0);
973 	ASSERT(zc->zc_cd < ZAP_MAXCD);
974 	return ((zc->zc_hash >> (64-ZAP_HASHBITS)) |
975 	    ((uint64_t)zc->zc_cd << ZAP_HASHBITS));
976 }
977 
978 int
979 zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
980 {
981 	int err;
982 	avl_index_t idx;
983 	mzap_ent_t mze_tofind;
984 	mzap_ent_t *mze;
985 
986 	if (zc->zc_hash == -1ULL)
987 		return (ENOENT);
988 
989 	if (zc->zc_zap == NULL) {
990 		err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
991 		    RW_READER, TRUE, FALSE, &zc->zc_zap);
992 		if (err)
993 			return (err);
994 	} else {
995 		rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
996 	}
997 	if (!zc->zc_zap->zap_ismicro) {
998 		err = fzap_cursor_retrieve(zc->zc_zap, zc, za);
999 	} else {
1000 		err = ENOENT;
1001 
1002 		mze_tofind.mze_hash = zc->zc_hash;
1003 		mze_tofind.mze_phys.mze_cd = zc->zc_cd;
1004 
1005 		mze = avl_find(&zc->zc_zap->zap_m.zap_avl, &mze_tofind, &idx);
1006 		if (mze == NULL) {
1007 			mze = avl_nearest(&zc->zc_zap->zap_m.zap_avl,
1008 			    idx, AVL_AFTER);
1009 		}
1010 		if (mze) {
1011 			ASSERT(0 == bcmp(&mze->mze_phys,
1012 			    &zc->zc_zap->zap_m.zap_phys->mz_chunk
1013 			    [mze->mze_chunkid], sizeof (mze->mze_phys)));
1014 
1015 			za->za_normalization_conflict =
1016 			    mzap_normalization_conflict(zc->zc_zap, NULL, mze);
1017 			za->za_integer_length = 8;
1018 			za->za_num_integers = 1;
1019 			za->za_first_integer = mze->mze_phys.mze_value;
1020 			(void) strcpy(za->za_name, mze->mze_phys.mze_name);
1021 			zc->zc_hash = mze->mze_hash;
1022 			zc->zc_cd = mze->mze_phys.mze_cd;
1023 			err = 0;
1024 		} else {
1025 			zc->zc_hash = -1ULL;
1026 		}
1027 	}
1028 	rw_exit(&zc->zc_zap->zap_rwlock);
1029 	return (err);
1030 }
1031 
1032 void
1033 zap_cursor_advance(zap_cursor_t *zc)
1034 {
1035 	if (zc->zc_hash == -1ULL)
1036 		return;
1037 	zc->zc_cd++;
1038 	if (zc->zc_cd >= ZAP_MAXCD) {
1039 		zc->zc_cd = 0;
1040 		zc->zc_hash += 1ULL<<(64-ZAP_HASHBITS);
1041 		if (zc->zc_hash == 0) /* EOF */
1042 			zc->zc_hash = -1ULL;
1043 	}
1044 }
1045 
1046 int
1047 zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
1048 {
1049 	int err;
1050 	zap_t *zap;
1051 
1052 	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
1053 	if (err)
1054 		return (err);
1055 
1056 	bzero(zs, sizeof (zap_stats_t));
1057 
1058 	if (zap->zap_ismicro) {
1059 		zs->zs_blocksize = zap->zap_dbuf->db_size;
1060 		zs->zs_num_entries = zap->zap_m.zap_num_entries;
1061 		zs->zs_num_blocks = 1;
1062 	} else {
1063 		fzap_get_stats(zap, zs);
1064 	}
1065 	zap_unlockdir(zap);
1066 	return (0);
1067 }
1068