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