1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * This file and its contents are supplied under the terms of the
4 * Common Development and Distribution License ("CDDL"), version 1.0.
5 * You may only use this file in accordance with the terms of version
6 * 1.0 of the CDDL.
7 *
8 * A full copy of the text of the CDDL should have accompanied this
9 * source. A copy of the CDDL is also available via the Internet at
10 * https://opensource.org/license/CDDL-1.0.
11 */
12
13 /*
14 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
15 * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
16 * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
17 * Copyright 2017 Nexenta Systems, Inc.
18 * Copyright (c) 2024, Klara, Inc.
19 * Copyright (c) 2026, TrueNAS.
20 */
21
22 #include <sys/zfs_context.h>
23 #include <sys/dmu.h>
24 #include <sys/dnode.h>
25 #include <sys/btree.h>
26 #include <sys/zap.h>
27 #include <sys/zap_impl.h>
28 #include <sys/zap_leaf.h>
29
30 /* zap_create */
31
32 static uint64_t
zap_create_impl(objset_t * os,int normflags,zap_flags_t flags,dmu_object_type_t ot,int leaf_blockshift,int indirect_blockshift,dmu_object_type_t bonustype,int bonuslen,int dnodesize,dnode_t ** allocated_dnode,const void * tag,dmu_tx_t * tx)33 zap_create_impl(objset_t *os, int normflags, zap_flags_t flags,
34 dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
35 dmu_object_type_t bonustype, int bonuslen, int dnodesize,
36 dnode_t **allocated_dnode, const void *tag, dmu_tx_t *tx)
37 {
38 uint64_t obj;
39
40 ASSERT3U(DMU_OT_BYTESWAP(ot), ==, DMU_BSWAP_ZAP);
41
42 if (allocated_dnode == NULL) {
43 dnode_t *dn;
44 obj = dmu_object_alloc_hold(os, ot, 1ULL << leaf_blockshift,
45 indirect_blockshift, bonustype, bonuslen, dnodesize,
46 &dn, FTAG, tx);
47 mzap_create_impl(dn, normflags, flags, tx);
48 dnode_rele(dn, FTAG);
49 } else {
50 obj = dmu_object_alloc_hold(os, ot, 1ULL << leaf_blockshift,
51 indirect_blockshift, bonustype, bonuslen, dnodesize,
52 allocated_dnode, tag, tx);
53 mzap_create_impl(*allocated_dnode, normflags, flags, tx);
54 }
55
56 return (obj);
57 }
58
59 uint64_t
zap_create(objset_t * os,dmu_object_type_t ot,dmu_object_type_t bonustype,int bonuslen,dmu_tx_t * tx)60 zap_create(objset_t *os, dmu_object_type_t ot,
61 dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
62 {
63 return (zap_create_norm(os, 0, ot, bonustype, bonuslen, tx));
64 }
65
66 uint64_t
zap_create_dnsize(objset_t * os,dmu_object_type_t ot,dmu_object_type_t bonustype,int bonuslen,int dnodesize,dmu_tx_t * tx)67 zap_create_dnsize(objset_t *os, dmu_object_type_t ot,
68 dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx)
69 {
70 return (zap_create_norm_dnsize(os, 0, ot, bonustype, bonuslen,
71 dnodesize, tx));
72 }
73
74 uint64_t
zap_create_norm(objset_t * os,int normflags,dmu_object_type_t ot,dmu_object_type_t bonustype,int bonuslen,dmu_tx_t * tx)75 zap_create_norm(objset_t *os, int normflags, dmu_object_type_t ot,
76 dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
77 {
78 return (zap_create_norm_dnsize(os, normflags, ot, bonustype, bonuslen,
79 0, tx));
80 }
81
82 uint64_t
zap_create_norm_dnsize(objset_t * os,int normflags,dmu_object_type_t ot,dmu_object_type_t bonustype,int bonuslen,int dnodesize,dmu_tx_t * tx)83 zap_create_norm_dnsize(objset_t *os, int normflags, dmu_object_type_t ot,
84 dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx)
85 {
86 return (zap_create_impl(os, normflags, 0, ot, 0, 0,
87 bonustype, bonuslen, dnodesize, NULL, NULL, tx));
88 }
89
90 uint64_t
zap_create_flags(objset_t * os,int normflags,zap_flags_t flags,dmu_object_type_t ot,int leaf_blockshift,int indirect_blockshift,dmu_object_type_t bonustype,int bonuslen,dmu_tx_t * tx)91 zap_create_flags(objset_t *os, int normflags, zap_flags_t flags,
92 dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
93 dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
94 {
95 return (zap_create_flags_dnsize(os, normflags, flags, ot,
96 leaf_blockshift, indirect_blockshift, bonustype, bonuslen, 0, tx));
97 }
98
99 uint64_t
zap_create_flags_dnsize(objset_t * os,int normflags,zap_flags_t flags,dmu_object_type_t ot,int leaf_blockshift,int indirect_blockshift,dmu_object_type_t bonustype,int bonuslen,int dnodesize,dmu_tx_t * tx)100 zap_create_flags_dnsize(objset_t *os, int normflags, zap_flags_t flags,
101 dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
102 dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx)
103 {
104 return (zap_create_impl(os, normflags, flags, ot, leaf_blockshift,
105 indirect_blockshift, bonustype, bonuslen, dnodesize, NULL, NULL,
106 tx));
107 }
108
109 /* zap_crate_hold */
110
111 uint64_t
zap_create_hold(objset_t * os,int normflags,zap_flags_t flags,dmu_object_type_t ot,int leaf_blockshift,int indirect_blockshift,dmu_object_type_t bonustype,int bonuslen,int dnodesize,dnode_t ** allocated_dnode,const void * tag,dmu_tx_t * tx)112 zap_create_hold(objset_t *os, int normflags, zap_flags_t flags,
113 dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
114 dmu_object_type_t bonustype, int bonuslen, int dnodesize,
115 dnode_t **allocated_dnode, const void *tag, dmu_tx_t *tx)
116 {
117 return (zap_create_impl(os, normflags, flags, ot, leaf_blockshift,
118 indirect_blockshift, bonustype, bonuslen, dnodesize,
119 allocated_dnode, tag, tx));
120 }
121
122 /* zap_create_link */
123
124 uint64_t
zap_create_link(objset_t * os,dmu_object_type_t ot,uint64_t parent_obj,const char * name,dmu_tx_t * tx)125 zap_create_link(objset_t *os, dmu_object_type_t ot, uint64_t parent_obj,
126 const char *name, dmu_tx_t *tx)
127 {
128 return (zap_create_link_dnsize(os, ot, parent_obj, name, 0, tx));
129 }
130
131 uint64_t
zap_create_link_dnsize(objset_t * os,dmu_object_type_t ot,uint64_t parent_obj,const char * name,int dnodesize,dmu_tx_t * tx)132 zap_create_link_dnsize(objset_t *os, dmu_object_type_t ot, uint64_t parent_obj,
133 const char *name, int dnodesize, dmu_tx_t *tx)
134 {
135 uint64_t new_obj;
136
137 new_obj = zap_create_dnsize(os, ot, DMU_OT_NONE, 0, dnodesize, tx);
138 VERIFY(new_obj != 0);
139 VERIFY0(zap_add(os, parent_obj, name, sizeof (uint64_t), 1, &new_obj,
140 tx));
141
142 return (new_obj);
143 }
144
145 /* zap_create_claim */
146
147 int
zap_create_claim(objset_t * os,uint64_t obj,dmu_object_type_t ot,dmu_object_type_t bonustype,int bonuslen,dmu_tx_t * tx)148 zap_create_claim(objset_t *os, uint64_t obj, dmu_object_type_t ot,
149 dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
150 {
151 return (zap_create_claim_dnsize(os, obj, ot, bonustype, bonuslen,
152 0, tx));
153 }
154
155 int
zap_create_claim_dnsize(objset_t * os,uint64_t obj,dmu_object_type_t ot,dmu_object_type_t bonustype,int bonuslen,int dnodesize,dmu_tx_t * tx)156 zap_create_claim_dnsize(objset_t *os, uint64_t obj, dmu_object_type_t ot,
157 dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx)
158 {
159 return (zap_create_claim_norm_dnsize(os, obj,
160 0, ot, bonustype, bonuslen, dnodesize, tx));
161 }
162
163 int
zap_create_claim_norm(objset_t * os,uint64_t obj,int normflags,dmu_object_type_t ot,dmu_object_type_t bonustype,int bonuslen,dmu_tx_t * tx)164 zap_create_claim_norm(objset_t *os, uint64_t obj, int normflags,
165 dmu_object_type_t ot,
166 dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
167 {
168 return (zap_create_claim_norm_dnsize(os, obj, normflags, ot, bonustype,
169 bonuslen, 0, tx));
170 }
171
172 int
zap_create_claim_norm_dnsize(objset_t * os,uint64_t obj,int normflags,dmu_object_type_t ot,dmu_object_type_t bonustype,int bonuslen,int dnodesize,dmu_tx_t * tx)173 zap_create_claim_norm_dnsize(objset_t *os, uint64_t obj, int normflags,
174 dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen,
175 int dnodesize, dmu_tx_t *tx)
176 {
177 dnode_t *dn;
178 int error;
179
180 ASSERT3U(DMU_OT_BYTESWAP(ot), ==, DMU_BSWAP_ZAP);
181 error = dmu_object_claim_dnsize(os, obj, ot, 0, bonustype, bonuslen,
182 dnodesize, tx);
183 if (error != 0)
184 return (error);
185
186 error = dnode_hold(os, obj, FTAG, &dn);
187 if (error != 0)
188 return (error);
189
190 mzap_create_impl(dn, normflags, 0, tx);
191
192 dnode_rele(dn, FTAG);
193
194 return (0);
195 }
196
197 /* zap_destroy */
198
199 int
zap_destroy(objset_t * os,uint64_t zapobj,dmu_tx_t * tx)200 zap_destroy(objset_t *os, uint64_t zapobj, dmu_tx_t *tx)
201 {
202 /*
203 * dmu_object_free will free the object number and free the
204 * data. Freeing the data will cause our pageout function to be
205 * called, which will destroy our data (zap_leaf_t's and zap_t).
206 */
207
208 return (dmu_object_free(os, zapobj, tx));
209 }
210
211 /* zap_lookup */
212
213 int
zap_lookup_norm_by_dnode(dnode_t * dn,const char * name,uint64_t integer_size,uint64_t num_integers,void * buf,matchtype_t mt,char * realname,int rn_len,boolean_t * ncp)214 zap_lookup_norm_by_dnode(dnode_t *dn, const char *name,
215 uint64_t integer_size, uint64_t num_integers, void *buf,
216 matchtype_t mt, char *realname, int rn_len,
217 boolean_t *ncp)
218 {
219 zap_t *zap;
220
221 int err =
222 zap_lock_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
223 if (err != 0)
224 return (err);
225
226 zap_name_t *zn = zap_name_alloc_str(zap, name, mt);
227 if (zn == NULL) {
228 zap_unlock(zap, FTAG);
229 return (SET_ERROR(ENOTSUP));
230 }
231
232 if (!zap->zap_ismicro) {
233 err = fzap_lookup(zn, integer_size, num_integers, buf,
234 realname, rn_len, ncp, NULL);
235 } else {
236 zfs_btree_index_t idx;
237 mzap_ent_t *mze = mze_find(zn, &idx);
238 if (mze == NULL) {
239 err = SET_ERROR(ENOENT);
240 } else {
241 if (num_integers < 1) {
242 err = SET_ERROR(EOVERFLOW);
243 } else if (integer_size != 8) {
244 err = SET_ERROR(EINVAL);
245 } else {
246 *(uint64_t *)buf =
247 MZE_PHYS(zap, mze)->mze_value;
248 if (realname != NULL)
249 (void) strlcpy(realname,
250 MZE_PHYS(zap, mze)->mze_name,
251 rn_len);
252 if (ncp) {
253 *ncp = mzap_normalization_conflict(zap,
254 zn, mze, &idx);
255 }
256 }
257 }
258 }
259 zap_name_free(zn);
260 zap_unlock(zap, FTAG);
261 return (err);
262 }
263
264 int
zap_lookup(objset_t * os,uint64_t zapobj,const char * name,uint64_t integer_size,uint64_t num_integers,void * buf)265 zap_lookup(objset_t *os, uint64_t zapobj, const char *name,
266 uint64_t integer_size, uint64_t num_integers, void *buf)
267 {
268 return (zap_lookup_norm(os, zapobj, name, integer_size,
269 num_integers, buf, 0, NULL, 0, NULL));
270 }
271
272 int
zap_lookup_by_dnode(dnode_t * dn,const char * name,uint64_t integer_size,uint64_t num_integers,void * buf)273 zap_lookup_by_dnode(dnode_t *dn, const char *name,
274 uint64_t integer_size, uint64_t num_integers, void *buf)
275 {
276 return (zap_lookup_norm_by_dnode(dn, name, integer_size,
277 num_integers, buf, 0, NULL, 0, NULL));
278 }
279
280 int
zap_lookup_norm(objset_t * os,uint64_t zapobj,const char * name,uint64_t integer_size,uint64_t num_integers,void * buf,matchtype_t mt,char * realname,int rn_len,boolean_t * ncp)281 zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
282 uint64_t integer_size, uint64_t num_integers, void *buf,
283 matchtype_t mt, char *realname, int rn_len,
284 boolean_t *ncp)
285 {
286 dnode_t *dn;
287 int err = dnode_hold(os, zapobj, FTAG, &dn);
288 if (err != 0)
289 return (err);
290 err = zap_lookup_norm_by_dnode(dn, name, integer_size,
291 num_integers, buf, mt, realname, rn_len, ncp);
292 dnode_rele(dn, FTAG);
293 return (err);
294 }
295
296 /* zap_lookup_uint64 */
297
298 int
zap_lookup_length_uint64_by_dnode(dnode_t * dn,const uint64_t * key,int key_numints,uint64_t integer_size,uint64_t num_integers,void * buf,uint64_t * actual_num_integers)299 zap_lookup_length_uint64_by_dnode(dnode_t *dn, const uint64_t *key,
300 int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf,
301 uint64_t *actual_num_integers)
302 {
303 zap_t *zap;
304 int err =
305 zap_lock_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
306 if (err != 0)
307 return (err);
308
309 zap_name_t *zn = zap_name_alloc_uint64(zap, key, key_numints);
310 if (zn == NULL) {
311 zap_unlock(zap, FTAG);
312 return (SET_ERROR(ENOTSUP));
313 }
314
315 err = fzap_lookup(zn, integer_size, num_integers, buf,
316 NULL, 0, NULL, actual_num_integers);
317 zap_name_free(zn);
318 zap_unlock(zap, FTAG);
319 return (err);
320 }
321
322 int
zap_lookup_uint64(objset_t * os,uint64_t zapobj,const uint64_t * key,int key_numints,uint64_t integer_size,uint64_t num_integers,void * buf)323 zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
324 int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf)
325 {
326 dnode_t *dn;
327 int err = dnode_hold(os, zapobj, FTAG, &dn);
328 if (err != 0)
329 return (err);
330 err = zap_lookup_length_uint64_by_dnode(dn, key, key_numints,
331 integer_size, num_integers, buf, NULL);
332 dnode_rele(dn, FTAG);
333 return (err);
334 }
335
336 int
zap_lookup_uint64_by_dnode(dnode_t * dn,const uint64_t * key,int key_numints,uint64_t integer_size,uint64_t num_integers,void * buf)337 zap_lookup_uint64_by_dnode(dnode_t *dn, const uint64_t *key,
338 int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf)
339 {
340 return (zap_lookup_length_uint64_by_dnode(dn, key, key_numints,
341 integer_size, num_integers, buf, NULL));
342 }
343
344 /* zap_contains */
345
346 int
zap_contains_by_dnode(dnode_t * dn,const char * name)347 zap_contains_by_dnode(dnode_t *dn, const char *name)
348 {
349 int err = zap_lookup_norm_by_dnode(dn, name, 0,
350 0, NULL, 0, NULL, 0, NULL);
351 if (err == EOVERFLOW || err == EINVAL)
352 err = 0; /* found, but skipped reading the value */
353 return (err);
354 }
355
356 int
zap_contains(objset_t * os,uint64_t zapobj,const char * name)357 zap_contains(objset_t *os, uint64_t zapobj, const char *name)
358 {
359 dnode_t *dn;
360 int err = dnode_hold(os, zapobj, FTAG, &dn);
361 if (err != 0)
362 return (err);
363 err = zap_contains_by_dnode(dn, name);
364 dnode_rele(dn, FTAG);
365 return (err);
366 }
367
368 /* zap_prefetch */
369
370 static int
zap_prefetch_by_dnode(dnode_t * dn,const char * name)371 zap_prefetch_by_dnode(dnode_t *dn, const char *name)
372 {
373 zap_t *zap;
374 int err =
375 zap_lock_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
376 if (err)
377 return (err);
378
379 zap_name_t *zn = zap_name_alloc_str(zap, name, 0);
380 if (zn == NULL) {
381 zap_unlock(zap, FTAG);
382 return (SET_ERROR(ENOTSUP));
383 }
384
385 fzap_prefetch(zn);
386 zap_name_free(zn);
387 zap_unlock(zap, FTAG);
388 return (err);
389 }
390
391 int
zap_prefetch(objset_t * os,uint64_t zapobj,const char * name)392 zap_prefetch(objset_t *os, uint64_t zapobj, const char *name)
393 {
394 dnode_t *dn;
395 int err = dnode_hold(os, zapobj, FTAG, &dn);
396 if (err != 0)
397 return (err);
398 err = zap_prefetch_by_dnode(dn, name);
399 dnode_rele(dn, FTAG);
400 return (err);
401 }
402
403 /* zap_prefetch_uint64 */
404
405 int
zap_prefetch_uint64_by_dnode(dnode_t * dn,const uint64_t * key,int key_numints)406 zap_prefetch_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int key_numints)
407 {
408 zap_t *zap;
409 int err =
410 zap_lock_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
411 if (err != 0)
412 return (err);
413
414 zap_name_t *zn = zap_name_alloc_uint64(zap, key, key_numints);
415 if (zn == NULL) {
416 zap_unlock(zap, FTAG);
417 return (SET_ERROR(ENOTSUP));
418 }
419
420 fzap_prefetch(zn);
421 zap_name_free(zn);
422 zap_unlock(zap, FTAG);
423 return (0);
424 }
425
426 int
zap_prefetch_uint64(objset_t * os,uint64_t zapobj,const uint64_t * key,int key_numints)427 zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
428 int key_numints)
429 {
430 dnode_t *dn;
431 int err = dnode_hold(os, zapobj, FTAG, &dn);
432 if (err != 0)
433 return (err);
434 err = zap_prefetch_uint64_by_dnode(dn, key, key_numints);
435 dnode_rele(dn, FTAG);
436 return (err);
437 }
438
439 /* zap_prefetch_object */
440
441 int
zap_prefetch_object(objset_t * os,uint64_t zapobj)442 zap_prefetch_object(objset_t *os, uint64_t zapobj)
443 {
444 int error;
445 dmu_object_info_t doi;
446
447 error = dmu_object_info(os, zapobj, &doi);
448 if (error == 0 && DMU_OT_BYTESWAP(doi.doi_type) != DMU_BSWAP_ZAP)
449 error = SET_ERROR(EINVAL);
450 if (error == 0)
451 dmu_prefetch_wait(os, zapobj, 0, doi.doi_max_offset);
452
453 return (error);
454 }
455
456 /* zap_add */
457
458 int
zap_add_by_dnode(dnode_t * dn,const char * key,int integer_size,uint64_t num_integers,const void * val,dmu_tx_t * tx)459 zap_add_by_dnode(dnode_t *dn, const char *key,
460 int integer_size, uint64_t num_integers,
461 const void *val, dmu_tx_t *tx)
462 {
463 zap_t *zap;
464 int err =
465 zap_lock_by_dnode(dn, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
466 if (err != 0)
467 return (err);
468
469 const uint64_t *intval = val;
470 zap_name_t *zn = zap_name_alloc_str(zap, key, 0);
471 if (zn == NULL) {
472 zap_unlock(zap, FTAG);
473 return (SET_ERROR(ENOTSUP));
474 }
475 if (!zap->zap_ismicro) {
476 err = fzap_add(zn, integer_size, num_integers, val, tx);
477 } else if (integer_size != 8 || num_integers != 1 ||
478 strlen(key) >= MZAP_NAME_LEN ||
479 !mze_canfit_fzap_leaf(zn, zn->zn_hash)) {
480 err = mzap_upgrade(&zn->zn_zap, tx, 0);
481 if (err == 0) {
482 err = fzap_add(zn, integer_size, num_integers, val, tx);
483 }
484 } else {
485 zfs_btree_index_t idx;
486 if (mze_find(zn, &idx) != NULL) {
487 err = SET_ERROR(EEXIST);
488 } else {
489 mzap_addent(zn, *intval);
490 }
491 }
492 ASSERT(zap == zn->zn_zap);
493 zap_name_free(zn);
494 zap_unlock(zap, FTAG);
495 return (err);
496 }
497
498 int
zap_add(objset_t * os,uint64_t zapobj,const char * key,int integer_size,uint64_t num_integers,const void * val,dmu_tx_t * tx)499 zap_add(objset_t *os, uint64_t zapobj, const char *key,
500 int integer_size, uint64_t num_integers,
501 const void *val, dmu_tx_t *tx)
502 {
503 dnode_t *dn;
504 int err = dnode_hold(os, zapobj, FTAG, &dn);
505 if (err != 0)
506 return (err);
507 err = zap_add_by_dnode(dn, key, integer_size, num_integers, val, tx);
508 dnode_rele(dn, FTAG);
509 return (err);
510 }
511
512 /* zap_add_uint64 */
513
514 int
zap_add_uint64_by_dnode(dnode_t * dn,const uint64_t * key,int key_numints,int integer_size,uint64_t num_integers,const void * val,dmu_tx_t * tx)515 zap_add_uint64_by_dnode(dnode_t *dn, const uint64_t *key,
516 int key_numints, int integer_size, uint64_t num_integers,
517 const void *val, dmu_tx_t *tx)
518 {
519 zap_t *zap;
520 int err =
521 zap_lock_by_dnode(dn, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
522 if (err != 0)
523 return (err);
524
525 zap_name_t *zn = zap_name_alloc_uint64(zap, key, key_numints);
526 if (zn == NULL) {
527 zap_unlock(zap, FTAG);
528 return (SET_ERROR(ENOTSUP));
529 }
530 err = fzap_add(zn, integer_size, num_integers, val, tx);
531 zap = zn->zn_zap; /* fzap_add() may change zap */
532 zap_name_free(zn);
533 if (zap != NULL) /* may be NULL if fzap_add() failed */
534 zap_unlock(zap, FTAG);
535 return (err);
536 }
537
538 int
zap_add_uint64(objset_t * os,uint64_t zapobj,const uint64_t * key,int key_numints,int integer_size,uint64_t num_integers,const void * val,dmu_tx_t * tx)539 zap_add_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
540 int key_numints, int integer_size, uint64_t num_integers,
541 const void *val, dmu_tx_t *tx)
542 {
543 dnode_t *dn;
544 int err = dnode_hold(os, zapobj, FTAG, &dn);
545 if (err != 0)
546 return (err);
547 err = zap_add_uint64_by_dnode(dn, key, key_numints,
548 integer_size, num_integers, val, tx);
549 dnode_rele(dn, FTAG);
550 return (err);
551 }
552
553 /* zap_update */
554
555 int
zap_update_by_dnode(dnode_t * dn,const char * name,int integer_size,uint64_t num_integers,const void * val,dmu_tx_t * tx)556 zap_update_by_dnode(dnode_t *dn, const char *name, int integer_size,
557 uint64_t num_integers, const void *val, dmu_tx_t *tx)
558 {
559 zap_t *zap;
560 int err =
561 zap_lock_by_dnode(dn, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
562 if (err != 0)
563 return (err);
564
565 const uint64_t *intval = val;
566 zap_name_t *zn = zap_name_alloc_str(zap, name, 0);
567 if (zn == NULL) {
568 zap_unlock(zap, FTAG);
569 return (SET_ERROR(ENOTSUP));
570 }
571 if (!zap->zap_ismicro) {
572 err = fzap_update(zn, integer_size, num_integers, val, tx);
573 } else if (integer_size != 8 || num_integers != 1 ||
574 strlen(name) >= MZAP_NAME_LEN) {
575 dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
576 (u_longlong_t)dn->dn_object, integer_size,
577 (u_longlong_t)num_integers, name);
578 err = mzap_upgrade(&zn->zn_zap, tx, 0);
579 if (err == 0) {
580 err = fzap_update(zn, integer_size, num_integers,
581 val, tx);
582 }
583 } else {
584 zfs_btree_index_t idx;
585 mzap_ent_t *mze = mze_find(zn, &idx);
586 if (mze != NULL) {
587 MZE_PHYS(zap, mze)->mze_value = *intval;
588 } else {
589 mzap_addent(zn, *intval);
590 }
591 }
592 ASSERT(zap == zn->zn_zap);
593 zap_name_free(zn);
594 zap_unlock(zap, FTAG);
595 return (err);
596 }
597
598 int
zap_update(objset_t * os,uint64_t zapobj,const char * name,int integer_size,uint64_t num_integers,const void * val,dmu_tx_t * tx)599 zap_update(objset_t *os, uint64_t zapobj, const char *name,
600 int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
601 {
602 dnode_t *dn;
603 int err = dnode_hold(os, zapobj, FTAG, &dn);
604 if (err != 0)
605 return (err);
606 err = zap_update_by_dnode(dn, name,
607 integer_size, num_integers, val, tx);
608 dnode_rele(dn, FTAG);
609 return (err);
610 }
611
612 /* zap_update_uint64 */
613
614 int
zap_update_uint64_by_dnode(dnode_t * dn,const uint64_t * key,int key_numints,int integer_size,uint64_t num_integers,const void * val,dmu_tx_t * tx)615 zap_update_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int key_numints,
616 int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
617 {
618 zap_t *zap;
619 int err =
620 zap_lock_by_dnode(dn, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
621 if (err != 0)
622 return (err);
623
624 zap_name_t *zn = zap_name_alloc_uint64(zap, key, key_numints);
625 if (zn == NULL) {
626 zap_unlock(zap, FTAG);
627 return (SET_ERROR(ENOTSUP));
628 }
629 err = fzap_update(zn, integer_size, num_integers, val, tx);
630 zap_name_free(zn);
631 zap_unlock(zap, FTAG);
632 return (err);
633 }
634
635 int
zap_update_uint64(objset_t * os,uint64_t zapobj,const uint64_t * key,int key_numints,int integer_size,uint64_t num_integers,const void * val,dmu_tx_t * tx)636 zap_update_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
637 int key_numints, int integer_size, uint64_t num_integers, const void *val,
638 dmu_tx_t *tx)
639 {
640 dnode_t *dn;
641 int err = dnode_hold(os, zapobj, FTAG, &dn);
642 if (err != 0)
643 return (err);
644 err = zap_update_uint64_by_dnode(dn, key, key_numints,
645 integer_size, num_integers, val, tx);
646 dnode_rele(dn, FTAG);
647 return (err);
648 }
649
650 /* zap_length */
651
652 int
zap_length_by_dnode(dnode_t * dn,const char * name,uint64_t * integer_size,uint64_t * num_integers)653 zap_length_by_dnode(dnode_t *dn, const char *name, uint64_t *integer_size,
654 uint64_t *num_integers)
655 {
656 zap_t *zap;
657 int err =
658 zap_lock_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
659 if (err != 0)
660 return (err);
661
662 zap_name_t *zn = zap_name_alloc_str(zap, name, 0);
663 if (zn == NULL) {
664 zap_unlock(zap, FTAG);
665 return (SET_ERROR(ENOTSUP));
666 }
667 if (!zap->zap_ismicro) {
668 err = fzap_length(zn, integer_size, num_integers);
669 } else {
670 zfs_btree_index_t idx;
671 mzap_ent_t *mze = mze_find(zn, &idx);
672 if (mze == NULL) {
673 err = SET_ERROR(ENOENT);
674 } else {
675 if (integer_size)
676 *integer_size = 8;
677 if (num_integers)
678 *num_integers = 1;
679 }
680 }
681 zap_name_free(zn);
682 zap_unlock(zap, FTAG);
683 return (err);
684 }
685
686 int
zap_length(objset_t * os,uint64_t zapobj,const char * name,uint64_t * integer_size,uint64_t * num_integers)687 zap_length(objset_t *os, uint64_t zapobj, const char *name,
688 uint64_t *integer_size, uint64_t *num_integers)
689 {
690 dnode_t *dn;
691 int err = dnode_hold(os, zapobj, FTAG, &dn);
692 if (err != 0)
693 return (err);
694 err = zap_length_by_dnode(dn, name, integer_size, num_integers);
695 dnode_rele(dn, FTAG);
696 return (err);
697 }
698
699 /* zap_length_uint64 */
700
701 int
zap_length_uint64_by_dnode(dnode_t * dn,const uint64_t * key,int key_numints,uint64_t * integer_size,uint64_t * num_integers)702 zap_length_uint64_by_dnode(dnode_t *dn, const uint64_t *key,
703 int key_numints, uint64_t *integer_size, uint64_t *num_integers)
704 {
705 zap_t *zap;
706 int err =
707 zap_lock_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
708 if (err != 0)
709 return (err);
710 zap_name_t *zn = zap_name_alloc_uint64(zap, key, key_numints);
711 if (zn == NULL) {
712 zap_unlock(zap, FTAG);
713 return (SET_ERROR(ENOTSUP));
714 }
715 err = fzap_length(zn, integer_size, num_integers);
716 zap_name_free(zn);
717 zap_unlock(zap, FTAG);
718 return (err);
719 }
720
721 int
zap_length_uint64(objset_t * os,uint64_t zapobj,const uint64_t * key,int key_numints,uint64_t * integer_size,uint64_t * num_integers)722 zap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
723 int key_numints, uint64_t *integer_size, uint64_t *num_integers)
724 {
725 dnode_t *dn;
726 int err = dnode_hold(os, zapobj, FTAG, &dn);
727 if (err != 0)
728 return (err);
729 err = zap_length_uint64_by_dnode(dn, key, key_numints,
730 integer_size, num_integers);
731 dnode_rele(dn, FTAG);
732 return (err);
733 }
734
735 /* zap_remove */
736
737 int
zap_remove_norm_by_dnode(dnode_t * dn,const char * name,matchtype_t mt,dmu_tx_t * tx)738 zap_remove_norm_by_dnode(dnode_t *dn, const char *name, matchtype_t mt,
739 dmu_tx_t *tx)
740 {
741 zap_t *zap;
742 int err =
743 zap_lock_by_dnode(dn, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
744 if (err)
745 return (err);
746
747 zap_name_t *zn = zap_name_alloc_str(zap, name, mt);
748 if (zn == NULL) {
749 zap_unlock(zap, FTAG);
750 return (SET_ERROR(ENOTSUP));
751 }
752 if (!zap->zap_ismicro) {
753 err = fzap_remove(zn, tx);
754 } else {
755 zfs_btree_index_t idx;
756 mzap_ent_t *mze = mze_find(zn, &idx);
757 if (mze == NULL) {
758 err = SET_ERROR(ENOENT);
759 } else {
760 zap->zap_m.zap_num_entries--;
761 memset(MZE_PHYS(zap, mze), 0, sizeof (mzap_ent_phys_t));
762 zfs_btree_remove_idx(&zap->zap_m.zap_tree, &idx);
763 }
764 }
765 zap_name_free(zn);
766 zap_unlock(zap, FTAG);
767 return (err);
768 }
769
770 int
zap_remove(objset_t * os,uint64_t zapobj,const char * name,dmu_tx_t * tx)771 zap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx)
772 {
773 return (zap_remove_norm(os, zapobj, name, 0, tx));
774 }
775
776 int
zap_remove_by_dnode(dnode_t * dn,const char * name,dmu_tx_t * tx)777 zap_remove_by_dnode(dnode_t *dn, const char *name, dmu_tx_t *tx)
778 {
779 return (zap_remove_norm_by_dnode(dn, name, 0, tx));
780 }
781
782 int
zap_remove_norm(objset_t * os,uint64_t zapobj,const char * name,matchtype_t mt,dmu_tx_t * tx)783 zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
784 matchtype_t mt, dmu_tx_t *tx)
785 {
786 dnode_t *dn;
787 int err = dnode_hold(os, zapobj, FTAG, &dn);
788 if (err != 0)
789 return (err);
790 err = zap_remove_norm_by_dnode(dn, name, mt, tx);
791 dnode_rele(dn, FTAG);
792 return (err);
793 }
794
795 /* zap_remove_uint64 */
796
797 int
zap_remove_uint64_by_dnode(dnode_t * dn,const uint64_t * key,int key_numints,dmu_tx_t * tx)798 zap_remove_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int key_numints,
799 dmu_tx_t *tx)
800 {
801 zap_t *zap;
802 int err =
803 zap_lock_by_dnode(dn, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
804 if (err != 0)
805 return (err);
806
807 zap_name_t *zn = zap_name_alloc_uint64(zap, key, key_numints);
808 if (zn == NULL) {
809 zap_unlock(zap, FTAG);
810 return (SET_ERROR(ENOTSUP));
811 }
812 err = fzap_remove(zn, tx);
813 zap_name_free(zn);
814 zap_unlock(zap, FTAG);
815 return (err);
816 }
817
818 int
zap_remove_uint64(objset_t * os,uint64_t zapobj,const uint64_t * key,int key_numints,dmu_tx_t * tx)819 zap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
820 int key_numints, dmu_tx_t *tx)
821 {
822 dnode_t *dn;
823 int err = dnode_hold(os, zapobj, FTAG, &dn);
824 if (err != 0)
825 return (err);
826 err = zap_remove_uint64_by_dnode(dn, key, key_numints, tx);
827 dnode_rele(dn, FTAG);
828 return (err);
829 }
830
831 /* zap_count */
832
833 int
zap_count_by_dnode(dnode_t * dn,uint64_t * count)834 zap_count_by_dnode(dnode_t *dn, uint64_t *count)
835 {
836 zap_t *zap;
837 int err =
838 zap_lock_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
839 if (err != 0)
840 return (err);
841 if (!zap->zap_ismicro) {
842 err = fzap_count(zap, count);
843 } else {
844 *count = zap->zap_m.zap_num_entries;
845 }
846 zap_unlock(zap, FTAG);
847 return (err);
848 }
849
850 int
zap_count(objset_t * os,uint64_t zapobj,uint64_t * count)851 zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
852 {
853 dnode_t *dn;
854 int err = dnode_hold(os, zapobj, FTAG, &dn);
855 if (err != 0)
856 return (err);
857 err = zap_count_by_dnode(dn, count);
858 dnode_rele(dn, FTAG);
859 return (err);
860 }
861
862 /* zap_increment */
863
864 int
zap_increment_by_dnode(dnode_t * dn,const char * name,int64_t delta,dmu_tx_t * tx)865 zap_increment_by_dnode(dnode_t *dn, const char *name, int64_t delta,
866 dmu_tx_t *tx)
867 {
868 uint64_t value = 0;
869
870 if (delta == 0)
871 return (0);
872
873 int err = zap_lookup_by_dnode(dn, name, 8, 1, &value);
874 if (err != 0 && err != ENOENT)
875 return (err);
876 value += delta;
877 if (value == 0)
878 err = zap_remove_by_dnode(dn, name, tx);
879 else
880 err = zap_update_by_dnode(dn, name, 8, 1, &value, tx);
881 return (err);
882 }
883
884 int
zap_increment(objset_t * os,uint64_t zapobj,const char * name,int64_t delta,dmu_tx_t * tx)885 zap_increment(objset_t *os, uint64_t zapobj, const char *name, int64_t delta,
886 dmu_tx_t *tx)
887 {
888 dnode_t *dn;
889 int err = dnode_hold(os, zapobj, FTAG, &dn);
890 if (err != 0)
891 return (err);
892 err = zap_increment_by_dnode(dn, name, delta, tx);
893 dnode_rele(dn, FTAG);
894 return (err);
895 }
896
897 /* zap_value_search */
898
899 static int
zap_value_search_impl(zap_cursor_t * zc,uint64_t value,uint64_t mask,char * name,uint64_t namelen)900 zap_value_search_impl(zap_cursor_t *zc, uint64_t value, uint64_t mask,
901 char *name, uint64_t namelen)
902 {
903 int err;
904
905 if (mask == 0)
906 mask = -1ULL;
907
908 zap_attribute_t *za = zap_attribute_long_alloc();
909 for (; (err = zap_cursor_retrieve(zc, za)) == 0;
910 zap_cursor_advance(zc)) {
911 if ((za->za_first_integer & mask) == (value & mask)) {
912 if (strlcpy(name, za->za_name, namelen) >= namelen)
913 err = SET_ERROR(ENAMETOOLONG);
914 break;
915 }
916 }
917 zap_cursor_fini(zc);
918 zap_attribute_free(za);
919 return (err);
920 }
921
922 int
zap_value_search(objset_t * os,uint64_t zapobj,uint64_t value,uint64_t mask,char * name,uint64_t namelen)923 zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask,
924 char *name, uint64_t namelen)
925 {
926 zap_cursor_t zc;
927 zap_cursor_init(&zc, os, zapobj);
928 return (zap_value_search_impl(&zc, value, mask, name, namelen));
929 }
930
931 int
zap_value_search_by_dnode(dnode_t * dn,uint64_t value,uint64_t mask,char * name,uint64_t namelen)932 zap_value_search_by_dnode(dnode_t *dn, uint64_t value, uint64_t mask,
933 char *name, uint64_t namelen)
934 {
935 zap_cursor_t zc;
936 zap_cursor_init_by_dnode(&zc, dn);
937 return (zap_value_search_impl(&zc, value, mask, name, namelen));
938 }
939
940 /* zap_*_int */
941
942 #define FORMAT_INT_KEY(name, value) \
943 char name[20]; \
944 (void) snprintf(name, sizeof (name), "%llx", (longlong_t)value);
945
946 int
zap_add_int(objset_t * os,uint64_t obj,uint64_t value,dmu_tx_t * tx)947 zap_add_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx)
948 {
949 FORMAT_INT_KEY(name, value);
950 return (zap_add(os, obj, name, 8, 1, &value, tx));
951 }
952 int
zap_add_int_by_dnode(dnode_t * dn,uint64_t value,dmu_tx_t * tx)953 zap_add_int_by_dnode(dnode_t *dn, uint64_t value, dmu_tx_t *tx)
954 {
955 FORMAT_INT_KEY(name, value);
956 return (zap_add_by_dnode(dn, name, 8, 1, &value, tx));
957 }
958
959 int
zap_remove_int(objset_t * os,uint64_t obj,uint64_t value,dmu_tx_t * tx)960 zap_remove_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx)
961 {
962 FORMAT_INT_KEY(name, value);
963 return (zap_remove(os, obj, name, tx));
964 }
965 int
zap_remove_int_by_dnode(dnode_t * dn,uint64_t value,dmu_tx_t * tx)966 zap_remove_int_by_dnode(dnode_t *dn, uint64_t value, dmu_tx_t *tx)
967 {
968 FORMAT_INT_KEY(name, value);
969 return (zap_remove_by_dnode(dn, name, tx));
970 }
971
972 int
zap_lookup_int(objset_t * os,uint64_t obj,uint64_t value)973 zap_lookup_int(objset_t *os, uint64_t obj, uint64_t value)
974 {
975 FORMAT_INT_KEY(name, value);
976 return (zap_lookup(os, obj, name, 8, 1, &value));
977 }
978
979 int
zap_lookup_int_by_dnode(dnode_t * dn,uint64_t value)980 zap_lookup_int_by_dnode(dnode_t *dn, uint64_t value)
981 {
982 FORMAT_INT_KEY(name, value);
983 return (zap_lookup_by_dnode(dn, name, 8, 1, &value));
984 }
985
986 /* zap_*_int_key */
987
988 int
zap_add_int_key(objset_t * os,uint64_t obj,uint64_t key,uint64_t value,dmu_tx_t * tx)989 zap_add_int_key(objset_t *os, uint64_t obj,
990 uint64_t key, uint64_t value, dmu_tx_t *tx)
991 {
992 FORMAT_INT_KEY(name, key);
993 return (zap_add(os, obj, name, 8, 1, &value, tx));
994 }
995 int
zap_add_int_key_by_dnode(dnode_t * dn,uint64_t key,uint64_t value,dmu_tx_t * tx)996 zap_add_int_key_by_dnode(dnode_t *dn,
997 uint64_t key, uint64_t value, dmu_tx_t *tx)
998 {
999 FORMAT_INT_KEY(name, key);
1000 return (zap_add_by_dnode(dn, name, 8, 1, &value, tx));
1001 }
1002
1003 int
zap_update_int_key(objset_t * os,uint64_t obj,uint64_t key,uint64_t value,dmu_tx_t * tx)1004 zap_update_int_key(objset_t *os, uint64_t obj,
1005 uint64_t key, uint64_t value, dmu_tx_t *tx)
1006 {
1007 FORMAT_INT_KEY(name, key);
1008 return (zap_update(os, obj, name, 8, 1, &value, tx));
1009 }
1010 int
zap_update_int_key_by_dnode(dnode_t * dn,uint64_t key,uint64_t value,dmu_tx_t * tx)1011 zap_update_int_key_by_dnode(dnode_t *dn,
1012 uint64_t key, uint64_t value, dmu_tx_t *tx)
1013 {
1014 FORMAT_INT_KEY(name, key);
1015 return (zap_update_by_dnode(dn, name, 8, 1, &value, tx));
1016 }
1017
1018 int
zap_lookup_int_key(objset_t * os,uint64_t obj,uint64_t key,uint64_t * valuep)1019 zap_lookup_int_key(objset_t *os, uint64_t obj, uint64_t key, uint64_t *valuep)
1020 {
1021 FORMAT_INT_KEY(name, key);
1022 return (zap_lookup(os, obj, name, 8, 1, valuep));
1023 }
1024 int
zap_lookup_int_key_by_dnode(dnode_t * dn,uint64_t key,uint64_t * valuep)1025 zap_lookup_int_key_by_dnode(dnode_t *dn, uint64_t key, uint64_t *valuep)
1026 {
1027 FORMAT_INT_KEY(name, key);
1028 return (zap_lookup_by_dnode(dn, name, 8, 1, valuep));
1029 }
1030
1031 /* zap_cursor */
1032
1033 static int
zap_cursor_init_by_dnode_impl(zap_cursor_t * zc,dnode_t * dn,uint64_t serialized,boolean_t prefetch)1034 zap_cursor_init_by_dnode_impl(zap_cursor_t *zc, dnode_t *dn,
1035 uint64_t serialized, boolean_t prefetch)
1036 {
1037 zc->zc_zap = NULL;
1038 zc->zc_leaf = NULL;
1039
1040 int err = zap_lock_by_dnode(dn, NULL, RW_READER, TRUE, FALSE,
1041 zc, &zc->zc_zap);
1042 if (err != 0)
1043 return (err);
1044
1045 zc->zc_prefetch = prefetch;
1046 zc->zc_objset = dn->dn_objset;
1047 zc->zc_zapobj = dn->dn_object;
1048
1049 int hb = zap_hashbits(zc->zc_zap);
1050 zc->zc_hash = serialized << (64 - hb);
1051 zc->zc_cd = serialized >> hb;
1052 if (zc->zc_cd >= zap_maxcd(zc->zc_zap)) /* corrupt serialized */
1053 zc->zc_cd = 0;
1054
1055 /*
1056 * Drop ZAP read lock, but keep the hold, so the holds on the
1057 * underlying dnode and header dbuf are maintained.
1058 */
1059 rw_exit(&zc->zc_zap->zap_rwlock);
1060
1061 return (0);
1062 }
1063
1064 static int
zap_cursor_init_impl(zap_cursor_t * zc,objset_t * os,uint64_t zapobj,uint64_t serialized,uint32_t prefetch)1065 zap_cursor_init_impl(zap_cursor_t *zc, objset_t *os, uint64_t zapobj,
1066 uint64_t serialized, uint32_t prefetch)
1067 {
1068 dnode_t *dn = NULL;
1069 int err = dnode_hold(os, zapobj, FTAG, &dn);
1070 if (err != 0) {
1071 zc->zc_zap = NULL;
1072 zc->zc_leaf = NULL;
1073 return (err);
1074 }
1075
1076 err = zap_cursor_init_by_dnode_impl(zc, dn, serialized, prefetch);
1077
1078 dnode_rele(dn, FTAG);
1079
1080 return (err);
1081 }
1082
1083 int
zap_cursor_init(zap_cursor_t * zc,objset_t * os,uint64_t zapobj)1084 zap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj)
1085 {
1086 return (zap_cursor_init_impl(zc, os, zapobj, 0, B_TRUE));
1087 }
1088
1089 int
zap_cursor_init_by_dnode(zap_cursor_t * zc,dnode_t * dn)1090 zap_cursor_init_by_dnode(zap_cursor_t *zc, dnode_t *dn)
1091 {
1092 return (zap_cursor_init_by_dnode_impl(zc, dn, 0, B_TRUE));
1093 }
1094
1095 int
zap_cursor_init_noprefetch(zap_cursor_t * zc,objset_t * os,uint64_t zapobj)1096 zap_cursor_init_noprefetch(zap_cursor_t *zc, objset_t *os, uint64_t zapobj)
1097 {
1098 return (zap_cursor_init_impl(zc, os, zapobj, 0, B_FALSE));
1099 }
1100
1101 int
zap_cursor_init_noprefetch_by_dnode(zap_cursor_t * zc,dnode_t * dn)1102 zap_cursor_init_noprefetch_by_dnode(zap_cursor_t *zc, dnode_t *dn)
1103 {
1104 return (zap_cursor_init_by_dnode_impl(zc, dn, 0, B_FALSE));
1105 }
1106
1107 int
zap_cursor_init_serialized(zap_cursor_t * zc,objset_t * os,uint64_t zapobj,uint64_t serialized)1108 zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, uint64_t zapobj,
1109 uint64_t serialized)
1110 {
1111 return (zap_cursor_init_impl(zc, os, zapobj, serialized, B_TRUE));
1112 }
1113
1114 int
zap_cursor_init_serialized_by_dnode(zap_cursor_t * zc,dnode_t * dn,uint64_t serialized)1115 zap_cursor_init_serialized_by_dnode(zap_cursor_t *zc, dnode_t *dn,
1116 uint64_t serialized)
1117 {
1118 return (zap_cursor_init_by_dnode_impl(zc, dn, serialized, B_TRUE));
1119 }
1120
1121 void
zap_cursor_fini(zap_cursor_t * zc)1122 zap_cursor_fini(zap_cursor_t *zc)
1123 {
1124 if (zc->zc_leaf) {
1125 rw_enter(&zc->zc_leaf->l_rwlock, RW_READER);
1126 zap_put_leaf(zc->zc_leaf);
1127 }
1128 if (zc->zc_zap) {
1129 rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
1130 zap_unlock(zc->zc_zap, zc);
1131 }
1132 memset(zc, 0, sizeof (zap_cursor_t));
1133 }
1134
1135 int
zap_cursor_retrieve(zap_cursor_t * zc,zap_attribute_t * za)1136 zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
1137 {
1138 int err;
1139
1140 if (zc->zc_zap == NULL)
1141 /* zap_cursor_init failed, cursor is invalid */
1142 return (SET_ERROR(EIO));
1143
1144 if (zc->zc_hash == -1ULL)
1145 return (SET_ERROR(ENOENT));
1146
1147 rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
1148
1149 if (!zc->zc_zap->zap_ismicro) {
1150 err = fzap_cursor_retrieve(zc->zc_zap, zc, za);
1151 } else {
1152 zfs_btree_index_t idx;
1153 mzap_ent_t mze_tofind;
1154
1155 mze_tofind.mze_hash = zc->zc_hash >> 32;
1156 mze_tofind.mze_cd = zc->zc_cd;
1157
1158 mzap_ent_t *mze = zfs_btree_find(&zc->zc_zap->zap_m.zap_tree,
1159 &mze_tofind, &idx);
1160 if (mze == NULL) {
1161 mze = zfs_btree_next(&zc->zc_zap->zap_m.zap_tree,
1162 &idx, &idx);
1163 }
1164 if (mze) {
1165 mzap_ent_phys_t *mzep = MZE_PHYS(zc->zc_zap, mze);
1166 ASSERT3U(mze->mze_cd, ==, mzep->mze_cd);
1167 za->za_normalization_conflict =
1168 mzap_normalization_conflict(zc->zc_zap, NULL,
1169 mze, &idx);
1170 za->za_integer_length = 8;
1171 za->za_num_integers = 1;
1172 za->za_first_integer = mzep->mze_value;
1173 (void) strlcpy(za->za_name, mzep->mze_name,
1174 za->za_name_len);
1175 zc->zc_hash = (uint64_t)mze->mze_hash << 32;
1176 zc->zc_cd = mze->mze_cd;
1177 err = 0;
1178 } else {
1179 zc->zc_hash = -1ULL;
1180 err = SET_ERROR(ENOENT);
1181 }
1182 }
1183
1184 rw_exit(&zc->zc_zap->zap_rwlock);
1185 return (err);
1186 }
1187
1188 void
zap_cursor_advance(zap_cursor_t * zc)1189 zap_cursor_advance(zap_cursor_t *zc)
1190 {
1191 if (zc->zc_hash == -1ULL)
1192 return;
1193 zc->zc_cd++;
1194 }
1195
1196 uint64_t
zap_cursor_serialize(zap_cursor_t * zc)1197 zap_cursor_serialize(zap_cursor_t *zc)
1198 {
1199 if (zc->zc_zap == NULL || zc->zc_hash == -1ULL)
1200 return (-1ULL);
1201
1202 ASSERT0((zc->zc_hash & zap_maxcd(zc->zc_zap)));
1203 ASSERT(zc->zc_cd < zap_maxcd(zc->zc_zap));
1204
1205 /*
1206 * We want to keep the high 32 bits of the cursor zero if we can, so
1207 * that 32-bit programs can access this. So usually use a small
1208 * (28-bit) hash value so we can fit 4 bits of cd into the low 32-bits
1209 * of the cursor.
1210 *
1211 * [ collision differentiator | zap_hashbits()-bit hash value ]
1212 */
1213 return ((zc->zc_hash >> (64 - zap_hashbits(zc->zc_zap))) |
1214 ((uint64_t)zc->zc_cd << zap_hashbits(zc->zc_zap)));
1215 }
1216
1217 /* zap_get_stats */
1218
1219 int
zap_get_stats_by_dnode(dnode_t * dn,zap_stats_t * zs)1220 zap_get_stats_by_dnode(dnode_t *dn, zap_stats_t *zs)
1221 {
1222 zap_t *zap;
1223 int err =
1224 zap_lock_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
1225 if (err != 0)
1226 return (err);
1227
1228 memset(zs, 0, sizeof (zap_stats_t));
1229
1230 if (zap->zap_ismicro) {
1231 zs->zs_blocksize = zap->zap_dbuf->db_size;
1232 zs->zs_num_entries = zap->zap_m.zap_num_entries;
1233 zs->zs_num_blocks = 1;
1234 } else {
1235 fzap_get_stats(zap, zs);
1236 }
1237 zap_unlock(zap, FTAG);
1238 return (0);
1239 }
1240
1241 int
zap_get_stats(objset_t * os,uint64_t zapobj,zap_stats_t * zs)1242 zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
1243 {
1244 dnode_t *dn;
1245 int err = dnode_hold(os, zapobj, FTAG, &dn);
1246 if (err != 0)
1247 return (err);
1248 err = zap_get_stats_by_dnode(dn, zs);
1249 dnode_rele(dn, FTAG);
1250 return (err);
1251 }
1252
1253 EXPORT_SYMBOL(zap_create);
1254 EXPORT_SYMBOL(zap_create_dnsize);
1255 EXPORT_SYMBOL(zap_create_norm);
1256 EXPORT_SYMBOL(zap_create_norm_dnsize);
1257 EXPORT_SYMBOL(zap_create_flags);
1258 EXPORT_SYMBOL(zap_create_flags_dnsize);
1259 EXPORT_SYMBOL(zap_create_claim);
1260 EXPORT_SYMBOL(zap_create_claim_norm);
1261 EXPORT_SYMBOL(zap_create_claim_norm_dnsize);
1262 EXPORT_SYMBOL(zap_create_hold);
1263 EXPORT_SYMBOL(zap_destroy);
1264 EXPORT_SYMBOL(zap_lookup);
1265 EXPORT_SYMBOL(zap_lookup_by_dnode);
1266 EXPORT_SYMBOL(zap_lookup_norm);
1267 EXPORT_SYMBOL(zap_lookup_uint64);
1268 EXPORT_SYMBOL(zap_lookup_length_uint64_by_dnode);
1269 EXPORT_SYMBOL(zap_contains);
1270 EXPORT_SYMBOL(zap_prefetch);
1271 EXPORT_SYMBOL(zap_prefetch_uint64);
1272 EXPORT_SYMBOL(zap_prefetch_object);
1273 EXPORT_SYMBOL(zap_add);
1274 EXPORT_SYMBOL(zap_add_by_dnode);
1275 EXPORT_SYMBOL(zap_add_uint64);
1276 EXPORT_SYMBOL(zap_add_uint64_by_dnode);
1277 EXPORT_SYMBOL(zap_update);
1278 EXPORT_SYMBOL(zap_update_uint64);
1279 EXPORT_SYMBOL(zap_update_uint64_by_dnode);
1280 EXPORT_SYMBOL(zap_length);
1281 EXPORT_SYMBOL(zap_length_uint64);
1282 EXPORT_SYMBOL(zap_length_uint64_by_dnode);
1283 EXPORT_SYMBOL(zap_remove);
1284 EXPORT_SYMBOL(zap_remove_by_dnode);
1285 EXPORT_SYMBOL(zap_remove_norm);
1286 EXPORT_SYMBOL(zap_remove_uint64);
1287 EXPORT_SYMBOL(zap_remove_uint64_by_dnode);
1288 EXPORT_SYMBOL(zap_count);
1289 EXPORT_SYMBOL(zap_count_by_dnode);
1290 EXPORT_SYMBOL(zap_value_search);
1291 EXPORT_SYMBOL(zap_add_int);
1292 EXPORT_SYMBOL(zap_remove_int);
1293 EXPORT_SYMBOL(zap_lookup_int);
1294 EXPORT_SYMBOL(zap_add_int_key);
1295 EXPORT_SYMBOL(zap_lookup_int_key);
1296 EXPORT_SYMBOL(zap_increment);
1297 EXPORT_SYMBOL(zap_cursor_init);
1298 EXPORT_SYMBOL(zap_cursor_fini);
1299 EXPORT_SYMBOL(zap_cursor_retrieve);
1300 EXPORT_SYMBOL(zap_cursor_advance);
1301 EXPORT_SYMBOL(zap_cursor_serialize);
1302 EXPORT_SYMBOL(zap_cursor_init_serialized);
1303 EXPORT_SYMBOL(zap_get_stats);
1304