1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/cred.h> 27 #include <sys/zfs_context.h> 28 #include <sys/dmu_objset.h> 29 #include <sys/dsl_dir.h> 30 #include <sys/dsl_dataset.h> 31 #include <sys/dsl_prop.h> 32 #include <sys/dsl_pool.h> 33 #include <sys/dsl_synctask.h> 34 #include <sys/dsl_deleg.h> 35 #include <sys/dnode.h> 36 #include <sys/dbuf.h> 37 #include <sys/zvol.h> 38 #include <sys/dmu_tx.h> 39 #include <sys/zio_checksum.h> 40 #include <sys/zap.h> 41 #include <sys/zil.h> 42 #include <sys/dmu_impl.h> 43 #include <sys/zfs_ioctl.h> 44 45 spa_t * 46 dmu_objset_spa(objset_t *os) 47 { 48 return (os->os_spa); 49 } 50 51 zilog_t * 52 dmu_objset_zil(objset_t *os) 53 { 54 return (os->os_zil); 55 } 56 57 dsl_pool_t * 58 dmu_objset_pool(objset_t *os) 59 { 60 dsl_dataset_t *ds; 61 62 if ((ds = os->os_dsl_dataset) != NULL && ds->ds_dir) 63 return (ds->ds_dir->dd_pool); 64 else 65 return (spa_get_dsl(os->os_spa)); 66 } 67 68 dsl_dataset_t * 69 dmu_objset_ds(objset_t *os) 70 { 71 return (os->os_dsl_dataset); 72 } 73 74 dmu_objset_type_t 75 dmu_objset_type(objset_t *os) 76 { 77 return (os->os_phys->os_type); 78 } 79 80 void 81 dmu_objset_name(objset_t *os, char *buf) 82 { 83 dsl_dataset_name(os->os_dsl_dataset, buf); 84 } 85 86 uint64_t 87 dmu_objset_id(objset_t *os) 88 { 89 dsl_dataset_t *ds = os->os_dsl_dataset; 90 91 return (ds ? ds->ds_object : 0); 92 } 93 94 static void 95 checksum_changed_cb(void *arg, uint64_t newval) 96 { 97 objset_t *os = arg; 98 99 /* 100 * Inheritance should have been done by now. 101 */ 102 ASSERT(newval != ZIO_CHECKSUM_INHERIT); 103 104 os->os_checksum = zio_checksum_select(newval, ZIO_CHECKSUM_ON_VALUE); 105 } 106 107 static void 108 compression_changed_cb(void *arg, uint64_t newval) 109 { 110 objset_t *os = arg; 111 112 /* 113 * Inheritance and range checking should have been done by now. 114 */ 115 ASSERT(newval != ZIO_COMPRESS_INHERIT); 116 117 os->os_compress = zio_compress_select(newval, ZIO_COMPRESS_ON_VALUE); 118 } 119 120 static void 121 copies_changed_cb(void *arg, uint64_t newval) 122 { 123 objset_t *os = arg; 124 125 /* 126 * Inheritance and range checking should have been done by now. 127 */ 128 ASSERT(newval > 0); 129 ASSERT(newval <= spa_max_replication(os->os_spa)); 130 131 os->os_copies = newval; 132 } 133 134 static void 135 primary_cache_changed_cb(void *arg, uint64_t newval) 136 { 137 objset_t *os = arg; 138 139 /* 140 * Inheritance and range checking should have been done by now. 141 */ 142 ASSERT(newval == ZFS_CACHE_ALL || newval == ZFS_CACHE_NONE || 143 newval == ZFS_CACHE_METADATA); 144 145 os->os_primary_cache = newval; 146 } 147 148 static void 149 secondary_cache_changed_cb(void *arg, uint64_t newval) 150 { 151 objset_t *os = arg; 152 153 /* 154 * Inheritance and range checking should have been done by now. 155 */ 156 ASSERT(newval == ZFS_CACHE_ALL || newval == ZFS_CACHE_NONE || 157 newval == ZFS_CACHE_METADATA); 158 159 os->os_secondary_cache = newval; 160 } 161 162 void 163 dmu_objset_byteswap(void *buf, size_t size) 164 { 165 objset_phys_t *osp = buf; 166 167 ASSERT(size == OBJSET_OLD_PHYS_SIZE || size == sizeof (objset_phys_t)); 168 dnode_byteswap(&osp->os_meta_dnode); 169 byteswap_uint64_array(&osp->os_zil_header, sizeof (zil_header_t)); 170 osp->os_type = BSWAP_64(osp->os_type); 171 osp->os_flags = BSWAP_64(osp->os_flags); 172 if (size == sizeof (objset_phys_t)) { 173 dnode_byteswap(&osp->os_userused_dnode); 174 dnode_byteswap(&osp->os_groupused_dnode); 175 } 176 } 177 178 int 179 dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, 180 objset_t **osp) 181 { 182 objset_t *os; 183 int i, err; 184 185 ASSERT(ds == NULL || MUTEX_HELD(&ds->ds_opening_lock)); 186 187 os = kmem_zalloc(sizeof (objset_t), KM_SLEEP); 188 os->os_dsl_dataset = ds; 189 os->os_spa = spa; 190 os->os_rootbp = bp; 191 if (!BP_IS_HOLE(os->os_rootbp)) { 192 uint32_t aflags = ARC_WAIT; 193 zbookmark_t zb; 194 zb.zb_objset = ds ? ds->ds_object : 0; 195 zb.zb_object = 0; 196 zb.zb_level = -1; 197 zb.zb_blkid = 0; 198 if (DMU_OS_IS_L2CACHEABLE(os)) 199 aflags |= ARC_L2CACHE; 200 201 dprintf_bp(os->os_rootbp, "reading %s", ""); 202 /* 203 * NB: when bprewrite scrub can change the bp, 204 * and this is called from dmu_objset_open_ds_os, the bp 205 * could change, and we'll need a lock. 206 */ 207 err = arc_read_nolock(NULL, spa, os->os_rootbp, 208 arc_getbuf_func, &os->os_phys_buf, 209 ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL, &aflags, &zb); 210 if (err) { 211 kmem_free(os, sizeof (objset_t)); 212 /* convert checksum errors into IO errors */ 213 if (err == ECKSUM) 214 err = EIO; 215 return (err); 216 } 217 218 /* Increase the blocksize if we are permitted. */ 219 if (spa_version(spa) >= SPA_VERSION_USERSPACE && 220 arc_buf_size(os->os_phys_buf) < sizeof (objset_phys_t)) { 221 arc_buf_t *buf = arc_buf_alloc(spa, 222 sizeof (objset_phys_t), &os->os_phys_buf, 223 ARC_BUFC_METADATA); 224 bzero(buf->b_data, sizeof (objset_phys_t)); 225 bcopy(os->os_phys_buf->b_data, buf->b_data, 226 arc_buf_size(os->os_phys_buf)); 227 (void) arc_buf_remove_ref(os->os_phys_buf, 228 &os->os_phys_buf); 229 os->os_phys_buf = buf; 230 } 231 232 os->os_phys = os->os_phys_buf->b_data; 233 os->os_flags = os->os_phys->os_flags; 234 } else { 235 int size = spa_version(spa) >= SPA_VERSION_USERSPACE ? 236 sizeof (objset_phys_t) : OBJSET_OLD_PHYS_SIZE; 237 os->os_phys_buf = arc_buf_alloc(spa, size, 238 &os->os_phys_buf, ARC_BUFC_METADATA); 239 os->os_phys = os->os_phys_buf->b_data; 240 bzero(os->os_phys, size); 241 } 242 243 /* 244 * Note: the changed_cb will be called once before the register 245 * func returns, thus changing the checksum/compression from the 246 * default (fletcher2/off). Snapshots don't need to know about 247 * checksum/compression/copies. 248 */ 249 if (ds) { 250 err = dsl_prop_register(ds, "primarycache", 251 primary_cache_changed_cb, os); 252 if (err == 0) 253 err = dsl_prop_register(ds, "secondarycache", 254 secondary_cache_changed_cb, os); 255 if (!dsl_dataset_is_snapshot(ds)) { 256 if (err == 0) 257 err = dsl_prop_register(ds, "checksum", 258 checksum_changed_cb, os); 259 if (err == 0) 260 err = dsl_prop_register(ds, "compression", 261 compression_changed_cb, os); 262 if (err == 0) 263 err = dsl_prop_register(ds, "copies", 264 copies_changed_cb, os); 265 } 266 if (err) { 267 VERIFY(arc_buf_remove_ref(os->os_phys_buf, 268 &os->os_phys_buf) == 1); 269 kmem_free(os, sizeof (objset_t)); 270 return (err); 271 } 272 } else if (ds == NULL) { 273 /* It's the meta-objset. */ 274 os->os_checksum = ZIO_CHECKSUM_FLETCHER_4; 275 os->os_compress = ZIO_COMPRESS_LZJB; 276 os->os_copies = spa_max_replication(spa); 277 os->os_primary_cache = ZFS_CACHE_ALL; 278 os->os_secondary_cache = ZFS_CACHE_ALL; 279 } 280 281 os->os_zil_header = os->os_phys->os_zil_header; 282 os->os_zil = zil_alloc(os, &os->os_zil_header); 283 284 for (i = 0; i < TXG_SIZE; i++) { 285 list_create(&os->os_dirty_dnodes[i], sizeof (dnode_t), 286 offsetof(dnode_t, dn_dirty_link[i])); 287 list_create(&os->os_free_dnodes[i], sizeof (dnode_t), 288 offsetof(dnode_t, dn_dirty_link[i])); 289 } 290 list_create(&os->os_dnodes, sizeof (dnode_t), 291 offsetof(dnode_t, dn_link)); 292 list_create(&os->os_downgraded_dbufs, sizeof (dmu_buf_impl_t), 293 offsetof(dmu_buf_impl_t, db_link)); 294 295 mutex_init(&os->os_lock, NULL, MUTEX_DEFAULT, NULL); 296 mutex_init(&os->os_obj_lock, NULL, MUTEX_DEFAULT, NULL); 297 mutex_init(&os->os_user_ptr_lock, NULL, MUTEX_DEFAULT, NULL); 298 299 os->os_meta_dnode = dnode_special_open(os, 300 &os->os_phys->os_meta_dnode, DMU_META_DNODE_OBJECT); 301 if (arc_buf_size(os->os_phys_buf) >= sizeof (objset_phys_t)) { 302 os->os_userused_dnode = dnode_special_open(os, 303 &os->os_phys->os_userused_dnode, DMU_USERUSED_OBJECT); 304 os->os_groupused_dnode = dnode_special_open(os, 305 &os->os_phys->os_groupused_dnode, DMU_GROUPUSED_OBJECT); 306 } 307 308 /* 309 * We should be the only thread trying to do this because we 310 * have ds_opening_lock 311 */ 312 if (ds) { 313 mutex_enter(&ds->ds_lock); 314 ASSERT(ds->ds_objset == NULL); 315 ds->ds_objset = os; 316 mutex_exit(&ds->ds_lock); 317 } 318 319 *osp = os; 320 return (0); 321 } 322 323 int 324 dmu_objset_from_ds(dsl_dataset_t *ds, objset_t **osp) 325 { 326 int err = 0; 327 328 mutex_enter(&ds->ds_opening_lock); 329 *osp = ds->ds_objset; 330 if (*osp == NULL) { 331 err = dmu_objset_open_impl(dsl_dataset_get_spa(ds), 332 ds, &ds->ds_phys->ds_bp, osp); 333 } 334 mutex_exit(&ds->ds_opening_lock); 335 return (err); 336 } 337 338 /* called from zpl */ 339 int 340 dmu_objset_hold(const char *name, void *tag, objset_t **osp) 341 { 342 dsl_dataset_t *ds; 343 int err; 344 345 err = dsl_dataset_hold(name, tag, &ds); 346 if (err) 347 return (err); 348 349 err = dmu_objset_from_ds(ds, osp); 350 if (err) 351 dsl_dataset_rele(ds, tag); 352 353 return (err); 354 } 355 356 /* called from zpl */ 357 int 358 dmu_objset_own(const char *name, dmu_objset_type_t type, 359 boolean_t readonly, void *tag, objset_t **osp) 360 { 361 dsl_dataset_t *ds; 362 int err; 363 364 err = dsl_dataset_own(name, B_FALSE, tag, &ds); 365 if (err) 366 return (err); 367 368 err = dmu_objset_from_ds(ds, osp); 369 if (err) { 370 dsl_dataset_disown(ds, tag); 371 } else if ((type != DMU_OST_ANY && type != (*osp)->os_phys->os_type) || 372 (!readonly && dsl_dataset_is_snapshot(ds))) { 373 dmu_objset_disown(*osp, tag); 374 return (EINVAL); 375 } 376 377 return (err); 378 } 379 380 void 381 dmu_objset_rele(objset_t *os, void *tag) 382 { 383 dsl_dataset_rele(os->os_dsl_dataset, tag); 384 } 385 386 void 387 dmu_objset_disown(objset_t *os, void *tag) 388 { 389 dsl_dataset_disown(os->os_dsl_dataset, tag); 390 } 391 392 int 393 dmu_objset_evict_dbufs(objset_t *os) 394 { 395 dnode_t *dn; 396 397 mutex_enter(&os->os_lock); 398 399 /* process the mdn last, since the other dnodes have holds on it */ 400 list_remove(&os->os_dnodes, os->os_meta_dnode); 401 list_insert_tail(&os->os_dnodes, os->os_meta_dnode); 402 403 /* 404 * Find the first dnode with holds. We have to do this dance 405 * because dnode_add_ref() only works if you already have a 406 * hold. If there are no holds then it has no dbufs so OK to 407 * skip. 408 */ 409 for (dn = list_head(&os->os_dnodes); 410 dn && !dnode_add_ref(dn, FTAG); 411 dn = list_next(&os->os_dnodes, dn)) 412 continue; 413 414 while (dn) { 415 dnode_t *next_dn = dn; 416 417 do { 418 next_dn = list_next(&os->os_dnodes, next_dn); 419 } while (next_dn && !dnode_add_ref(next_dn, FTAG)); 420 421 mutex_exit(&os->os_lock); 422 dnode_evict_dbufs(dn); 423 dnode_rele(dn, FTAG); 424 mutex_enter(&os->os_lock); 425 dn = next_dn; 426 } 427 mutex_exit(&os->os_lock); 428 return (list_head(&os->os_dnodes) != os->os_meta_dnode); 429 } 430 431 void 432 dmu_objset_evict(objset_t *os) 433 { 434 dsl_dataset_t *ds = os->os_dsl_dataset; 435 int i; 436 437 for (i = 0; i < TXG_SIZE; i++) { 438 ASSERT(list_head(&os->os_dirty_dnodes[i]) == NULL); 439 ASSERT(list_head(&os->os_free_dnodes[i]) == NULL); 440 } 441 442 if (ds) { 443 if (!dsl_dataset_is_snapshot(ds)) { 444 VERIFY(0 == dsl_prop_unregister(ds, "checksum", 445 checksum_changed_cb, os)); 446 VERIFY(0 == dsl_prop_unregister(ds, "compression", 447 compression_changed_cb, os)); 448 VERIFY(0 == dsl_prop_unregister(ds, "copies", 449 copies_changed_cb, os)); 450 } 451 VERIFY(0 == dsl_prop_unregister(ds, "primarycache", 452 primary_cache_changed_cb, os)); 453 VERIFY(0 == dsl_prop_unregister(ds, "secondarycache", 454 secondary_cache_changed_cb, os)); 455 } 456 457 /* 458 * We should need only a single pass over the dnode list, since 459 * nothing can be added to the list at this point. 460 */ 461 (void) dmu_objset_evict_dbufs(os); 462 463 dnode_special_close(os->os_meta_dnode); 464 if (os->os_userused_dnode) { 465 dnode_special_close(os->os_userused_dnode); 466 dnode_special_close(os->os_groupused_dnode); 467 } 468 zil_free(os->os_zil); 469 470 ASSERT3P(list_head(&os->os_dnodes), ==, NULL); 471 472 VERIFY(arc_buf_remove_ref(os->os_phys_buf, &os->os_phys_buf) == 1); 473 mutex_destroy(&os->os_lock); 474 mutex_destroy(&os->os_obj_lock); 475 mutex_destroy(&os->os_user_ptr_lock); 476 kmem_free(os, sizeof (objset_t)); 477 } 478 479 /* called from dsl for meta-objset */ 480 objset_t * 481 dmu_objset_create_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, 482 dmu_objset_type_t type, dmu_tx_t *tx) 483 { 484 objset_t *os; 485 dnode_t *mdn; 486 487 ASSERT(dmu_tx_is_syncing(tx)); 488 if (ds) 489 mutex_enter(&ds->ds_opening_lock); 490 VERIFY(0 == dmu_objset_open_impl(spa, ds, bp, &os)); 491 if (ds) 492 mutex_exit(&ds->ds_opening_lock); 493 mdn = os->os_meta_dnode; 494 495 dnode_allocate(mdn, DMU_OT_DNODE, 1 << DNODE_BLOCK_SHIFT, 496 DN_MAX_INDBLKSHIFT, DMU_OT_NONE, 0, tx); 497 498 /* 499 * We don't want to have to increase the meta-dnode's nlevels 500 * later, because then we could do it in quescing context while 501 * we are also accessing it in open context. 502 * 503 * This precaution is not necessary for the MOS (ds == NULL), 504 * because the MOS is only updated in syncing context. 505 * This is most fortunate: the MOS is the only objset that 506 * needs to be synced multiple times as spa_sync() iterates 507 * to convergence, so minimizing its dn_nlevels matters. 508 */ 509 if (ds != NULL) { 510 int levels = 1; 511 512 /* 513 * Determine the number of levels necessary for the meta-dnode 514 * to contain DN_MAX_OBJECT dnodes. 515 */ 516 while ((uint64_t)mdn->dn_nblkptr << (mdn->dn_datablkshift + 517 (levels - 1) * (mdn->dn_indblkshift - SPA_BLKPTRSHIFT)) < 518 DN_MAX_OBJECT * sizeof (dnode_phys_t)) 519 levels++; 520 521 mdn->dn_next_nlevels[tx->tx_txg & TXG_MASK] = 522 mdn->dn_nlevels = levels; 523 } 524 525 ASSERT(type != DMU_OST_NONE); 526 ASSERT(type != DMU_OST_ANY); 527 ASSERT(type < DMU_OST_NUMTYPES); 528 os->os_phys->os_type = type; 529 if (dmu_objset_userused_enabled(os)) { 530 os->os_phys->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE; 531 os->os_flags = os->os_phys->os_flags; 532 } 533 534 dsl_dataset_dirty(ds, tx); 535 536 return (os); 537 } 538 539 struct oscarg { 540 void (*userfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx); 541 void *userarg; 542 dsl_dataset_t *clone_origin; 543 const char *lastname; 544 dmu_objset_type_t type; 545 uint64_t flags; 546 }; 547 548 /*ARGSUSED*/ 549 static int 550 dmu_objset_create_check(void *arg1, void *arg2, dmu_tx_t *tx) 551 { 552 dsl_dir_t *dd = arg1; 553 struct oscarg *oa = arg2; 554 objset_t *mos = dd->dd_pool->dp_meta_objset; 555 int err; 556 uint64_t ddobj; 557 558 err = zap_lookup(mos, dd->dd_phys->dd_child_dir_zapobj, 559 oa->lastname, sizeof (uint64_t), 1, &ddobj); 560 if (err != ENOENT) 561 return (err ? err : EEXIST); 562 563 if (oa->clone_origin != NULL) { 564 /* You can't clone across pools. */ 565 if (oa->clone_origin->ds_dir->dd_pool != dd->dd_pool) 566 return (EXDEV); 567 568 /* You can only clone snapshots, not the head datasets. */ 569 if (!dsl_dataset_is_snapshot(oa->clone_origin)) 570 return (EINVAL); 571 } 572 573 return (0); 574 } 575 576 static void 577 dmu_objset_create_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) 578 { 579 dsl_dir_t *dd = arg1; 580 struct oscarg *oa = arg2; 581 uint64_t dsobj; 582 583 ASSERT(dmu_tx_is_syncing(tx)); 584 585 dsobj = dsl_dataset_create_sync(dd, oa->lastname, 586 oa->clone_origin, oa->flags, cr, tx); 587 588 if (oa->clone_origin == NULL) { 589 dsl_dataset_t *ds; 590 blkptr_t *bp; 591 objset_t *os; 592 593 VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool, dsobj, 594 FTAG, &ds)); 595 bp = dsl_dataset_get_blkptr(ds); 596 ASSERT(BP_IS_HOLE(bp)); 597 598 os = dmu_objset_create_impl(dsl_dataset_get_spa(ds), 599 ds, bp, oa->type, tx); 600 601 if (oa->userfunc) 602 oa->userfunc(os, oa->userarg, cr, tx); 603 dsl_dataset_rele(ds, FTAG); 604 } 605 606 spa_history_internal_log(LOG_DS_CREATE, dd->dd_pool->dp_spa, 607 tx, cr, "dataset = %llu", dsobj); 608 } 609 610 int 611 dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags, 612 void (*func)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx), void *arg) 613 { 614 dsl_dir_t *pdd; 615 const char *tail; 616 int err = 0; 617 struct oscarg oa = { 0 }; 618 619 ASSERT(strchr(name, '@') == NULL); 620 err = dsl_dir_open(name, FTAG, &pdd, &tail); 621 if (err) 622 return (err); 623 if (tail == NULL) { 624 dsl_dir_close(pdd, FTAG); 625 return (EEXIST); 626 } 627 628 oa.userfunc = func; 629 oa.userarg = arg; 630 oa.lastname = tail; 631 oa.type = type; 632 oa.flags = flags; 633 634 err = dsl_sync_task_do(pdd->dd_pool, dmu_objset_create_check, 635 dmu_objset_create_sync, pdd, &oa, 5); 636 dsl_dir_close(pdd, FTAG); 637 return (err); 638 } 639 640 int 641 dmu_objset_clone(const char *name, dsl_dataset_t *clone_origin, uint64_t flags) 642 { 643 dsl_dir_t *pdd; 644 const char *tail; 645 int err = 0; 646 struct oscarg oa = { 0 }; 647 648 ASSERT(strchr(name, '@') == NULL); 649 err = dsl_dir_open(name, FTAG, &pdd, &tail); 650 if (err) 651 return (err); 652 if (tail == NULL) { 653 dsl_dir_close(pdd, FTAG); 654 return (EEXIST); 655 } 656 657 oa.lastname = tail; 658 oa.clone_origin = clone_origin; 659 oa.flags = flags; 660 661 err = dsl_sync_task_do(pdd->dd_pool, dmu_objset_create_check, 662 dmu_objset_create_sync, pdd, &oa, 5); 663 dsl_dir_close(pdd, FTAG); 664 return (err); 665 } 666 667 int 668 dmu_objset_destroy(const char *name, boolean_t defer) 669 { 670 dsl_dataset_t *ds; 671 int error; 672 673 /* 674 * dsl_dataset_destroy() can free any claimed-but-unplayed 675 * intent log, but if there is an active log, it has blocks that 676 * are allocated, but may not yet be reflected in the on-disk 677 * structure. Only the ZIL knows how to free them, so we have 678 * to call into it here. 679 */ 680 error = dsl_dataset_own(name, B_TRUE, FTAG, &ds); 681 if (error == 0) { 682 objset_t *os; 683 if (dmu_objset_from_ds(ds, &os) == 0) 684 zil_destroy(dmu_objset_zil(os), B_FALSE); 685 error = dsl_dataset_destroy(ds, FTAG, defer); 686 /* dsl_dataset_destroy() closes the ds. */ 687 } 688 689 return (error); 690 } 691 692 struct snaparg { 693 dsl_sync_task_group_t *dstg; 694 char *snapname; 695 char failed[MAXPATHLEN]; 696 boolean_t checkperms; 697 nvlist_t *props; 698 }; 699 700 static int 701 snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx) 702 { 703 objset_t *os = arg1; 704 struct snaparg *sn = arg2; 705 706 /* The props have already been checked by zfs_check_userprops(). */ 707 708 return (dsl_dataset_snapshot_check(os->os_dsl_dataset, 709 sn->snapname, tx)); 710 } 711 712 static void 713 snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) 714 { 715 objset_t *os = arg1; 716 dsl_dataset_t *ds = os->os_dsl_dataset; 717 struct snaparg *sn = arg2; 718 719 dsl_dataset_snapshot_sync(ds, sn->snapname, cr, tx); 720 721 if (sn->props) 722 dsl_props_set_sync(ds->ds_prev, sn->props, cr, tx); 723 } 724 725 static int 726 dmu_objset_snapshot_one(char *name, void *arg) 727 { 728 struct snaparg *sn = arg; 729 objset_t *os; 730 int err; 731 732 (void) strcpy(sn->failed, name); 733 734 /* 735 * Check permissions only when requested. This only applies when 736 * doing a recursive snapshot. The permission checks for the starting 737 * dataset have already been performed in zfs_secpolicy_snapshot() 738 */ 739 if (sn->checkperms == B_TRUE && 740 (err = zfs_secpolicy_snapshot_perms(name, CRED()))) 741 return (err); 742 743 err = dmu_objset_hold(name, sn, &os); 744 if (err != 0) 745 return (err); 746 747 /* If the objset is in an inconsistent state, return busy */ 748 if (os->os_dsl_dataset->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) { 749 dmu_objset_rele(os, sn); 750 return (EBUSY); 751 } 752 753 /* 754 * NB: we need to wait for all in-flight changes to get to disk, 755 * so that we snapshot those changes. zil_suspend does this as 756 * a side effect. 757 */ 758 err = zil_suspend(dmu_objset_zil(os)); 759 if (err == 0) { 760 dsl_sync_task_create(sn->dstg, snapshot_check, 761 snapshot_sync, os, sn, 3); 762 } else { 763 dmu_objset_rele(os, sn); 764 } 765 766 return (err); 767 } 768 769 int 770 dmu_objset_snapshot(char *fsname, char *snapname, 771 nvlist_t *props, boolean_t recursive) 772 { 773 dsl_sync_task_t *dst; 774 struct snaparg sn; 775 spa_t *spa; 776 int err; 777 778 (void) strcpy(sn.failed, fsname); 779 780 err = spa_open(fsname, &spa, FTAG); 781 if (err) 782 return (err); 783 784 sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); 785 sn.snapname = snapname; 786 sn.props = props; 787 788 if (recursive) { 789 sn.checkperms = B_TRUE; 790 err = dmu_objset_find(fsname, 791 dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN); 792 } else { 793 sn.checkperms = B_FALSE; 794 err = dmu_objset_snapshot_one(fsname, &sn); 795 } 796 797 if (err == 0) 798 err = dsl_sync_task_group_wait(sn.dstg); 799 800 for (dst = list_head(&sn.dstg->dstg_tasks); dst; 801 dst = list_next(&sn.dstg->dstg_tasks, dst)) { 802 objset_t *os = dst->dst_arg1; 803 dsl_dataset_t *ds = os->os_dsl_dataset; 804 if (dst->dst_err) 805 dsl_dataset_name(ds, sn.failed); 806 zil_resume(dmu_objset_zil(os)); 807 dmu_objset_rele(os, &sn); 808 } 809 810 if (err) 811 (void) strcpy(fsname, sn.failed); 812 dsl_sync_task_group_destroy(sn.dstg); 813 spa_close(spa, FTAG); 814 return (err); 815 } 816 817 static void 818 dmu_objset_sync_dnodes(list_t *list, list_t *newlist, dmu_tx_t *tx) 819 { 820 dnode_t *dn; 821 822 while (dn = list_head(list)) { 823 ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT); 824 ASSERT(dn->dn_dbuf->db_data_pending); 825 /* 826 * Initialize dn_zio outside dnode_sync() because the 827 * meta-dnode needs to set it ouside dnode_sync(). 828 */ 829 dn->dn_zio = dn->dn_dbuf->db_data_pending->dr_zio; 830 ASSERT(dn->dn_zio); 831 832 ASSERT3U(dn->dn_nlevels, <=, DN_MAX_LEVELS); 833 list_remove(list, dn); 834 835 if (newlist) { 836 (void) dnode_add_ref(dn, newlist); 837 list_insert_tail(newlist, dn); 838 } 839 840 dnode_sync(dn, tx); 841 } 842 } 843 844 /* ARGSUSED */ 845 static void 846 ready(zio_t *zio, arc_buf_t *abuf, void *arg) 847 { 848 blkptr_t *bp = zio->io_bp; 849 blkptr_t *bp_orig = &zio->io_bp_orig; 850 objset_t *os = arg; 851 dnode_phys_t *dnp = &os->os_phys->os_meta_dnode; 852 853 ASSERT(bp == os->os_rootbp); 854 ASSERT(BP_GET_TYPE(bp) == DMU_OT_OBJSET); 855 ASSERT(BP_GET_LEVEL(bp) == 0); 856 857 /* 858 * Update rootbp fill count: it should be the number of objects 859 * allocated in the object set (not counting the "special" 860 * objects that are stored in the objset_phys_t -- the meta 861 * dnode and user/group accounting objects). 862 */ 863 bp->blk_fill = 0; 864 for (int i = 0; i < dnp->dn_nblkptr; i++) 865 bp->blk_fill += dnp->dn_blkptr[i].blk_fill; 866 867 if (zio->io_flags & ZIO_FLAG_IO_REWRITE) { 868 ASSERT(DVA_EQUAL(BP_IDENTITY(bp), BP_IDENTITY(bp_orig))); 869 } else { 870 if (zio->io_bp_orig.blk_birth == os->os_synctx->tx_txg) 871 (void) dsl_dataset_block_kill(os->os_dsl_dataset, 872 &zio->io_bp_orig, zio, os->os_synctx); 873 dsl_dataset_block_born(os->os_dsl_dataset, bp, os->os_synctx); 874 } 875 } 876 877 /* called from dsl */ 878 void 879 dmu_objset_sync(objset_t *os, zio_t *pio, dmu_tx_t *tx) 880 { 881 int txgoff; 882 zbookmark_t zb; 883 writeprops_t wp = { 0 }; 884 zio_t *zio; 885 list_t *list; 886 list_t *newlist = NULL; 887 dbuf_dirty_record_t *dr; 888 889 dprintf_ds(os->os_dsl_dataset, "txg=%llu\n", tx->tx_txg); 890 891 ASSERT(dmu_tx_is_syncing(tx)); 892 /* XXX the write_done callback should really give us the tx... */ 893 os->os_synctx = tx; 894 895 if (os->os_dsl_dataset == NULL) { 896 /* 897 * This is the MOS. If we have upgraded, 898 * spa_max_replication() could change, so reset 899 * os_copies here. 900 */ 901 os->os_copies = spa_max_replication(os->os_spa); 902 } 903 904 /* 905 * Create the root block IO 906 */ 907 zb.zb_objset = os->os_dsl_dataset ? os->os_dsl_dataset->ds_object : 0; 908 zb.zb_object = 0; 909 zb.zb_level = -1; /* for block ordering; it's level 0 on disk */ 910 zb.zb_blkid = 0; 911 912 wp.wp_type = DMU_OT_OBJSET; 913 wp.wp_level = 0; /* on-disk BP level; see above */ 914 wp.wp_copies = os->os_copies; 915 wp.wp_oschecksum = os->os_checksum; 916 wp.wp_oscompress = os->os_compress; 917 918 if (BP_IS_OLDER(os->os_rootbp, tx->tx_txg)) { 919 (void) dsl_dataset_block_kill(os->os_dsl_dataset, 920 os->os_rootbp, pio, tx); 921 } 922 923 arc_release(os->os_phys_buf, &os->os_phys_buf); 924 925 zio = arc_write(pio, os->os_spa, &wp, DMU_OS_IS_L2CACHEABLE(os), 926 tx->tx_txg, os->os_rootbp, os->os_phys_buf, ready, NULL, os, 927 ZIO_PRIORITY_ASYNC_WRITE, ZIO_FLAG_MUSTSUCCEED, &zb); 928 929 /* 930 * Sync special dnodes - the parent IO for the sync is the root block 931 */ 932 os->os_meta_dnode->dn_zio = zio; 933 dnode_sync(os->os_meta_dnode, tx); 934 935 os->os_phys->os_flags = os->os_flags; 936 937 if (os->os_userused_dnode && 938 os->os_userused_dnode->dn_type != DMU_OT_NONE) { 939 os->os_userused_dnode->dn_zio = zio; 940 dnode_sync(os->os_userused_dnode, tx); 941 os->os_groupused_dnode->dn_zio = zio; 942 dnode_sync(os->os_groupused_dnode, tx); 943 } 944 945 txgoff = tx->tx_txg & TXG_MASK; 946 947 if (dmu_objset_userused_enabled(os)) { 948 newlist = &os->os_synced_dnodes; 949 /* 950 * We must create the list here because it uses the 951 * dn_dirty_link[] of this txg. 952 */ 953 list_create(newlist, sizeof (dnode_t), 954 offsetof(dnode_t, dn_dirty_link[txgoff])); 955 } 956 957 dmu_objset_sync_dnodes(&os->os_free_dnodes[txgoff], newlist, tx); 958 dmu_objset_sync_dnodes(&os->os_dirty_dnodes[txgoff], newlist, tx); 959 960 list = &os->os_meta_dnode->dn_dirty_records[txgoff]; 961 while (dr = list_head(list)) { 962 ASSERT(dr->dr_dbuf->db_level == 0); 963 list_remove(list, dr); 964 if (dr->dr_zio) 965 zio_nowait(dr->dr_zio); 966 } 967 /* 968 * Free intent log blocks up to this tx. 969 */ 970 zil_sync(os->os_zil, tx); 971 os->os_phys->os_zil_header = os->os_zil_header; 972 zio_nowait(zio); 973 } 974 975 static objset_used_cb_t *used_cbs[DMU_OST_NUMTYPES]; 976 977 void 978 dmu_objset_register_type(dmu_objset_type_t ost, objset_used_cb_t *cb) 979 { 980 used_cbs[ost] = cb; 981 } 982 983 boolean_t 984 dmu_objset_userused_enabled(objset_t *os) 985 { 986 return (spa_version(os->os_spa) >= SPA_VERSION_USERSPACE && 987 used_cbs[os->os_phys->os_type] && 988 os->os_userused_dnode); 989 } 990 991 void 992 dmu_objset_do_userquota_callbacks(objset_t *os, dmu_tx_t *tx) 993 { 994 dnode_t *dn; 995 list_t *list = &os->os_synced_dnodes; 996 static const char zerobuf[DN_MAX_BONUSLEN] = {0}; 997 998 ASSERT(list_head(list) == NULL || dmu_objset_userused_enabled(os)); 999 1000 while (dn = list_head(list)) { 1001 dmu_object_type_t bonustype; 1002 1003 ASSERT(!DMU_OBJECT_IS_SPECIAL(dn->dn_object)); 1004 ASSERT(dn->dn_oldphys); 1005 ASSERT(dn->dn_phys->dn_type == DMU_OT_NONE || 1006 dn->dn_phys->dn_flags & 1007 DNODE_FLAG_USERUSED_ACCOUNTED); 1008 1009 /* Allocate the user/groupused objects if necessary. */ 1010 if (os->os_userused_dnode->dn_type == DMU_OT_NONE) { 1011 VERIFY(0 == zap_create_claim(os, 1012 DMU_USERUSED_OBJECT, 1013 DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx)); 1014 VERIFY(0 == zap_create_claim(os, 1015 DMU_GROUPUSED_OBJECT, 1016 DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx)); 1017 } 1018 1019 /* 1020 * If the object was not previously 1021 * accounted, pretend that it was free. 1022 */ 1023 if (!(dn->dn_oldphys->dn_flags & 1024 DNODE_FLAG_USERUSED_ACCOUNTED)) { 1025 bzero(dn->dn_oldphys, sizeof (dnode_phys_t)); 1026 } 1027 1028 /* 1029 * If the object was freed, use the previous bonustype. 1030 */ 1031 bonustype = dn->dn_phys->dn_bonustype ? 1032 dn->dn_phys->dn_bonustype : dn->dn_oldphys->dn_bonustype; 1033 ASSERT(dn->dn_phys->dn_type != 0 || 1034 (bcmp(DN_BONUS(dn->dn_phys), zerobuf, 1035 DN_MAX_BONUSLEN) == 0 && 1036 DN_USED_BYTES(dn->dn_phys) == 0)); 1037 ASSERT(dn->dn_oldphys->dn_type != 0 || 1038 (bcmp(DN_BONUS(dn->dn_oldphys), zerobuf, 1039 DN_MAX_BONUSLEN) == 0 && 1040 DN_USED_BYTES(dn->dn_oldphys) == 0)); 1041 used_cbs[os->os_phys->os_type](os, bonustype, 1042 DN_BONUS(dn->dn_oldphys), DN_BONUS(dn->dn_phys), 1043 DN_USED_BYTES(dn->dn_oldphys), 1044 DN_USED_BYTES(dn->dn_phys), tx); 1045 1046 /* 1047 * The mutex is needed here for interlock with dnode_allocate. 1048 */ 1049 mutex_enter(&dn->dn_mtx); 1050 zio_buf_free(dn->dn_oldphys, sizeof (dnode_phys_t)); 1051 dn->dn_oldphys = NULL; 1052 mutex_exit(&dn->dn_mtx); 1053 1054 list_remove(list, dn); 1055 dnode_rele(dn, list); 1056 } 1057 } 1058 1059 boolean_t 1060 dmu_objset_userspace_present(objset_t *os) 1061 { 1062 return (os->os_phys->os_flags & 1063 OBJSET_FLAG_USERACCOUNTING_COMPLETE); 1064 } 1065 1066 int 1067 dmu_objset_userspace_upgrade(objset_t *os) 1068 { 1069 uint64_t obj; 1070 int err = 0; 1071 1072 if (dmu_objset_userspace_present(os)) 1073 return (0); 1074 if (!dmu_objset_userused_enabled(os)) 1075 return (ENOTSUP); 1076 if (dmu_objset_is_snapshot(os)) 1077 return (EINVAL); 1078 1079 /* 1080 * We simply need to mark every object dirty, so that it will be 1081 * synced out and now accounted. If this is called 1082 * concurrently, or if we already did some work before crashing, 1083 * that's fine, since we track each object's accounted state 1084 * independently. 1085 */ 1086 1087 for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE, 0)) { 1088 dmu_tx_t *tx; 1089 dmu_buf_t *db; 1090 int objerr; 1091 1092 if (issig(JUSTLOOKING) && issig(FORREAL)) 1093 return (EINTR); 1094 1095 objerr = dmu_bonus_hold(os, obj, FTAG, &db); 1096 if (objerr) 1097 continue; 1098 tx = dmu_tx_create(os); 1099 dmu_tx_hold_bonus(tx, obj); 1100 objerr = dmu_tx_assign(tx, TXG_WAIT); 1101 if (objerr) { 1102 dmu_tx_abort(tx); 1103 continue; 1104 } 1105 dmu_buf_will_dirty(db, tx); 1106 dmu_buf_rele(db, FTAG); 1107 dmu_tx_commit(tx); 1108 } 1109 1110 os->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE; 1111 txg_wait_synced(dmu_objset_pool(os), 0); 1112 return (0); 1113 } 1114 1115 void 1116 dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp, 1117 uint64_t *usedobjsp, uint64_t *availobjsp) 1118 { 1119 dsl_dataset_space(os->os_dsl_dataset, refdbytesp, availbytesp, 1120 usedobjsp, availobjsp); 1121 } 1122 1123 uint64_t 1124 dmu_objset_fsid_guid(objset_t *os) 1125 { 1126 return (dsl_dataset_fsid_guid(os->os_dsl_dataset)); 1127 } 1128 1129 void 1130 dmu_objset_fast_stat(objset_t *os, dmu_objset_stats_t *stat) 1131 { 1132 stat->dds_type = os->os_phys->os_type; 1133 if (os->os_dsl_dataset) 1134 dsl_dataset_fast_stat(os->os_dsl_dataset, stat); 1135 } 1136 1137 void 1138 dmu_objset_stats(objset_t *os, nvlist_t *nv) 1139 { 1140 ASSERT(os->os_dsl_dataset || 1141 os->os_phys->os_type == DMU_OST_META); 1142 1143 if (os->os_dsl_dataset != NULL) 1144 dsl_dataset_stats(os->os_dsl_dataset, nv); 1145 1146 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_TYPE, 1147 os->os_phys->os_type); 1148 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USERACCOUNTING, 1149 dmu_objset_userspace_present(os)); 1150 } 1151 1152 int 1153 dmu_objset_is_snapshot(objset_t *os) 1154 { 1155 if (os->os_dsl_dataset != NULL) 1156 return (dsl_dataset_is_snapshot(os->os_dsl_dataset)); 1157 else 1158 return (B_FALSE); 1159 } 1160 1161 int 1162 dmu_snapshot_realname(objset_t *os, char *name, char *real, int maxlen, 1163 boolean_t *conflict) 1164 { 1165 dsl_dataset_t *ds = os->os_dsl_dataset; 1166 uint64_t ignored; 1167 1168 if (ds->ds_phys->ds_snapnames_zapobj == 0) 1169 return (ENOENT); 1170 1171 return (zap_lookup_norm(ds->ds_dir->dd_pool->dp_meta_objset, 1172 ds->ds_phys->ds_snapnames_zapobj, name, 8, 1, &ignored, MT_FIRST, 1173 real, maxlen, conflict)); 1174 } 1175 1176 int 1177 dmu_snapshot_list_next(objset_t *os, int namelen, char *name, 1178 uint64_t *idp, uint64_t *offp, boolean_t *case_conflict) 1179 { 1180 dsl_dataset_t *ds = os->os_dsl_dataset; 1181 zap_cursor_t cursor; 1182 zap_attribute_t attr; 1183 1184 if (ds->ds_phys->ds_snapnames_zapobj == 0) 1185 return (ENOENT); 1186 1187 zap_cursor_init_serialized(&cursor, 1188 ds->ds_dir->dd_pool->dp_meta_objset, 1189 ds->ds_phys->ds_snapnames_zapobj, *offp); 1190 1191 if (zap_cursor_retrieve(&cursor, &attr) != 0) { 1192 zap_cursor_fini(&cursor); 1193 return (ENOENT); 1194 } 1195 1196 if (strlen(attr.za_name) + 1 > namelen) { 1197 zap_cursor_fini(&cursor); 1198 return (ENAMETOOLONG); 1199 } 1200 1201 (void) strcpy(name, attr.za_name); 1202 if (idp) 1203 *idp = attr.za_first_integer; 1204 if (case_conflict) 1205 *case_conflict = attr.za_normalization_conflict; 1206 zap_cursor_advance(&cursor); 1207 *offp = zap_cursor_serialize(&cursor); 1208 zap_cursor_fini(&cursor); 1209 1210 return (0); 1211 } 1212 1213 int 1214 dmu_dir_list_next(objset_t *os, int namelen, char *name, 1215 uint64_t *idp, uint64_t *offp) 1216 { 1217 dsl_dir_t *dd = os->os_dsl_dataset->ds_dir; 1218 zap_cursor_t cursor; 1219 zap_attribute_t attr; 1220 1221 /* there is no next dir on a snapshot! */ 1222 if (os->os_dsl_dataset->ds_object != 1223 dd->dd_phys->dd_head_dataset_obj) 1224 return (ENOENT); 1225 1226 zap_cursor_init_serialized(&cursor, 1227 dd->dd_pool->dp_meta_objset, 1228 dd->dd_phys->dd_child_dir_zapobj, *offp); 1229 1230 if (zap_cursor_retrieve(&cursor, &attr) != 0) { 1231 zap_cursor_fini(&cursor); 1232 return (ENOENT); 1233 } 1234 1235 if (strlen(attr.za_name) + 1 > namelen) { 1236 zap_cursor_fini(&cursor); 1237 return (ENAMETOOLONG); 1238 } 1239 1240 (void) strcpy(name, attr.za_name); 1241 if (idp) 1242 *idp = attr.za_first_integer; 1243 zap_cursor_advance(&cursor); 1244 *offp = zap_cursor_serialize(&cursor); 1245 zap_cursor_fini(&cursor); 1246 1247 return (0); 1248 } 1249 1250 struct findarg { 1251 int (*func)(char *, void *); 1252 void *arg; 1253 }; 1254 1255 /* ARGSUSED */ 1256 static int 1257 findfunc(spa_t *spa, uint64_t dsobj, const char *dsname, void *arg) 1258 { 1259 struct findarg *fa = arg; 1260 return (fa->func((char *)dsname, fa->arg)); 1261 } 1262 1263 /* 1264 * Find all objsets under name, and for each, call 'func(child_name, arg)'. 1265 * Perhaps change all callers to use dmu_objset_find_spa()? 1266 */ 1267 int 1268 dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) 1269 { 1270 struct findarg fa; 1271 fa.func = func; 1272 fa.arg = arg; 1273 return (dmu_objset_find_spa(NULL, name, findfunc, &fa, flags)); 1274 } 1275 1276 /* 1277 * Find all objsets under name, call func on each 1278 */ 1279 int 1280 dmu_objset_find_spa(spa_t *spa, const char *name, 1281 int func(spa_t *, uint64_t, const char *, void *), void *arg, int flags) 1282 { 1283 dsl_dir_t *dd; 1284 dsl_pool_t *dp; 1285 dsl_dataset_t *ds; 1286 zap_cursor_t zc; 1287 zap_attribute_t *attr; 1288 char *child; 1289 uint64_t thisobj; 1290 int err; 1291 1292 if (name == NULL) 1293 name = spa_name(spa); 1294 err = dsl_dir_open_spa(spa, name, FTAG, &dd, NULL); 1295 if (err) 1296 return (err); 1297 1298 /* Don't visit hidden ($MOS & $ORIGIN) objsets. */ 1299 if (dd->dd_myname[0] == '$') { 1300 dsl_dir_close(dd, FTAG); 1301 return (0); 1302 } 1303 1304 thisobj = dd->dd_phys->dd_head_dataset_obj; 1305 attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP); 1306 dp = dd->dd_pool; 1307 1308 /* 1309 * Iterate over all children. 1310 */ 1311 if (flags & DS_FIND_CHILDREN) { 1312 for (zap_cursor_init(&zc, dp->dp_meta_objset, 1313 dd->dd_phys->dd_child_dir_zapobj); 1314 zap_cursor_retrieve(&zc, attr) == 0; 1315 (void) zap_cursor_advance(&zc)) { 1316 ASSERT(attr->za_integer_length == sizeof (uint64_t)); 1317 ASSERT(attr->za_num_integers == 1); 1318 1319 child = kmem_alloc(MAXPATHLEN, KM_SLEEP); 1320 (void) strcpy(child, name); 1321 (void) strcat(child, "/"); 1322 (void) strcat(child, attr->za_name); 1323 err = dmu_objset_find_spa(spa, child, func, arg, flags); 1324 kmem_free(child, MAXPATHLEN); 1325 if (err) 1326 break; 1327 } 1328 zap_cursor_fini(&zc); 1329 1330 if (err) { 1331 dsl_dir_close(dd, FTAG); 1332 kmem_free(attr, sizeof (zap_attribute_t)); 1333 return (err); 1334 } 1335 } 1336 1337 /* 1338 * Iterate over all snapshots. 1339 */ 1340 if (flags & DS_FIND_SNAPSHOTS) { 1341 if (!dsl_pool_sync_context(dp)) 1342 rw_enter(&dp->dp_config_rwlock, RW_READER); 1343 err = dsl_dataset_hold_obj(dp, thisobj, FTAG, &ds); 1344 if (!dsl_pool_sync_context(dp)) 1345 rw_exit(&dp->dp_config_rwlock); 1346 1347 if (err == 0) { 1348 uint64_t snapobj = ds->ds_phys->ds_snapnames_zapobj; 1349 dsl_dataset_rele(ds, FTAG); 1350 1351 for (zap_cursor_init(&zc, dp->dp_meta_objset, snapobj); 1352 zap_cursor_retrieve(&zc, attr) == 0; 1353 (void) zap_cursor_advance(&zc)) { 1354 ASSERT(attr->za_integer_length == 1355 sizeof (uint64_t)); 1356 ASSERT(attr->za_num_integers == 1); 1357 1358 child = kmem_alloc(MAXPATHLEN, KM_SLEEP); 1359 (void) strcpy(child, name); 1360 (void) strcat(child, "@"); 1361 (void) strcat(child, attr->za_name); 1362 err = func(spa, attr->za_first_integer, 1363 child, arg); 1364 kmem_free(child, MAXPATHLEN); 1365 if (err) 1366 break; 1367 } 1368 zap_cursor_fini(&zc); 1369 } 1370 } 1371 1372 dsl_dir_close(dd, FTAG); 1373 kmem_free(attr, sizeof (zap_attribute_t)); 1374 1375 if (err) 1376 return (err); 1377 1378 /* 1379 * Apply to self if appropriate. 1380 */ 1381 err = func(spa, thisobj, name, arg); 1382 return (err); 1383 } 1384 1385 /* ARGSUSED */ 1386 int 1387 dmu_objset_prefetch(char *name, void *arg) 1388 { 1389 dsl_dataset_t *ds; 1390 1391 if (dsl_dataset_hold(name, FTAG, &ds)) 1392 return (0); 1393 1394 if (!BP_IS_HOLE(&ds->ds_phys->ds_bp)) { 1395 mutex_enter(&ds->ds_opening_lock); 1396 if (ds->ds_objset == NULL) { 1397 uint32_t aflags = ARC_NOWAIT | ARC_PREFETCH; 1398 zbookmark_t zb; 1399 1400 zb.zb_objset = ds->ds_object; 1401 zb.zb_object = 0; 1402 zb.zb_level = -1; 1403 zb.zb_blkid = 0; 1404 1405 (void) arc_read_nolock(NULL, dsl_dataset_get_spa(ds), 1406 &ds->ds_phys->ds_bp, NULL, NULL, 1407 ZIO_PRIORITY_ASYNC_READ, 1408 ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE, 1409 &aflags, &zb); 1410 } 1411 mutex_exit(&ds->ds_opening_lock); 1412 } 1413 1414 dsl_dataset_rele(ds, FTAG); 1415 return (0); 1416 } 1417 1418 void 1419 dmu_objset_set_user(objset_t *os, void *user_ptr) 1420 { 1421 ASSERT(MUTEX_HELD(&os->os_user_ptr_lock)); 1422 os->os_user_ptr = user_ptr; 1423 } 1424 1425 void * 1426 dmu_objset_get_user(objset_t *os) 1427 { 1428 ASSERT(MUTEX_HELD(&os->os_user_ptr_lock)); 1429 return (os->os_user_ptr); 1430 } 1431