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