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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 int 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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