xref: /freebsd/sys/contrib/openzfs/module/zfs/zap.c (revision d9497217456002b0ddad3cd319570d0b098daa29)
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