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