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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/dmu_objset.h> 29 #include <sys/dsl_dataset.h> 30 #include <sys/dsl_dir.h> 31 #include <sys/dsl_prop.h> 32 #include <sys/dsl_synctask.h> 33 #include <sys/dmu_traverse.h> 34 #include <sys/dmu_tx.h> 35 #include <sys/arc.h> 36 #include <sys/zio.h> 37 #include <sys/zap.h> 38 #include <sys/unique.h> 39 #include <sys/zfs_context.h> 40 #include <sys/zfs_ioctl.h> 41 #include <sys/spa.h> 42 #include <sys/sunddi.h> 43 44 static dsl_checkfunc_t dsl_dataset_destroy_begin_check; 45 static dsl_syncfunc_t dsl_dataset_destroy_begin_sync; 46 static dsl_checkfunc_t dsl_dataset_rollback_check; 47 static dsl_syncfunc_t dsl_dataset_rollback_sync; 48 49 #define DS_REF_MAX (1ULL << 62) 50 51 #define DSL_DEADLIST_BLOCKSIZE SPA_MAXBLOCKSIZE 52 53 /* 54 * We use weighted reference counts to express the various forms of exclusion 55 * between different open modes. A STANDARD open is 1 point, an EXCLUSIVE open 56 * is DS_REF_MAX, and a PRIMARY open is little more than half of an EXCLUSIVE. 57 * This makes the exclusion logic simple: the total refcnt for all opens cannot 58 * exceed DS_REF_MAX. For example, EXCLUSIVE opens are exclusive because their 59 * weight (DS_REF_MAX) consumes the entire refcnt space. PRIMARY opens consume 60 * just over half of the refcnt space, so there can't be more than one, but it 61 * can peacefully coexist with any number of STANDARD opens. 62 */ 63 static uint64_t ds_refcnt_weight[DS_MODE_LEVELS] = { 64 0, /* DS_MODE_NONE - invalid */ 65 1, /* DS_MODE_STANDARD - unlimited number */ 66 (DS_REF_MAX >> 1) + 1, /* DS_MODE_PRIMARY - only one of these */ 67 DS_REF_MAX /* DS_MODE_EXCLUSIVE - no other opens */ 68 }; 69 70 71 void 72 dsl_dataset_block_born(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx) 73 { 74 int used = bp_get_dasize(tx->tx_pool->dp_spa, bp); 75 int compressed = BP_GET_PSIZE(bp); 76 int uncompressed = BP_GET_UCSIZE(bp); 77 78 dprintf_bp(bp, "born, ds=%p\n", ds); 79 80 ASSERT(dmu_tx_is_syncing(tx)); 81 /* It could have been compressed away to nothing */ 82 if (BP_IS_HOLE(bp)) 83 return; 84 ASSERT(BP_GET_TYPE(bp) != DMU_OT_NONE); 85 ASSERT3U(BP_GET_TYPE(bp), <, DMU_OT_NUMTYPES); 86 if (ds == NULL) { 87 /* 88 * Account for the meta-objset space in its placeholder 89 * dsl_dir. 90 */ 91 ASSERT3U(compressed, ==, uncompressed); /* it's all metadata */ 92 dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, 93 used, compressed, uncompressed, tx); 94 dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx); 95 return; 96 } 97 dmu_buf_will_dirty(ds->ds_dbuf, tx); 98 mutex_enter(&ds->ds_lock); 99 ds->ds_phys->ds_used_bytes += used; 100 ds->ds_phys->ds_compressed_bytes += compressed; 101 ds->ds_phys->ds_uncompressed_bytes += uncompressed; 102 ds->ds_phys->ds_unique_bytes += used; 103 mutex_exit(&ds->ds_lock); 104 dsl_dir_diduse_space(ds->ds_dir, 105 used, compressed, uncompressed, tx); 106 } 107 108 void 109 dsl_dataset_block_kill(dsl_dataset_t *ds, blkptr_t *bp, zio_t *pio, 110 dmu_tx_t *tx) 111 { 112 int used = bp_get_dasize(tx->tx_pool->dp_spa, bp); 113 int compressed = BP_GET_PSIZE(bp); 114 int uncompressed = BP_GET_UCSIZE(bp); 115 116 ASSERT(dmu_tx_is_syncing(tx)); 117 /* No block pointer => nothing to free */ 118 if (BP_IS_HOLE(bp)) 119 return; 120 121 ASSERT(used > 0); 122 if (ds == NULL) { 123 int err; 124 /* 125 * Account for the meta-objset space in its placeholder 126 * dataset. 127 */ 128 err = arc_free(pio, tx->tx_pool->dp_spa, 129 tx->tx_txg, bp, NULL, NULL, pio ? ARC_NOWAIT: ARC_WAIT); 130 ASSERT(err == 0); 131 132 dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, 133 -used, -compressed, -uncompressed, tx); 134 dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx); 135 return; 136 } 137 ASSERT3P(tx->tx_pool, ==, ds->ds_dir->dd_pool); 138 139 dmu_buf_will_dirty(ds->ds_dbuf, tx); 140 141 if (bp->blk_birth > ds->ds_phys->ds_prev_snap_txg) { 142 int err; 143 144 dprintf_bp(bp, "freeing: %s", ""); 145 err = arc_free(pio, tx->tx_pool->dp_spa, 146 tx->tx_txg, bp, NULL, NULL, pio ? ARC_NOWAIT: ARC_WAIT); 147 ASSERT(err == 0); 148 149 mutex_enter(&ds->ds_lock); 150 /* XXX unique_bytes is not accurate for head datasets */ 151 /* ASSERT3U(ds->ds_phys->ds_unique_bytes, >=, used); */ 152 ds->ds_phys->ds_unique_bytes -= used; 153 mutex_exit(&ds->ds_lock); 154 dsl_dir_diduse_space(ds->ds_dir, 155 -used, -compressed, -uncompressed, tx); 156 } else { 157 dprintf_bp(bp, "putting on dead list: %s", ""); 158 VERIFY(0 == bplist_enqueue(&ds->ds_deadlist, bp, tx)); 159 /* if (bp->blk_birth > prev prev snap txg) prev unique += bs */ 160 if (ds->ds_phys->ds_prev_snap_obj != 0) { 161 ASSERT3U(ds->ds_prev->ds_object, ==, 162 ds->ds_phys->ds_prev_snap_obj); 163 ASSERT(ds->ds_prev->ds_phys->ds_num_children > 0); 164 if (ds->ds_prev->ds_phys->ds_next_snap_obj == 165 ds->ds_object && bp->blk_birth > 166 ds->ds_prev->ds_phys->ds_prev_snap_txg) { 167 dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx); 168 mutex_enter(&ds->ds_prev->ds_lock); 169 ds->ds_prev->ds_phys->ds_unique_bytes += 170 used; 171 mutex_exit(&ds->ds_prev->ds_lock); 172 } 173 } 174 } 175 mutex_enter(&ds->ds_lock); 176 ASSERT3U(ds->ds_phys->ds_used_bytes, >=, used); 177 ds->ds_phys->ds_used_bytes -= used; 178 ASSERT3U(ds->ds_phys->ds_compressed_bytes, >=, compressed); 179 ds->ds_phys->ds_compressed_bytes -= compressed; 180 ASSERT3U(ds->ds_phys->ds_uncompressed_bytes, >=, uncompressed); 181 ds->ds_phys->ds_uncompressed_bytes -= uncompressed; 182 mutex_exit(&ds->ds_lock); 183 } 184 185 uint64_t 186 dsl_dataset_prev_snap_txg(dsl_dataset_t *ds) 187 { 188 uint64_t trysnap = 0; 189 190 if (ds == NULL) 191 return (0); 192 /* 193 * The snapshot creation could fail, but that would cause an 194 * incorrect FALSE return, which would only result in an 195 * overestimation of the amount of space that an operation would 196 * consume, which is OK. 197 * 198 * There's also a small window where we could miss a pending 199 * snapshot, because we could set the sync task in the quiescing 200 * phase. So this should only be used as a guess. 201 */ 202 if (ds->ds_trysnap_txg > 203 spa_last_synced_txg(ds->ds_dir->dd_pool->dp_spa)) 204 trysnap = ds->ds_trysnap_txg; 205 return (MAX(ds->ds_phys->ds_prev_snap_txg, trysnap)); 206 } 207 208 int 209 dsl_dataset_block_freeable(dsl_dataset_t *ds, uint64_t blk_birth) 210 { 211 return (blk_birth > dsl_dataset_prev_snap_txg(ds)); 212 } 213 214 /* ARGSUSED */ 215 static void 216 dsl_dataset_evict(dmu_buf_t *db, void *dsv) 217 { 218 dsl_dataset_t *ds = dsv; 219 220 /* open_refcount == DS_REF_MAX when deleting */ 221 ASSERT(ds->ds_open_refcount == 0 || 222 ds->ds_open_refcount == DS_REF_MAX); 223 224 dprintf_ds(ds, "evicting %s\n", ""); 225 226 unique_remove(ds->ds_fsid_guid); 227 228 if (ds->ds_user_ptr != NULL) 229 ds->ds_user_evict_func(ds, ds->ds_user_ptr); 230 231 if (ds->ds_prev) { 232 dsl_dataset_close(ds->ds_prev, DS_MODE_NONE, ds); 233 ds->ds_prev = NULL; 234 } 235 236 bplist_close(&ds->ds_deadlist); 237 dsl_dir_close(ds->ds_dir, ds); 238 239 ASSERT(!list_link_active(&ds->ds_synced_link)); 240 241 mutex_destroy(&ds->ds_lock); 242 mutex_destroy(&ds->ds_opening_lock); 243 mutex_destroy(&ds->ds_deadlist.bpl_lock); 244 245 kmem_free(ds, sizeof (dsl_dataset_t)); 246 } 247 248 static int 249 dsl_dataset_get_snapname(dsl_dataset_t *ds) 250 { 251 dsl_dataset_phys_t *headphys; 252 int err; 253 dmu_buf_t *headdbuf; 254 dsl_pool_t *dp = ds->ds_dir->dd_pool; 255 objset_t *mos = dp->dp_meta_objset; 256 257 if (ds->ds_snapname[0]) 258 return (0); 259 if (ds->ds_phys->ds_next_snap_obj == 0) 260 return (0); 261 262 err = dmu_bonus_hold(mos, ds->ds_dir->dd_phys->dd_head_dataset_obj, 263 FTAG, &headdbuf); 264 if (err) 265 return (err); 266 headphys = headdbuf->db_data; 267 err = zap_value_search(dp->dp_meta_objset, 268 headphys->ds_snapnames_zapobj, ds->ds_object, 0, ds->ds_snapname); 269 dmu_buf_rele(headdbuf, FTAG); 270 return (err); 271 } 272 273 int 274 dsl_dataset_open_obj(dsl_pool_t *dp, uint64_t dsobj, const char *snapname, 275 int mode, void *tag, dsl_dataset_t **dsp) 276 { 277 uint64_t weight = ds_refcnt_weight[DS_MODE_LEVEL(mode)]; 278 objset_t *mos = dp->dp_meta_objset; 279 dmu_buf_t *dbuf; 280 dsl_dataset_t *ds; 281 int err; 282 283 ASSERT(RW_LOCK_HELD(&dp->dp_config_rwlock) || 284 dsl_pool_sync_context(dp)); 285 286 err = dmu_bonus_hold(mos, dsobj, tag, &dbuf); 287 if (err) 288 return (err); 289 ds = dmu_buf_get_user(dbuf); 290 if (ds == NULL) { 291 dsl_dataset_t *winner; 292 293 ds = kmem_zalloc(sizeof (dsl_dataset_t), KM_SLEEP); 294 ds->ds_dbuf = dbuf; 295 ds->ds_object = dsobj; 296 ds->ds_phys = dbuf->db_data; 297 298 mutex_init(&ds->ds_lock, NULL, MUTEX_DEFAULT, NULL); 299 mutex_init(&ds->ds_opening_lock, NULL, MUTEX_DEFAULT, NULL); 300 mutex_init(&ds->ds_deadlist.bpl_lock, NULL, MUTEX_DEFAULT, 301 NULL); 302 303 err = bplist_open(&ds->ds_deadlist, 304 mos, ds->ds_phys->ds_deadlist_obj); 305 if (err == 0) { 306 err = dsl_dir_open_obj(dp, 307 ds->ds_phys->ds_dir_obj, NULL, ds, &ds->ds_dir); 308 } 309 if (err) { 310 /* 311 * we don't really need to close the blist if we 312 * just opened it. 313 */ 314 mutex_destroy(&ds->ds_lock); 315 mutex_destroy(&ds->ds_opening_lock); 316 mutex_destroy(&ds->ds_deadlist.bpl_lock); 317 kmem_free(ds, sizeof (dsl_dataset_t)); 318 dmu_buf_rele(dbuf, tag); 319 return (err); 320 } 321 322 if (ds->ds_dir->dd_phys->dd_head_dataset_obj == dsobj) { 323 ds->ds_snapname[0] = '\0'; 324 if (ds->ds_phys->ds_prev_snap_obj) { 325 err = dsl_dataset_open_obj(dp, 326 ds->ds_phys->ds_prev_snap_obj, NULL, 327 DS_MODE_NONE, ds, &ds->ds_prev); 328 } 329 } else { 330 if (snapname) { 331 #ifdef ZFS_DEBUG 332 dsl_dataset_phys_t *headphys; 333 dmu_buf_t *headdbuf; 334 err = dmu_bonus_hold(mos, 335 ds->ds_dir->dd_phys->dd_head_dataset_obj, 336 FTAG, &headdbuf); 337 if (err == 0) { 338 headphys = headdbuf->db_data; 339 uint64_t foundobj; 340 err = zap_lookup(dp->dp_meta_objset, 341 headphys->ds_snapnames_zapobj, 342 snapname, sizeof (foundobj), 1, 343 &foundobj); 344 ASSERT3U(foundobj, ==, dsobj); 345 dmu_buf_rele(headdbuf, FTAG); 346 } 347 #endif 348 (void) strcat(ds->ds_snapname, snapname); 349 } else if (zfs_flags & ZFS_DEBUG_SNAPNAMES) { 350 err = dsl_dataset_get_snapname(ds); 351 } 352 } 353 354 if (err == 0) { 355 winner = dmu_buf_set_user_ie(dbuf, ds, &ds->ds_phys, 356 dsl_dataset_evict); 357 } 358 if (err || winner) { 359 bplist_close(&ds->ds_deadlist); 360 if (ds->ds_prev) { 361 dsl_dataset_close(ds->ds_prev, 362 DS_MODE_NONE, ds); 363 } 364 dsl_dir_close(ds->ds_dir, ds); 365 mutex_destroy(&ds->ds_lock); 366 mutex_destroy(&ds->ds_opening_lock); 367 mutex_destroy(&ds->ds_deadlist.bpl_lock); 368 kmem_free(ds, sizeof (dsl_dataset_t)); 369 if (err) { 370 dmu_buf_rele(dbuf, tag); 371 return (err); 372 } 373 ds = winner; 374 } else { 375 ds->ds_fsid_guid = 376 unique_insert(ds->ds_phys->ds_fsid_guid); 377 } 378 } 379 ASSERT3P(ds->ds_dbuf, ==, dbuf); 380 ASSERT3P(ds->ds_phys, ==, dbuf->db_data); 381 382 mutex_enter(&ds->ds_lock); 383 if ((DS_MODE_LEVEL(mode) == DS_MODE_PRIMARY && 384 (ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) && 385 !DS_MODE_IS_INCONSISTENT(mode)) || 386 (ds->ds_open_refcount + weight > DS_REF_MAX)) { 387 mutex_exit(&ds->ds_lock); 388 dsl_dataset_close(ds, DS_MODE_NONE, tag); 389 return (EBUSY); 390 } 391 ds->ds_open_refcount += weight; 392 mutex_exit(&ds->ds_lock); 393 394 *dsp = ds; 395 return (0); 396 } 397 398 int 399 dsl_dataset_open_spa(spa_t *spa, const char *name, int mode, 400 void *tag, dsl_dataset_t **dsp) 401 { 402 dsl_dir_t *dd; 403 dsl_pool_t *dp; 404 const char *tail; 405 uint64_t obj; 406 dsl_dataset_t *ds = NULL; 407 int err = 0; 408 409 err = dsl_dir_open_spa(spa, name, FTAG, &dd, &tail); 410 if (err) 411 return (err); 412 413 dp = dd->dd_pool; 414 obj = dd->dd_phys->dd_head_dataset_obj; 415 rw_enter(&dp->dp_config_rwlock, RW_READER); 416 if (obj == 0) { 417 /* A dataset with no associated objset */ 418 err = ENOENT; 419 goto out; 420 } 421 422 if (tail != NULL) { 423 objset_t *mos = dp->dp_meta_objset; 424 425 err = dsl_dataset_open_obj(dp, obj, NULL, 426 DS_MODE_NONE, tag, &ds); 427 if (err) 428 goto out; 429 obj = ds->ds_phys->ds_snapnames_zapobj; 430 dsl_dataset_close(ds, DS_MODE_NONE, tag); 431 ds = NULL; 432 433 if (tail[0] != '@') { 434 err = ENOENT; 435 goto out; 436 } 437 tail++; 438 439 /* Look for a snapshot */ 440 if (!DS_MODE_IS_READONLY(mode)) { 441 err = EROFS; 442 goto out; 443 } 444 dprintf("looking for snapshot '%s'\n", tail); 445 err = zap_lookup(mos, obj, tail, 8, 1, &obj); 446 if (err) 447 goto out; 448 } 449 err = dsl_dataset_open_obj(dp, obj, tail, mode, tag, &ds); 450 451 out: 452 rw_exit(&dp->dp_config_rwlock); 453 dsl_dir_close(dd, FTAG); 454 455 ASSERT3U((err == 0), ==, (ds != NULL)); 456 /* ASSERT(ds == NULL || strcmp(name, ds->ds_name) == 0); */ 457 458 *dsp = ds; 459 return (err); 460 } 461 462 int 463 dsl_dataset_open(const char *name, int mode, void *tag, dsl_dataset_t **dsp) 464 { 465 return (dsl_dataset_open_spa(NULL, name, mode, tag, dsp)); 466 } 467 468 void 469 dsl_dataset_name(dsl_dataset_t *ds, char *name) 470 { 471 if (ds == NULL) { 472 (void) strcpy(name, "mos"); 473 } else { 474 dsl_dir_name(ds->ds_dir, name); 475 VERIFY(0 == dsl_dataset_get_snapname(ds)); 476 if (ds->ds_snapname[0]) { 477 (void) strcat(name, "@"); 478 if (!MUTEX_HELD(&ds->ds_lock)) { 479 /* 480 * We use a "recursive" mutex so that we 481 * can call dprintf_ds() with ds_lock held. 482 */ 483 mutex_enter(&ds->ds_lock); 484 (void) strcat(name, ds->ds_snapname); 485 mutex_exit(&ds->ds_lock); 486 } else { 487 (void) strcat(name, ds->ds_snapname); 488 } 489 } 490 } 491 } 492 493 static int 494 dsl_dataset_namelen(dsl_dataset_t *ds) 495 { 496 int result; 497 498 if (ds == NULL) { 499 result = 3; /* "mos" */ 500 } else { 501 result = dsl_dir_namelen(ds->ds_dir); 502 VERIFY(0 == dsl_dataset_get_snapname(ds)); 503 if (ds->ds_snapname[0]) { 504 ++result; /* adding one for the @-sign */ 505 if (!MUTEX_HELD(&ds->ds_lock)) { 506 /* see dsl_datset_name */ 507 mutex_enter(&ds->ds_lock); 508 result += strlen(ds->ds_snapname); 509 mutex_exit(&ds->ds_lock); 510 } else { 511 result += strlen(ds->ds_snapname); 512 } 513 } 514 } 515 516 return (result); 517 } 518 519 void 520 dsl_dataset_close(dsl_dataset_t *ds, int mode, void *tag) 521 { 522 uint64_t weight = ds_refcnt_weight[DS_MODE_LEVEL(mode)]; 523 mutex_enter(&ds->ds_lock); 524 ASSERT3U(ds->ds_open_refcount, >=, weight); 525 ds->ds_open_refcount -= weight; 526 dprintf_ds(ds, "closing mode %u refcount now 0x%llx\n", 527 mode, ds->ds_open_refcount); 528 mutex_exit(&ds->ds_lock); 529 530 dmu_buf_rele(ds->ds_dbuf, tag); 531 } 532 533 void 534 dsl_dataset_downgrade(dsl_dataset_t *ds, int oldmode, int newmode) 535 { 536 uint64_t oldweight = ds_refcnt_weight[DS_MODE_LEVEL(oldmode)]; 537 uint64_t newweight = ds_refcnt_weight[DS_MODE_LEVEL(newmode)]; 538 mutex_enter(&ds->ds_lock); 539 ASSERT3U(ds->ds_open_refcount, >=, oldweight); 540 ASSERT3U(oldweight, >=, newweight); 541 ds->ds_open_refcount -= oldweight; 542 ds->ds_open_refcount += newweight; 543 mutex_exit(&ds->ds_lock); 544 } 545 546 boolean_t 547 dsl_dataset_tryupgrade(dsl_dataset_t *ds, int oldmode, int newmode) 548 { 549 boolean_t rv; 550 uint64_t oldweight = ds_refcnt_weight[DS_MODE_LEVEL(oldmode)]; 551 uint64_t newweight = ds_refcnt_weight[DS_MODE_LEVEL(newmode)]; 552 mutex_enter(&ds->ds_lock); 553 ASSERT3U(ds->ds_open_refcount, >=, oldweight); 554 ASSERT3U(newweight, >=, oldweight); 555 if (ds->ds_open_refcount - oldweight + newweight > DS_REF_MAX) { 556 rv = B_FALSE; 557 } else { 558 ds->ds_open_refcount -= oldweight; 559 ds->ds_open_refcount += newweight; 560 rv = B_TRUE; 561 } 562 mutex_exit(&ds->ds_lock); 563 return (rv); 564 } 565 566 void 567 dsl_dataset_create_root(dsl_pool_t *dp, uint64_t *ddobjp, dmu_tx_t *tx) 568 { 569 objset_t *mos = dp->dp_meta_objset; 570 dmu_buf_t *dbuf; 571 dsl_dataset_phys_t *dsphys; 572 dsl_dataset_t *ds; 573 uint64_t dsobj; 574 dsl_dir_t *dd; 575 576 dsl_dir_create_root(mos, ddobjp, tx); 577 VERIFY(0 == dsl_dir_open_obj(dp, *ddobjp, NULL, FTAG, &dd)); 578 579 dsobj = dmu_object_alloc(mos, DMU_OT_DSL_DATASET, 0, 580 DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx); 581 VERIFY(0 == dmu_bonus_hold(mos, dsobj, FTAG, &dbuf)); 582 dmu_buf_will_dirty(dbuf, tx); 583 dsphys = dbuf->db_data; 584 dsphys->ds_dir_obj = dd->dd_object; 585 dsphys->ds_fsid_guid = unique_create(); 586 (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid, 587 sizeof (dsphys->ds_guid)); 588 dsphys->ds_snapnames_zapobj = 589 zap_create(mos, DMU_OT_DSL_DS_SNAP_MAP, DMU_OT_NONE, 0, tx); 590 dsphys->ds_creation_time = gethrestime_sec(); 591 dsphys->ds_creation_txg = tx->tx_txg; 592 dsphys->ds_deadlist_obj = 593 bplist_create(mos, DSL_DEADLIST_BLOCKSIZE, tx); 594 dmu_buf_rele(dbuf, FTAG); 595 596 dmu_buf_will_dirty(dd->dd_dbuf, tx); 597 dd->dd_phys->dd_head_dataset_obj = dsobj; 598 dsl_dir_close(dd, FTAG); 599 600 VERIFY(0 == 601 dsl_dataset_open_obj(dp, dsobj, NULL, DS_MODE_NONE, FTAG, &ds)); 602 (void) dmu_objset_create_impl(dp->dp_spa, ds, 603 &ds->ds_phys->ds_bp, DMU_OST_ZFS, tx); 604 dsl_dataset_close(ds, DS_MODE_NONE, FTAG); 605 } 606 607 uint64_t 608 dsl_dataset_create_sync_impl(dsl_dir_t *dd, dsl_dataset_t *origin, dmu_tx_t *tx) 609 { 610 dsl_pool_t *dp = dd->dd_pool; 611 dmu_buf_t *dbuf; 612 dsl_dataset_phys_t *dsphys; 613 uint64_t dsobj; 614 objset_t *mos = dp->dp_meta_objset; 615 616 ASSERT(origin == NULL || origin->ds_dir->dd_pool == dp); 617 ASSERT(origin == NULL || origin->ds_phys->ds_num_children > 0); 618 ASSERT(dmu_tx_is_syncing(tx)); 619 ASSERT(dd->dd_phys->dd_head_dataset_obj == 0); 620 621 dsobj = dmu_object_alloc(mos, DMU_OT_DSL_DATASET, 0, 622 DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx); 623 VERIFY(0 == dmu_bonus_hold(mos, dsobj, FTAG, &dbuf)); 624 dmu_buf_will_dirty(dbuf, tx); 625 dsphys = dbuf->db_data; 626 dsphys->ds_dir_obj = dd->dd_object; 627 dsphys->ds_fsid_guid = unique_create(); 628 (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid, 629 sizeof (dsphys->ds_guid)); 630 dsphys->ds_snapnames_zapobj = 631 zap_create(mos, DMU_OT_DSL_DS_SNAP_MAP, DMU_OT_NONE, 0, tx); 632 dsphys->ds_creation_time = gethrestime_sec(); 633 dsphys->ds_creation_txg = tx->tx_txg; 634 dsphys->ds_deadlist_obj = 635 bplist_create(mos, DSL_DEADLIST_BLOCKSIZE, tx); 636 if (origin) { 637 dsphys->ds_prev_snap_obj = origin->ds_object; 638 dsphys->ds_prev_snap_txg = 639 origin->ds_phys->ds_creation_txg; 640 dsphys->ds_used_bytes = 641 origin->ds_phys->ds_used_bytes; 642 dsphys->ds_compressed_bytes = 643 origin->ds_phys->ds_compressed_bytes; 644 dsphys->ds_uncompressed_bytes = 645 origin->ds_phys->ds_uncompressed_bytes; 646 dsphys->ds_bp = origin->ds_phys->ds_bp; 647 648 dmu_buf_will_dirty(origin->ds_dbuf, tx); 649 origin->ds_phys->ds_num_children++; 650 651 dmu_buf_will_dirty(dd->dd_dbuf, tx); 652 dd->dd_phys->dd_origin_obj = origin->ds_object; 653 } 654 dmu_buf_rele(dbuf, FTAG); 655 656 dmu_buf_will_dirty(dd->dd_dbuf, tx); 657 dd->dd_phys->dd_head_dataset_obj = dsobj; 658 659 return (dsobj); 660 } 661 662 uint64_t 663 dsl_dataset_create_sync(dsl_dir_t *pdd, 664 const char *lastname, dsl_dataset_t *origin, cred_t *cr, dmu_tx_t *tx) 665 { 666 dsl_pool_t *dp = pdd->dd_pool; 667 uint64_t dsobj, ddobj; 668 dsl_dir_t *dd; 669 670 ASSERT(lastname[0] != '@'); 671 672 ddobj = dsl_dir_create_sync(pdd, lastname, tx); 673 VERIFY(0 == dsl_dir_open_obj(dp, ddobj, lastname, FTAG, &dd)); 674 675 dsobj = dsl_dataset_create_sync_impl(dd, origin, tx); 676 677 dsl_deleg_set_create_perms(dd, tx, cr); 678 679 dsl_dir_close(dd, FTAG); 680 681 return (dsobj); 682 } 683 684 struct destroyarg { 685 dsl_sync_task_group_t *dstg; 686 char *snapname; 687 char *failed; 688 }; 689 690 static int 691 dsl_snapshot_destroy_one(char *name, void *arg) 692 { 693 struct destroyarg *da = arg; 694 dsl_dataset_t *ds; 695 char *cp; 696 int err; 697 698 (void) strcat(name, "@"); 699 (void) strcat(name, da->snapname); 700 err = dsl_dataset_open(name, 701 DS_MODE_EXCLUSIVE | DS_MODE_READONLY | DS_MODE_INCONSISTENT, 702 da->dstg, &ds); 703 cp = strchr(name, '@'); 704 *cp = '\0'; 705 if (err == ENOENT) 706 return (0); 707 if (err) { 708 (void) strcpy(da->failed, name); 709 return (err); 710 } 711 712 dsl_sync_task_create(da->dstg, dsl_dataset_destroy_check, 713 dsl_dataset_destroy_sync, ds, da->dstg, 0); 714 return (0); 715 } 716 717 /* 718 * Destroy 'snapname' in all descendants of 'fsname'. 719 */ 720 #pragma weak dmu_snapshots_destroy = dsl_snapshots_destroy 721 int 722 dsl_snapshots_destroy(char *fsname, char *snapname) 723 { 724 int err; 725 struct destroyarg da; 726 dsl_sync_task_t *dst; 727 spa_t *spa; 728 729 err = spa_open(fsname, &spa, FTAG); 730 if (err) 731 return (err); 732 da.dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); 733 da.snapname = snapname; 734 da.failed = fsname; 735 736 err = dmu_objset_find(fsname, 737 dsl_snapshot_destroy_one, &da, DS_FIND_CHILDREN); 738 739 if (err == 0) 740 err = dsl_sync_task_group_wait(da.dstg); 741 742 for (dst = list_head(&da.dstg->dstg_tasks); dst; 743 dst = list_next(&da.dstg->dstg_tasks, dst)) { 744 dsl_dataset_t *ds = dst->dst_arg1; 745 if (dst->dst_err) { 746 dsl_dataset_name(ds, fsname); 747 *strchr(fsname, '@') = '\0'; 748 } 749 /* 750 * If it was successful, destroy_sync would have 751 * closed the ds 752 */ 753 if (err) 754 dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, da.dstg); 755 } 756 757 dsl_sync_task_group_destroy(da.dstg); 758 spa_close(spa, FTAG); 759 return (err); 760 } 761 762 /* 763 * ds must be opened EXCLUSIVE or PRIMARY. on return (whether 764 * successful or not), ds will be closed and caller can no longer 765 * dereference it. 766 */ 767 int 768 dsl_dataset_destroy(dsl_dataset_t *ds, void *tag) 769 { 770 int err; 771 dsl_sync_task_group_t *dstg; 772 objset_t *os; 773 dsl_dir_t *dd; 774 uint64_t obj; 775 776 if (ds->ds_open_refcount != DS_REF_MAX) { 777 if (dsl_dataset_tryupgrade(ds, DS_MODE_PRIMARY, 778 DS_MODE_EXCLUSIVE) == 0) { 779 dsl_dataset_close(ds, DS_MODE_PRIMARY, tag); 780 return (EBUSY); 781 } 782 } 783 784 if (dsl_dataset_is_snapshot(ds)) { 785 /* Destroying a snapshot is simpler */ 786 err = dsl_sync_task_do(ds->ds_dir->dd_pool, 787 dsl_dataset_destroy_check, dsl_dataset_destroy_sync, 788 ds, tag, 0); 789 goto out; 790 } 791 792 dd = ds->ds_dir; 793 794 /* 795 * Check for errors and mark this ds as inconsistent, in 796 * case we crash while freeing the objects. 797 */ 798 err = dsl_sync_task_do(dd->dd_pool, dsl_dataset_destroy_begin_check, 799 dsl_dataset_destroy_begin_sync, ds, NULL, 0); 800 if (err) 801 goto out; 802 803 err = dmu_objset_open_ds(ds, DMU_OST_ANY, &os); 804 if (err) 805 goto out; 806 807 /* 808 * remove the objects in open context, so that we won't 809 * have too much to do in syncing context. 810 */ 811 for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE, 812 ds->ds_phys->ds_prev_snap_txg)) { 813 dmu_tx_t *tx = dmu_tx_create(os); 814 dmu_tx_hold_free(tx, obj, 0, DMU_OBJECT_END); 815 dmu_tx_hold_bonus(tx, obj); 816 err = dmu_tx_assign(tx, TXG_WAIT); 817 if (err) { 818 /* 819 * Perhaps there is not enough disk 820 * space. Just deal with it from 821 * dsl_dataset_destroy_sync(). 822 */ 823 dmu_tx_abort(tx); 824 continue; 825 } 826 VERIFY(0 == dmu_object_free(os, obj, tx)); 827 dmu_tx_commit(tx); 828 } 829 /* Make sure it's not dirty before we finish destroying it. */ 830 txg_wait_synced(dd->dd_pool, 0); 831 832 dmu_objset_close(os); 833 if (err != ESRCH) 834 goto out; 835 836 if (ds->ds_user_ptr) { 837 ds->ds_user_evict_func(ds, ds->ds_user_ptr); 838 ds->ds_user_ptr = NULL; 839 } 840 841 rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); 842 err = dsl_dir_open_obj(dd->dd_pool, dd->dd_object, NULL, FTAG, &dd); 843 rw_exit(&dd->dd_pool->dp_config_rwlock); 844 845 if (err) 846 goto out; 847 848 /* 849 * Blow away the dsl_dir + head dataset. 850 */ 851 dstg = dsl_sync_task_group_create(ds->ds_dir->dd_pool); 852 dsl_sync_task_create(dstg, dsl_dataset_destroy_check, 853 dsl_dataset_destroy_sync, ds, tag, 0); 854 dsl_sync_task_create(dstg, dsl_dir_destroy_check, 855 dsl_dir_destroy_sync, dd, FTAG, 0); 856 err = dsl_sync_task_group_wait(dstg); 857 dsl_sync_task_group_destroy(dstg); 858 /* if it is successful, *destroy_sync will close the ds+dd */ 859 if (err) 860 dsl_dir_close(dd, FTAG); 861 out: 862 if (err) 863 dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, tag); 864 return (err); 865 } 866 867 int 868 dsl_dataset_rollback(dsl_dataset_t *ds, dmu_objset_type_t ost) 869 { 870 ASSERT3U(ds->ds_open_refcount, ==, DS_REF_MAX); 871 872 return (dsl_sync_task_do(ds->ds_dir->dd_pool, 873 dsl_dataset_rollback_check, dsl_dataset_rollback_sync, 874 ds, &ost, 0)); 875 } 876 877 void * 878 dsl_dataset_set_user_ptr(dsl_dataset_t *ds, 879 void *p, dsl_dataset_evict_func_t func) 880 { 881 void *old; 882 883 mutex_enter(&ds->ds_lock); 884 old = ds->ds_user_ptr; 885 if (old == NULL) { 886 ds->ds_user_ptr = p; 887 ds->ds_user_evict_func = func; 888 } 889 mutex_exit(&ds->ds_lock); 890 return (old); 891 } 892 893 void * 894 dsl_dataset_get_user_ptr(dsl_dataset_t *ds) 895 { 896 return (ds->ds_user_ptr); 897 } 898 899 900 blkptr_t * 901 dsl_dataset_get_blkptr(dsl_dataset_t *ds) 902 { 903 return (&ds->ds_phys->ds_bp); 904 } 905 906 void 907 dsl_dataset_set_blkptr(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx) 908 { 909 ASSERT(dmu_tx_is_syncing(tx)); 910 /* If it's the meta-objset, set dp_meta_rootbp */ 911 if (ds == NULL) { 912 tx->tx_pool->dp_meta_rootbp = *bp; 913 } else { 914 dmu_buf_will_dirty(ds->ds_dbuf, tx); 915 ds->ds_phys->ds_bp = *bp; 916 } 917 } 918 919 spa_t * 920 dsl_dataset_get_spa(dsl_dataset_t *ds) 921 { 922 return (ds->ds_dir->dd_pool->dp_spa); 923 } 924 925 void 926 dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx) 927 { 928 dsl_pool_t *dp; 929 930 if (ds == NULL) /* this is the meta-objset */ 931 return; 932 933 ASSERT(ds->ds_user_ptr != NULL); 934 935 if (ds->ds_phys->ds_next_snap_obj != 0) 936 panic("dirtying snapshot!"); 937 938 dp = ds->ds_dir->dd_pool; 939 940 if (txg_list_add(&dp->dp_dirty_datasets, ds, tx->tx_txg) == 0) { 941 /* up the hold count until we can be written out */ 942 dmu_buf_add_ref(ds->ds_dbuf, ds); 943 } 944 } 945 946 struct killarg { 947 uint64_t *usedp; 948 uint64_t *compressedp; 949 uint64_t *uncompressedp; 950 zio_t *zio; 951 dmu_tx_t *tx; 952 }; 953 954 static int 955 kill_blkptr(traverse_blk_cache_t *bc, spa_t *spa, void *arg) 956 { 957 struct killarg *ka = arg; 958 blkptr_t *bp = &bc->bc_blkptr; 959 960 ASSERT3U(bc->bc_errno, ==, 0); 961 962 /* 963 * Since this callback is not called concurrently, no lock is 964 * needed on the accounting values. 965 */ 966 *ka->usedp += bp_get_dasize(spa, bp); 967 *ka->compressedp += BP_GET_PSIZE(bp); 968 *ka->uncompressedp += BP_GET_UCSIZE(bp); 969 /* XXX check for EIO? */ 970 (void) arc_free(ka->zio, spa, ka->tx->tx_txg, bp, NULL, NULL, 971 ARC_NOWAIT); 972 return (0); 973 } 974 975 /* ARGSUSED */ 976 static int 977 dsl_dataset_rollback_check(void *arg1, void *arg2, dmu_tx_t *tx) 978 { 979 dsl_dataset_t *ds = arg1; 980 dmu_objset_type_t *ost = arg2; 981 982 /* 983 * We can only roll back to emptyness if it is a ZPL objset. 984 */ 985 if (*ost != DMU_OST_ZFS && ds->ds_phys->ds_prev_snap_txg == 0) 986 return (EINVAL); 987 988 /* 989 * This must not be a snapshot. 990 */ 991 if (ds->ds_phys->ds_next_snap_obj != 0) 992 return (EINVAL); 993 994 /* 995 * If we made changes this txg, traverse_dsl_dataset won't find 996 * them. Try again. 997 */ 998 if (ds->ds_phys->ds_bp.blk_birth >= tx->tx_txg) 999 return (EAGAIN); 1000 1001 return (0); 1002 } 1003 1004 /* ARGSUSED */ 1005 static void 1006 dsl_dataset_rollback_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) 1007 { 1008 dsl_dataset_t *ds = arg1; 1009 dmu_objset_type_t *ost = arg2; 1010 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; 1011 1012 dmu_buf_will_dirty(ds->ds_dbuf, tx); 1013 1014 /* 1015 * Before the roll back destroy the zil. 1016 */ 1017 if (ds->ds_user_ptr != NULL) { 1018 zil_rollback_destroy( 1019 ((objset_impl_t *)ds->ds_user_ptr)->os_zil, tx); 1020 1021 /* 1022 * We need to make sure that the objset_impl_t is reopened after 1023 * we do the rollback, otherwise it will have the wrong 1024 * objset_phys_t. Normally this would happen when this 1025 * DS_MODE_EXCLUSIVE dataset-open is closed, thus causing the 1026 * dataset to be immediately evicted. But when doing "zfs recv 1027 * -F", we reopen the objset before that, so that there is no 1028 * window where the dataset is closed and inconsistent. 1029 */ 1030 ds->ds_user_evict_func(ds, ds->ds_user_ptr); 1031 ds->ds_user_ptr = NULL; 1032 } 1033 1034 /* Zero out the deadlist. */ 1035 bplist_close(&ds->ds_deadlist); 1036 bplist_destroy(mos, ds->ds_phys->ds_deadlist_obj, tx); 1037 ds->ds_phys->ds_deadlist_obj = 1038 bplist_create(mos, DSL_DEADLIST_BLOCKSIZE, tx); 1039 VERIFY(0 == bplist_open(&ds->ds_deadlist, mos, 1040 ds->ds_phys->ds_deadlist_obj)); 1041 1042 { 1043 /* Free blkptrs that we gave birth to */ 1044 zio_t *zio; 1045 uint64_t used = 0, compressed = 0, uncompressed = 0; 1046 struct killarg ka; 1047 1048 zio = zio_root(tx->tx_pool->dp_spa, NULL, NULL, 1049 ZIO_FLAG_MUSTSUCCEED); 1050 ka.usedp = &used; 1051 ka.compressedp = &compressed; 1052 ka.uncompressedp = &uncompressed; 1053 ka.zio = zio; 1054 ka.tx = tx; 1055 (void) traverse_dsl_dataset(ds, ds->ds_phys->ds_prev_snap_txg, 1056 ADVANCE_POST, kill_blkptr, &ka); 1057 (void) zio_wait(zio); 1058 1059 dsl_dir_diduse_space(ds->ds_dir, 1060 -used, -compressed, -uncompressed, tx); 1061 } 1062 1063 if (ds->ds_prev) { 1064 /* Change our contents to that of the prev snapshot */ 1065 ASSERT3U(ds->ds_prev->ds_object, ==, 1066 ds->ds_phys->ds_prev_snap_obj); 1067 ds->ds_phys->ds_bp = ds->ds_prev->ds_phys->ds_bp; 1068 ds->ds_phys->ds_used_bytes = 1069 ds->ds_prev->ds_phys->ds_used_bytes; 1070 ds->ds_phys->ds_compressed_bytes = 1071 ds->ds_prev->ds_phys->ds_compressed_bytes; 1072 ds->ds_phys->ds_uncompressed_bytes = 1073 ds->ds_prev->ds_phys->ds_uncompressed_bytes; 1074 ds->ds_phys->ds_flags = ds->ds_prev->ds_phys->ds_flags; 1075 ds->ds_phys->ds_unique_bytes = 0; 1076 1077 if (ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) { 1078 dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx); 1079 ds->ds_prev->ds_phys->ds_unique_bytes = 0; 1080 } 1081 } else { 1082 /* Zero out our contents, recreate objset */ 1083 bzero(&ds->ds_phys->ds_bp, sizeof (blkptr_t)); 1084 ds->ds_phys->ds_used_bytes = 0; 1085 ds->ds_phys->ds_compressed_bytes = 0; 1086 ds->ds_phys->ds_uncompressed_bytes = 0; 1087 ds->ds_phys->ds_flags = 0; 1088 ds->ds_phys->ds_unique_bytes = 0; 1089 (void) dmu_objset_create_impl(ds->ds_dir->dd_pool->dp_spa, ds, 1090 &ds->ds_phys->ds_bp, *ost, tx); 1091 } 1092 1093 spa_history_internal_log(LOG_DS_ROLLBACK, ds->ds_dir->dd_pool->dp_spa, 1094 tx, cr, "dataset = %llu", ds->ds_object); 1095 } 1096 1097 /* ARGSUSED */ 1098 static int 1099 dsl_dataset_destroy_begin_check(void *arg1, void *arg2, dmu_tx_t *tx) 1100 { 1101 dsl_dataset_t *ds = arg1; 1102 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; 1103 uint64_t count; 1104 int err; 1105 1106 /* 1107 * Can't delete a head dataset if there are snapshots of it. 1108 * (Except if the only snapshots are from the branch we cloned 1109 * from.) 1110 */ 1111 if (ds->ds_prev != NULL && 1112 ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) 1113 return (EINVAL); 1114 1115 /* 1116 * This is really a dsl_dir thing, but check it here so that 1117 * we'll be less likely to leave this dataset inconsistent & 1118 * nearly destroyed. 1119 */ 1120 err = zap_count(mos, ds->ds_dir->dd_phys->dd_child_dir_zapobj, &count); 1121 if (err) 1122 return (err); 1123 if (count != 0) 1124 return (EEXIST); 1125 1126 return (0); 1127 } 1128 1129 /* ARGSUSED */ 1130 static void 1131 dsl_dataset_destroy_begin_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) 1132 { 1133 dsl_dataset_t *ds = arg1; 1134 dsl_pool_t *dp = ds->ds_dir->dd_pool; 1135 1136 /* Mark it as inconsistent on-disk, in case we crash */ 1137 dmu_buf_will_dirty(ds->ds_dbuf, tx); 1138 ds->ds_phys->ds_flags |= DS_FLAG_INCONSISTENT; 1139 1140 spa_history_internal_log(LOG_DS_DESTROY_BEGIN, dp->dp_spa, tx, 1141 cr, "dataset = %llu", ds->ds_object); 1142 } 1143 1144 /* ARGSUSED */ 1145 int 1146 dsl_dataset_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx) 1147 { 1148 dsl_dataset_t *ds = arg1; 1149 1150 /* Can't delete a branch point. */ 1151 if (ds->ds_phys->ds_num_children > 1) 1152 return (EEXIST); 1153 1154 /* 1155 * Can't delete a head dataset if there are snapshots of it. 1156 * (Except if the only snapshots are from the branch we cloned 1157 * from.) 1158 */ 1159 if (ds->ds_prev != NULL && 1160 ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) 1161 return (EINVAL); 1162 1163 /* 1164 * If we made changes this txg, traverse_dsl_dataset won't find 1165 * them. Try again. 1166 */ 1167 if (ds->ds_phys->ds_bp.blk_birth >= tx->tx_txg) 1168 return (EAGAIN); 1169 1170 /* XXX we should do some i/o error checking... */ 1171 return (0); 1172 } 1173 1174 void 1175 dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) 1176 { 1177 dsl_dataset_t *ds = arg1; 1178 uint64_t used = 0, compressed = 0, uncompressed = 0; 1179 zio_t *zio; 1180 int err; 1181 int after_branch_point = FALSE; 1182 dsl_pool_t *dp = ds->ds_dir->dd_pool; 1183 objset_t *mos = dp->dp_meta_objset; 1184 dsl_dataset_t *ds_prev = NULL; 1185 uint64_t obj; 1186 1187 ASSERT3U(ds->ds_open_refcount, ==, DS_REF_MAX); 1188 ASSERT3U(ds->ds_phys->ds_num_children, <=, 1); 1189 ASSERT(ds->ds_prev == NULL || 1190 ds->ds_prev->ds_phys->ds_next_snap_obj != ds->ds_object); 1191 ASSERT3U(ds->ds_phys->ds_bp.blk_birth, <=, tx->tx_txg); 1192 1193 ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock)); 1194 1195 obj = ds->ds_object; 1196 1197 if (ds->ds_phys->ds_prev_snap_obj != 0) { 1198 if (ds->ds_prev) { 1199 ds_prev = ds->ds_prev; 1200 } else { 1201 VERIFY(0 == dsl_dataset_open_obj(dp, 1202 ds->ds_phys->ds_prev_snap_obj, NULL, 1203 DS_MODE_NONE, FTAG, &ds_prev)); 1204 } 1205 after_branch_point = 1206 (ds_prev->ds_phys->ds_next_snap_obj != obj); 1207 1208 dmu_buf_will_dirty(ds_prev->ds_dbuf, tx); 1209 if (after_branch_point && 1210 ds->ds_phys->ds_next_snap_obj == 0) { 1211 /* This clone is toast. */ 1212 ASSERT(ds_prev->ds_phys->ds_num_children > 1); 1213 ds_prev->ds_phys->ds_num_children--; 1214 } else if (!after_branch_point) { 1215 ds_prev->ds_phys->ds_next_snap_obj = 1216 ds->ds_phys->ds_next_snap_obj; 1217 } 1218 } 1219 1220 zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); 1221 1222 if (ds->ds_phys->ds_next_snap_obj != 0) { 1223 blkptr_t bp; 1224 dsl_dataset_t *ds_next; 1225 uint64_t itor = 0; 1226 1227 spa_scrub_restart(dp->dp_spa, tx->tx_txg); 1228 1229 VERIFY(0 == dsl_dataset_open_obj(dp, 1230 ds->ds_phys->ds_next_snap_obj, NULL, 1231 DS_MODE_NONE, FTAG, &ds_next)); 1232 ASSERT3U(ds_next->ds_phys->ds_prev_snap_obj, ==, obj); 1233 1234 dmu_buf_will_dirty(ds_next->ds_dbuf, tx); 1235 ds_next->ds_phys->ds_prev_snap_obj = 1236 ds->ds_phys->ds_prev_snap_obj; 1237 ds_next->ds_phys->ds_prev_snap_txg = 1238 ds->ds_phys->ds_prev_snap_txg; 1239 ASSERT3U(ds->ds_phys->ds_prev_snap_txg, ==, 1240 ds_prev ? ds_prev->ds_phys->ds_creation_txg : 0); 1241 1242 /* 1243 * Transfer to our deadlist (which will become next's 1244 * new deadlist) any entries from next's current 1245 * deadlist which were born before prev, and free the 1246 * other entries. 1247 * 1248 * XXX we're doing this long task with the config lock held 1249 */ 1250 while (bplist_iterate(&ds_next->ds_deadlist, &itor, 1251 &bp) == 0) { 1252 if (bp.blk_birth <= ds->ds_phys->ds_prev_snap_txg) { 1253 VERIFY(0 == bplist_enqueue(&ds->ds_deadlist, 1254 &bp, tx)); 1255 if (ds_prev && !after_branch_point && 1256 bp.blk_birth > 1257 ds_prev->ds_phys->ds_prev_snap_txg) { 1258 ds_prev->ds_phys->ds_unique_bytes += 1259 bp_get_dasize(dp->dp_spa, &bp); 1260 } 1261 } else { 1262 used += bp_get_dasize(dp->dp_spa, &bp); 1263 compressed += BP_GET_PSIZE(&bp); 1264 uncompressed += BP_GET_UCSIZE(&bp); 1265 /* XXX check return value? */ 1266 (void) arc_free(zio, dp->dp_spa, tx->tx_txg, 1267 &bp, NULL, NULL, ARC_NOWAIT); 1268 } 1269 } 1270 1271 /* free next's deadlist */ 1272 bplist_close(&ds_next->ds_deadlist); 1273 bplist_destroy(mos, ds_next->ds_phys->ds_deadlist_obj, tx); 1274 1275 /* set next's deadlist to our deadlist */ 1276 ds_next->ds_phys->ds_deadlist_obj = 1277 ds->ds_phys->ds_deadlist_obj; 1278 VERIFY(0 == bplist_open(&ds_next->ds_deadlist, mos, 1279 ds_next->ds_phys->ds_deadlist_obj)); 1280 ds->ds_phys->ds_deadlist_obj = 0; 1281 1282 if (ds_next->ds_phys->ds_next_snap_obj != 0) { 1283 /* 1284 * Update next's unique to include blocks which 1285 * were previously shared by only this snapshot 1286 * and it. Those blocks will be born after the 1287 * prev snap and before this snap, and will have 1288 * died after the next snap and before the one 1289 * after that (ie. be on the snap after next's 1290 * deadlist). 1291 * 1292 * XXX we're doing this long task with the 1293 * config lock held 1294 */ 1295 dsl_dataset_t *ds_after_next; 1296 1297 VERIFY(0 == dsl_dataset_open_obj(dp, 1298 ds_next->ds_phys->ds_next_snap_obj, NULL, 1299 DS_MODE_NONE, FTAG, &ds_after_next)); 1300 itor = 0; 1301 while (bplist_iterate(&ds_after_next->ds_deadlist, 1302 &itor, &bp) == 0) { 1303 if (bp.blk_birth > 1304 ds->ds_phys->ds_prev_snap_txg && 1305 bp.blk_birth <= 1306 ds->ds_phys->ds_creation_txg) { 1307 ds_next->ds_phys->ds_unique_bytes += 1308 bp_get_dasize(dp->dp_spa, &bp); 1309 } 1310 } 1311 1312 dsl_dataset_close(ds_after_next, DS_MODE_NONE, FTAG); 1313 ASSERT3P(ds_next->ds_prev, ==, NULL); 1314 } else { 1315 /* 1316 * It would be nice to update the head dataset's 1317 * unique. To do so we would have to traverse 1318 * it for blocks born after ds_prev, which is 1319 * pretty expensive just to maintain something 1320 * for debugging purposes. 1321 */ 1322 ASSERT3P(ds_next->ds_prev, ==, ds); 1323 dsl_dataset_close(ds_next->ds_prev, DS_MODE_NONE, 1324 ds_next); 1325 if (ds_prev) { 1326 VERIFY(0 == dsl_dataset_open_obj(dp, 1327 ds->ds_phys->ds_prev_snap_obj, NULL, 1328 DS_MODE_NONE, ds_next, &ds_next->ds_prev)); 1329 } else { 1330 ds_next->ds_prev = NULL; 1331 } 1332 } 1333 dsl_dataset_close(ds_next, DS_MODE_NONE, FTAG); 1334 1335 /* 1336 * NB: unique_bytes is not accurate for head objsets 1337 * because we don't update it when we delete the most 1338 * recent snapshot -- see above comment. 1339 */ 1340 ASSERT3U(used, ==, ds->ds_phys->ds_unique_bytes); 1341 } else { 1342 /* 1343 * There's no next snapshot, so this is a head dataset. 1344 * Destroy the deadlist. Unless it's a clone, the 1345 * deadlist should be empty. (If it's a clone, it's 1346 * safe to ignore the deadlist contents.) 1347 */ 1348 struct killarg ka; 1349 1350 ASSERT(after_branch_point || bplist_empty(&ds->ds_deadlist)); 1351 bplist_close(&ds->ds_deadlist); 1352 bplist_destroy(mos, ds->ds_phys->ds_deadlist_obj, tx); 1353 ds->ds_phys->ds_deadlist_obj = 0; 1354 1355 /* 1356 * Free everything that we point to (that's born after 1357 * the previous snapshot, if we are a clone) 1358 * 1359 * XXX we're doing this long task with the config lock held 1360 */ 1361 ka.usedp = &used; 1362 ka.compressedp = &compressed; 1363 ka.uncompressedp = &uncompressed; 1364 ka.zio = zio; 1365 ka.tx = tx; 1366 err = traverse_dsl_dataset(ds, ds->ds_phys->ds_prev_snap_txg, 1367 ADVANCE_POST, kill_blkptr, &ka); 1368 ASSERT3U(err, ==, 0); 1369 } 1370 1371 err = zio_wait(zio); 1372 ASSERT3U(err, ==, 0); 1373 1374 dsl_dir_diduse_space(ds->ds_dir, -used, -compressed, -uncompressed, tx); 1375 1376 if (ds->ds_phys->ds_snapnames_zapobj) { 1377 err = zap_destroy(mos, ds->ds_phys->ds_snapnames_zapobj, tx); 1378 ASSERT(err == 0); 1379 } 1380 1381 if (ds->ds_dir->dd_phys->dd_head_dataset_obj == ds->ds_object) { 1382 /* Erase the link in the dataset */ 1383 dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx); 1384 ds->ds_dir->dd_phys->dd_head_dataset_obj = 0; 1385 /* 1386 * dsl_dir_sync_destroy() called us, they'll destroy 1387 * the dataset. 1388 */ 1389 } else { 1390 /* remove from snapshot namespace */ 1391 dsl_dataset_t *ds_head; 1392 VERIFY(0 == dsl_dataset_open_obj(dp, 1393 ds->ds_dir->dd_phys->dd_head_dataset_obj, NULL, 1394 DS_MODE_NONE, FTAG, &ds_head)); 1395 VERIFY(0 == dsl_dataset_get_snapname(ds)); 1396 #ifdef ZFS_DEBUG 1397 { 1398 uint64_t val; 1399 err = zap_lookup(mos, 1400 ds_head->ds_phys->ds_snapnames_zapobj, 1401 ds->ds_snapname, 8, 1, &val); 1402 ASSERT3U(err, ==, 0); 1403 ASSERT3U(val, ==, obj); 1404 } 1405 #endif 1406 err = zap_remove(mos, ds_head->ds_phys->ds_snapnames_zapobj, 1407 ds->ds_snapname, tx); 1408 ASSERT(err == 0); 1409 dsl_dataset_close(ds_head, DS_MODE_NONE, FTAG); 1410 } 1411 1412 if (ds_prev && ds->ds_prev != ds_prev) 1413 dsl_dataset_close(ds_prev, DS_MODE_NONE, FTAG); 1414 1415 spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx); 1416 spa_history_internal_log(LOG_DS_DESTROY, dp->dp_spa, tx, 1417 cr, "dataset = %llu", ds->ds_object); 1418 1419 dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, tag); 1420 VERIFY(0 == dmu_object_free(mos, obj, tx)); 1421 1422 } 1423 1424 /* ARGSUSED */ 1425 int 1426 dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx) 1427 { 1428 dsl_dataset_t *ds = arg1; 1429 const char *snapname = arg2; 1430 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; 1431 int err; 1432 uint64_t value; 1433 1434 /* 1435 * We don't allow multiple snapshots of the same txg. If there 1436 * is already one, try again. 1437 */ 1438 if (ds->ds_phys->ds_prev_snap_txg >= tx->tx_txg) 1439 return (EAGAIN); 1440 1441 /* 1442 * Check for conflicting name snapshot name. 1443 */ 1444 err = zap_lookup(mos, ds->ds_phys->ds_snapnames_zapobj, 1445 snapname, 8, 1, &value); 1446 if (err == 0) 1447 return (EEXIST); 1448 if (err != ENOENT) 1449 return (err); 1450 1451 /* 1452 * Check that the dataset's name is not too long. Name consists 1453 * of the dataset's length + 1 for the @-sign + snapshot name's length 1454 */ 1455 if (dsl_dataset_namelen(ds) + 1 + strlen(snapname) >= MAXNAMELEN) 1456 return (ENAMETOOLONG); 1457 1458 ds->ds_trysnap_txg = tx->tx_txg; 1459 return (0); 1460 } 1461 1462 void 1463 dsl_dataset_snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) 1464 { 1465 dsl_dataset_t *ds = arg1; 1466 const char *snapname = arg2; 1467 dsl_pool_t *dp = ds->ds_dir->dd_pool; 1468 dmu_buf_t *dbuf; 1469 dsl_dataset_phys_t *dsphys; 1470 uint64_t dsobj; 1471 objset_t *mos = dp->dp_meta_objset; 1472 int err; 1473 1474 spa_scrub_restart(dp->dp_spa, tx->tx_txg); 1475 ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock)); 1476 1477 dsobj = dmu_object_alloc(mos, DMU_OT_DSL_DATASET, 0, 1478 DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx); 1479 VERIFY(0 == dmu_bonus_hold(mos, dsobj, FTAG, &dbuf)); 1480 dmu_buf_will_dirty(dbuf, tx); 1481 dsphys = dbuf->db_data; 1482 dsphys->ds_dir_obj = ds->ds_dir->dd_object; 1483 dsphys->ds_fsid_guid = unique_create(); 1484 (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid, 1485 sizeof (dsphys->ds_guid)); 1486 dsphys->ds_prev_snap_obj = ds->ds_phys->ds_prev_snap_obj; 1487 dsphys->ds_prev_snap_txg = ds->ds_phys->ds_prev_snap_txg; 1488 dsphys->ds_next_snap_obj = ds->ds_object; 1489 dsphys->ds_num_children = 1; 1490 dsphys->ds_creation_time = gethrestime_sec(); 1491 dsphys->ds_creation_txg = tx->tx_txg; 1492 dsphys->ds_deadlist_obj = ds->ds_phys->ds_deadlist_obj; 1493 dsphys->ds_used_bytes = ds->ds_phys->ds_used_bytes; 1494 dsphys->ds_compressed_bytes = ds->ds_phys->ds_compressed_bytes; 1495 dsphys->ds_uncompressed_bytes = ds->ds_phys->ds_uncompressed_bytes; 1496 dsphys->ds_flags = ds->ds_phys->ds_flags; 1497 dsphys->ds_bp = ds->ds_phys->ds_bp; 1498 dmu_buf_rele(dbuf, FTAG); 1499 1500 ASSERT3U(ds->ds_prev != 0, ==, ds->ds_phys->ds_prev_snap_obj != 0); 1501 if (ds->ds_prev) { 1502 ASSERT(ds->ds_prev->ds_phys->ds_next_snap_obj == 1503 ds->ds_object || 1504 ds->ds_prev->ds_phys->ds_num_children > 1); 1505 if (ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) { 1506 dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx); 1507 ASSERT3U(ds->ds_phys->ds_prev_snap_txg, ==, 1508 ds->ds_prev->ds_phys->ds_creation_txg); 1509 ds->ds_prev->ds_phys->ds_next_snap_obj = dsobj; 1510 } 1511 } 1512 1513 bplist_close(&ds->ds_deadlist); 1514 dmu_buf_will_dirty(ds->ds_dbuf, tx); 1515 ASSERT3U(ds->ds_phys->ds_prev_snap_txg, <, dsphys->ds_creation_txg); 1516 ds->ds_phys->ds_prev_snap_obj = dsobj; 1517 ds->ds_phys->ds_prev_snap_txg = dsphys->ds_creation_txg; 1518 ds->ds_phys->ds_unique_bytes = 0; 1519 ds->ds_phys->ds_deadlist_obj = 1520 bplist_create(mos, DSL_DEADLIST_BLOCKSIZE, tx); 1521 VERIFY(0 == bplist_open(&ds->ds_deadlist, mos, 1522 ds->ds_phys->ds_deadlist_obj)); 1523 1524 dprintf("snap '%s' -> obj %llu\n", snapname, dsobj); 1525 err = zap_add(mos, ds->ds_phys->ds_snapnames_zapobj, 1526 snapname, 8, 1, &dsobj, tx); 1527 ASSERT(err == 0); 1528 1529 if (ds->ds_prev) 1530 dsl_dataset_close(ds->ds_prev, DS_MODE_NONE, ds); 1531 VERIFY(0 == dsl_dataset_open_obj(dp, 1532 ds->ds_phys->ds_prev_snap_obj, snapname, 1533 DS_MODE_NONE, ds, &ds->ds_prev)); 1534 1535 spa_history_internal_log(LOG_DS_SNAPSHOT, dp->dp_spa, tx, cr, 1536 "dataset = %llu", dsobj); 1537 } 1538 1539 void 1540 dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx) 1541 { 1542 ASSERT(dmu_tx_is_syncing(tx)); 1543 ASSERT(ds->ds_user_ptr != NULL); 1544 ASSERT(ds->ds_phys->ds_next_snap_obj == 0); 1545 1546 /* 1547 * in case we had to change ds_fsid_guid when we opened it, 1548 * sync it out now. 1549 */ 1550 dmu_buf_will_dirty(ds->ds_dbuf, tx); 1551 ds->ds_phys->ds_fsid_guid = ds->ds_fsid_guid; 1552 1553 dsl_dir_dirty(ds->ds_dir, tx); 1554 dmu_objset_sync(ds->ds_user_ptr, zio, tx); 1555 } 1556 1557 void 1558 dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv) 1559 { 1560 dsl_dir_stats(ds->ds_dir, nv); 1561 1562 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_CREATION, 1563 ds->ds_phys->ds_creation_time); 1564 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_CREATETXG, 1565 ds->ds_phys->ds_creation_txg); 1566 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFERENCED, 1567 ds->ds_phys->ds_used_bytes); 1568 1569 if (ds->ds_phys->ds_next_snap_obj) { 1570 /* 1571 * This is a snapshot; override the dd's space used with 1572 * our unique space and compression ratio. 1573 */ 1574 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, 1575 ds->ds_phys->ds_unique_bytes); 1576 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, 1577 ds->ds_phys->ds_compressed_bytes == 0 ? 100 : 1578 (ds->ds_phys->ds_uncompressed_bytes * 100 / 1579 ds->ds_phys->ds_compressed_bytes)); 1580 } 1581 } 1582 1583 void 1584 dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat) 1585 { 1586 stat->dds_creation_txg = ds->ds_phys->ds_creation_txg; 1587 stat->dds_inconsistent = ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT; 1588 stat->dds_guid = ds->ds_phys->ds_guid; 1589 if (ds->ds_phys->ds_next_snap_obj) { 1590 stat->dds_is_snapshot = B_TRUE; 1591 stat->dds_num_clones = ds->ds_phys->ds_num_children - 1; 1592 } 1593 1594 /* clone origin is really a dsl_dir thing... */ 1595 if (ds->ds_dir->dd_phys->dd_origin_obj) { 1596 dsl_dataset_t *ods; 1597 1598 rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER); 1599 VERIFY(0 == dsl_dataset_open_obj(ds->ds_dir->dd_pool, 1600 ds->ds_dir->dd_phys->dd_origin_obj, 1601 NULL, DS_MODE_NONE, FTAG, &ods)); 1602 dsl_dataset_name(ods, stat->dds_origin); 1603 dsl_dataset_close(ods, DS_MODE_NONE, FTAG); 1604 rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock); 1605 } 1606 } 1607 1608 uint64_t 1609 dsl_dataset_fsid_guid(dsl_dataset_t *ds) 1610 { 1611 return (ds->ds_fsid_guid); 1612 } 1613 1614 void 1615 dsl_dataset_space(dsl_dataset_t *ds, 1616 uint64_t *refdbytesp, uint64_t *availbytesp, 1617 uint64_t *usedobjsp, uint64_t *availobjsp) 1618 { 1619 *refdbytesp = ds->ds_phys->ds_used_bytes; 1620 *availbytesp = dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE); 1621 *usedobjsp = ds->ds_phys->ds_bp.blk_fill; 1622 *availobjsp = DN_MAX_OBJECT - *usedobjsp; 1623 } 1624 1625 boolean_t 1626 dsl_dataset_modified_since_lastsnap(dsl_dataset_t *ds) 1627 { 1628 dsl_pool_t *dp = ds->ds_dir->dd_pool; 1629 1630 ASSERT(RW_LOCK_HELD(&dp->dp_config_rwlock) || 1631 dsl_pool_sync_context(dp)); 1632 if (ds->ds_prev == NULL) 1633 return (B_FALSE); 1634 if (ds->ds_phys->ds_bp.blk_birth > 1635 ds->ds_prev->ds_phys->ds_creation_txg) 1636 return (B_TRUE); 1637 return (B_FALSE); 1638 } 1639 1640 /* ARGSUSED */ 1641 static int 1642 dsl_dataset_snapshot_rename_check(void *arg1, void *arg2, dmu_tx_t *tx) 1643 { 1644 dsl_dataset_t *ds = arg1; 1645 char *newsnapname = arg2; 1646 dsl_dir_t *dd = ds->ds_dir; 1647 objset_t *mos = dd->dd_pool->dp_meta_objset; 1648 dsl_dataset_t *hds; 1649 uint64_t val; 1650 int err; 1651 1652 err = dsl_dataset_open_obj(dd->dd_pool, 1653 dd->dd_phys->dd_head_dataset_obj, NULL, DS_MODE_NONE, FTAG, &hds); 1654 if (err) 1655 return (err); 1656 1657 /* new name better not be in use */ 1658 err = zap_lookup(mos, hds->ds_phys->ds_snapnames_zapobj, 1659 newsnapname, 8, 1, &val); 1660 dsl_dataset_close(hds, DS_MODE_NONE, FTAG); 1661 1662 if (err == 0) 1663 err = EEXIST; 1664 else if (err == ENOENT) 1665 err = 0; 1666 1667 /* dataset name + 1 for the "@" + the new snapshot name must fit */ 1668 if (dsl_dir_namelen(ds->ds_dir) + 1 + strlen(newsnapname) >= MAXNAMELEN) 1669 err = ENAMETOOLONG; 1670 1671 return (err); 1672 } 1673 1674 static void 1675 dsl_dataset_snapshot_rename_sync(void *arg1, void *arg2, 1676 cred_t *cr, dmu_tx_t *tx) 1677 { 1678 dsl_dataset_t *ds = arg1; 1679 const char *newsnapname = arg2; 1680 dsl_dir_t *dd = ds->ds_dir; 1681 objset_t *mos = dd->dd_pool->dp_meta_objset; 1682 dsl_dataset_t *hds; 1683 int err; 1684 1685 ASSERT(ds->ds_phys->ds_next_snap_obj != 0); 1686 1687 VERIFY(0 == dsl_dataset_open_obj(dd->dd_pool, 1688 dd->dd_phys->dd_head_dataset_obj, NULL, DS_MODE_NONE, FTAG, &hds)); 1689 1690 VERIFY(0 == dsl_dataset_get_snapname(ds)); 1691 err = zap_remove(mos, hds->ds_phys->ds_snapnames_zapobj, 1692 ds->ds_snapname, tx); 1693 ASSERT3U(err, ==, 0); 1694 mutex_enter(&ds->ds_lock); 1695 (void) strcpy(ds->ds_snapname, newsnapname); 1696 mutex_exit(&ds->ds_lock); 1697 err = zap_add(mos, hds->ds_phys->ds_snapnames_zapobj, 1698 ds->ds_snapname, 8, 1, &ds->ds_object, tx); 1699 ASSERT3U(err, ==, 0); 1700 1701 spa_history_internal_log(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx, 1702 cr, "dataset = %llu", ds->ds_object); 1703 dsl_dataset_close(hds, DS_MODE_NONE, FTAG); 1704 } 1705 1706 struct renamesnaparg { 1707 dsl_sync_task_group_t *dstg; 1708 char failed[MAXPATHLEN]; 1709 char *oldsnap; 1710 char *newsnap; 1711 }; 1712 1713 static int 1714 dsl_snapshot_rename_one(char *name, void *arg) 1715 { 1716 struct renamesnaparg *ra = arg; 1717 dsl_dataset_t *ds = NULL; 1718 char *cp; 1719 int err; 1720 1721 cp = name + strlen(name); 1722 *cp = '@'; 1723 (void) strcpy(cp + 1, ra->oldsnap); 1724 1725 /* 1726 * For recursive snapshot renames the parent won't be changing 1727 * so we just pass name for both the to/from argument. 1728 */ 1729 if (err = zfs_secpolicy_rename_perms(name, name, CRED())) { 1730 (void) strcpy(ra->failed, name); 1731 return (err); 1732 } 1733 1734 err = dsl_dataset_open(name, DS_MODE_READONLY | DS_MODE_STANDARD, 1735 ra->dstg, &ds); 1736 if (err == ENOENT) { 1737 *cp = '\0'; 1738 return (0); 1739 } 1740 if (err) { 1741 (void) strcpy(ra->failed, name); 1742 *cp = '\0'; 1743 dsl_dataset_close(ds, DS_MODE_STANDARD, ra->dstg); 1744 return (err); 1745 } 1746 1747 #ifdef _KERNEL 1748 /* for all filesystems undergoing rename, we'll need to unmount it */ 1749 (void) zfs_unmount_snap(name, NULL); 1750 #endif 1751 1752 *cp = '\0'; 1753 1754 dsl_sync_task_create(ra->dstg, dsl_dataset_snapshot_rename_check, 1755 dsl_dataset_snapshot_rename_sync, ds, ra->newsnap, 0); 1756 1757 return (0); 1758 } 1759 1760 static int 1761 dsl_recursive_rename(char *oldname, const char *newname) 1762 { 1763 int err; 1764 struct renamesnaparg *ra; 1765 dsl_sync_task_t *dst; 1766 spa_t *spa; 1767 char *cp, *fsname = spa_strdup(oldname); 1768 int len = strlen(oldname); 1769 1770 /* truncate the snapshot name to get the fsname */ 1771 cp = strchr(fsname, '@'); 1772 *cp = '\0'; 1773 1774 err = spa_open(fsname, &spa, FTAG); 1775 if (err) { 1776 kmem_free(fsname, len + 1); 1777 return (err); 1778 } 1779 ra = kmem_alloc(sizeof (struct renamesnaparg), KM_SLEEP); 1780 ra->dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); 1781 1782 ra->oldsnap = strchr(oldname, '@') + 1; 1783 ra->newsnap = strchr(newname, '@') + 1; 1784 *ra->failed = '\0'; 1785 1786 err = dmu_objset_find(fsname, dsl_snapshot_rename_one, ra, 1787 DS_FIND_CHILDREN); 1788 kmem_free(fsname, len + 1); 1789 1790 if (err == 0) { 1791 err = dsl_sync_task_group_wait(ra->dstg); 1792 } 1793 1794 for (dst = list_head(&ra->dstg->dstg_tasks); dst; 1795 dst = list_next(&ra->dstg->dstg_tasks, dst)) { 1796 dsl_dataset_t *ds = dst->dst_arg1; 1797 if (dst->dst_err) { 1798 dsl_dir_name(ds->ds_dir, ra->failed); 1799 (void) strcat(ra->failed, "@"); 1800 (void) strcat(ra->failed, ra->newsnap); 1801 } 1802 dsl_dataset_close(ds, DS_MODE_STANDARD, ra->dstg); 1803 } 1804 1805 if (err) 1806 (void) strcpy(oldname, ra->failed); 1807 1808 dsl_sync_task_group_destroy(ra->dstg); 1809 kmem_free(ra, sizeof (struct renamesnaparg)); 1810 spa_close(spa, FTAG); 1811 return (err); 1812 } 1813 1814 static int 1815 dsl_valid_rename(char *oldname, void *arg) 1816 { 1817 int delta = *(int *)arg; 1818 1819 if (strlen(oldname) + delta >= MAXNAMELEN) 1820 return (ENAMETOOLONG); 1821 1822 return (0); 1823 } 1824 1825 #pragma weak dmu_objset_rename = dsl_dataset_rename 1826 int 1827 dsl_dataset_rename(char *oldname, const char *newname, 1828 boolean_t recursive) 1829 { 1830 dsl_dir_t *dd; 1831 dsl_dataset_t *ds; 1832 const char *tail; 1833 int err; 1834 1835 err = dsl_dir_open(oldname, FTAG, &dd, &tail); 1836 if (err) 1837 return (err); 1838 if (tail == NULL) { 1839 int delta = strlen(newname) - strlen(oldname); 1840 1841 /* if we're growing, validate child size lengths */ 1842 if (delta > 0) 1843 err = dmu_objset_find(oldname, dsl_valid_rename, 1844 &delta, DS_FIND_CHILDREN | DS_FIND_SNAPSHOTS); 1845 1846 if (!err) 1847 err = dsl_dir_rename(dd, newname); 1848 dsl_dir_close(dd, FTAG); 1849 return (err); 1850 } 1851 if (tail[0] != '@') { 1852 /* the name ended in a nonexistant component */ 1853 dsl_dir_close(dd, FTAG); 1854 return (ENOENT); 1855 } 1856 1857 dsl_dir_close(dd, FTAG); 1858 1859 /* new name must be snapshot in same filesystem */ 1860 tail = strchr(newname, '@'); 1861 if (tail == NULL) 1862 return (EINVAL); 1863 tail++; 1864 if (strncmp(oldname, newname, tail - newname) != 0) 1865 return (EXDEV); 1866 1867 if (recursive) { 1868 err = dsl_recursive_rename(oldname, newname); 1869 } else { 1870 err = dsl_dataset_open(oldname, 1871 DS_MODE_READONLY | DS_MODE_STANDARD, FTAG, &ds); 1872 if (err) 1873 return (err); 1874 1875 err = dsl_sync_task_do(ds->ds_dir->dd_pool, 1876 dsl_dataset_snapshot_rename_check, 1877 dsl_dataset_snapshot_rename_sync, ds, (char *)tail, 1); 1878 1879 dsl_dataset_close(ds, DS_MODE_STANDARD, FTAG); 1880 } 1881 1882 return (err); 1883 } 1884 1885 struct promotearg { 1886 uint64_t used, comp, uncomp, unique; 1887 uint64_t newnext_obj, snapnames_obj; 1888 }; 1889 1890 /* ARGSUSED */ 1891 static int 1892 dsl_dataset_promote_check(void *arg1, void *arg2, dmu_tx_t *tx) 1893 { 1894 dsl_dataset_t *hds = arg1; 1895 struct promotearg *pa = arg2; 1896 dsl_dir_t *dd = hds->ds_dir; 1897 dsl_pool_t *dp = hds->ds_dir->dd_pool; 1898 dsl_dir_t *odd = NULL; 1899 dsl_dataset_t *ds = NULL; 1900 dsl_dataset_t *origin_ds = NULL; 1901 dsl_dataset_t *newnext_ds = NULL; 1902 int err; 1903 char *name = NULL; 1904 uint64_t itor = 0; 1905 blkptr_t bp; 1906 1907 bzero(pa, sizeof (*pa)); 1908 1909 /* Check that it is a clone */ 1910 if (dd->dd_phys->dd_origin_obj == 0) 1911 return (EINVAL); 1912 1913 /* Since this is so expensive, don't do the preliminary check */ 1914 if (!dmu_tx_is_syncing(tx)) 1915 return (0); 1916 1917 if (err = dsl_dataset_open_obj(dp, dd->dd_phys->dd_origin_obj, 1918 NULL, DS_MODE_EXCLUSIVE, FTAG, &origin_ds)) 1919 goto out; 1920 odd = origin_ds->ds_dir; 1921 1922 { 1923 dsl_dataset_t *phds; 1924 if (err = dsl_dataset_open_obj(dd->dd_pool, 1925 odd->dd_phys->dd_head_dataset_obj, 1926 NULL, DS_MODE_NONE, FTAG, &phds)) 1927 goto out; 1928 pa->snapnames_obj = phds->ds_phys->ds_snapnames_zapobj; 1929 dsl_dataset_close(phds, DS_MODE_NONE, FTAG); 1930 } 1931 1932 if (hds->ds_phys->ds_flags & DS_FLAG_NOPROMOTE) { 1933 err = EXDEV; 1934 goto out; 1935 } 1936 1937 /* find origin's new next ds */ 1938 VERIFY(0 == dsl_dataset_open_obj(dd->dd_pool, hds->ds_object, 1939 NULL, DS_MODE_NONE, FTAG, &newnext_ds)); 1940 while (newnext_ds->ds_phys->ds_prev_snap_obj != origin_ds->ds_object) { 1941 dsl_dataset_t *prev; 1942 1943 if (err = dsl_dataset_open_obj(dd->dd_pool, 1944 newnext_ds->ds_phys->ds_prev_snap_obj, 1945 NULL, DS_MODE_NONE, FTAG, &prev)) 1946 goto out; 1947 dsl_dataset_close(newnext_ds, DS_MODE_NONE, FTAG); 1948 newnext_ds = prev; 1949 } 1950 pa->newnext_obj = newnext_ds->ds_object; 1951 1952 /* compute origin's new unique space */ 1953 while ((err = bplist_iterate(&newnext_ds->ds_deadlist, 1954 &itor, &bp)) == 0) { 1955 if (bp.blk_birth > origin_ds->ds_phys->ds_prev_snap_txg) 1956 pa->unique += bp_get_dasize(dd->dd_pool->dp_spa, &bp); 1957 } 1958 if (err != ENOENT) 1959 goto out; 1960 1961 /* Walk the snapshots that we are moving */ 1962 name = kmem_alloc(MAXPATHLEN, KM_SLEEP); 1963 ds = origin_ds; 1964 /* CONSTCOND */ 1965 while (TRUE) { 1966 uint64_t val, dlused, dlcomp, dluncomp; 1967 dsl_dataset_t *prev; 1968 1969 /* Check that the snapshot name does not conflict */ 1970 dsl_dataset_name(ds, name); 1971 err = zap_lookup(dd->dd_pool->dp_meta_objset, 1972 hds->ds_phys->ds_snapnames_zapobj, ds->ds_snapname, 1973 8, 1, &val); 1974 if (err != ENOENT) { 1975 if (err == 0) 1976 err = EEXIST; 1977 goto out; 1978 } 1979 1980 /* 1981 * compute space to transfer. Each snapshot gave birth to: 1982 * (my used) - (prev's used) + (deadlist's used) 1983 */ 1984 pa->used += ds->ds_phys->ds_used_bytes; 1985 pa->comp += ds->ds_phys->ds_compressed_bytes; 1986 pa->uncomp += ds->ds_phys->ds_uncompressed_bytes; 1987 1988 /* If we reach the first snapshot, we're done. */ 1989 if (ds->ds_phys->ds_prev_snap_obj == 0) 1990 break; 1991 1992 if (err = bplist_space(&ds->ds_deadlist, 1993 &dlused, &dlcomp, &dluncomp)) 1994 goto out; 1995 if (err = dsl_dataset_open_obj(dd->dd_pool, 1996 ds->ds_phys->ds_prev_snap_obj, NULL, DS_MODE_EXCLUSIVE, 1997 FTAG, &prev)) 1998 goto out; 1999 pa->used += dlused - prev->ds_phys->ds_used_bytes; 2000 pa->comp += dlcomp - prev->ds_phys->ds_compressed_bytes; 2001 pa->uncomp += dluncomp - prev->ds_phys->ds_uncompressed_bytes; 2002 2003 /* 2004 * We could be a clone of a clone. If we reach our 2005 * parent's branch point, we're done. 2006 */ 2007 if (prev->ds_phys->ds_next_snap_obj != ds->ds_object) { 2008 dsl_dataset_close(prev, DS_MODE_EXCLUSIVE, FTAG); 2009 break; 2010 } 2011 if (ds != origin_ds) 2012 dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); 2013 ds = prev; 2014 } 2015 2016 /* Check that there is enough space here */ 2017 err = dsl_dir_transfer_possible(odd, dd, pa->used); 2018 2019 out: 2020 if (ds && ds != origin_ds) 2021 dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); 2022 if (origin_ds) 2023 dsl_dataset_close(origin_ds, DS_MODE_EXCLUSIVE, FTAG); 2024 if (newnext_ds) 2025 dsl_dataset_close(newnext_ds, DS_MODE_NONE, FTAG); 2026 if (name) 2027 kmem_free(name, MAXPATHLEN); 2028 return (err); 2029 } 2030 2031 static void 2032 dsl_dataset_promote_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) 2033 { 2034 dsl_dataset_t *hds = arg1; 2035 struct promotearg *pa = arg2; 2036 dsl_dir_t *dd = hds->ds_dir; 2037 dsl_pool_t *dp = hds->ds_dir->dd_pool; 2038 dsl_dir_t *odd = NULL; 2039 dsl_dataset_t *ds, *origin_ds; 2040 char *name; 2041 2042 ASSERT(dd->dd_phys->dd_origin_obj != 0); 2043 ASSERT(0 == (hds->ds_phys->ds_flags & DS_FLAG_NOPROMOTE)); 2044 2045 VERIFY(0 == dsl_dataset_open_obj(dp, dd->dd_phys->dd_origin_obj, 2046 NULL, DS_MODE_EXCLUSIVE, FTAG, &origin_ds)); 2047 /* 2048 * We need to explicitly open odd, since origin_ds's dd will be 2049 * changing. 2050 */ 2051 VERIFY(0 == dsl_dir_open_obj(dp, origin_ds->ds_dir->dd_object, 2052 NULL, FTAG, &odd)); 2053 2054 /* move snapshots to this dir */ 2055 name = kmem_alloc(MAXPATHLEN, KM_SLEEP); 2056 ds = origin_ds; 2057 /* CONSTCOND */ 2058 while (TRUE) { 2059 dsl_dataset_t *prev; 2060 2061 /* move snap name entry */ 2062 dsl_dataset_name(ds, name); 2063 VERIFY(0 == zap_remove(dp->dp_meta_objset, 2064 pa->snapnames_obj, ds->ds_snapname, tx)); 2065 VERIFY(0 == zap_add(dp->dp_meta_objset, 2066 hds->ds_phys->ds_snapnames_zapobj, ds->ds_snapname, 2067 8, 1, &ds->ds_object, tx)); 2068 2069 /* change containing dsl_dir */ 2070 dmu_buf_will_dirty(ds->ds_dbuf, tx); 2071 ASSERT3U(ds->ds_phys->ds_dir_obj, ==, odd->dd_object); 2072 ds->ds_phys->ds_dir_obj = dd->dd_object; 2073 ASSERT3P(ds->ds_dir, ==, odd); 2074 dsl_dir_close(ds->ds_dir, ds); 2075 VERIFY(0 == dsl_dir_open_obj(dp, dd->dd_object, 2076 NULL, ds, &ds->ds_dir)); 2077 2078 ASSERT3U(dsl_prop_numcb(ds), ==, 0); 2079 2080 if (ds->ds_phys->ds_prev_snap_obj == 0) 2081 break; 2082 2083 VERIFY(0 == dsl_dataset_open_obj(dp, 2084 ds->ds_phys->ds_prev_snap_obj, NULL, DS_MODE_EXCLUSIVE, 2085 FTAG, &prev)); 2086 2087 if (prev->ds_phys->ds_next_snap_obj != ds->ds_object) { 2088 dsl_dataset_close(prev, DS_MODE_EXCLUSIVE, FTAG); 2089 break; 2090 } 2091 if (ds != origin_ds) 2092 dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); 2093 ds = prev; 2094 } 2095 if (ds != origin_ds) 2096 dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); 2097 2098 /* change origin's next snap */ 2099 dmu_buf_will_dirty(origin_ds->ds_dbuf, tx); 2100 origin_ds->ds_phys->ds_next_snap_obj = pa->newnext_obj; 2101 2102 /* change origin */ 2103 dmu_buf_will_dirty(dd->dd_dbuf, tx); 2104 ASSERT3U(dd->dd_phys->dd_origin_obj, ==, origin_ds->ds_object); 2105 dd->dd_phys->dd_origin_obj = odd->dd_phys->dd_origin_obj; 2106 dmu_buf_will_dirty(odd->dd_dbuf, tx); 2107 odd->dd_phys->dd_origin_obj = origin_ds->ds_object; 2108 2109 /* change space accounting */ 2110 dsl_dir_diduse_space(odd, -pa->used, -pa->comp, -pa->uncomp, tx); 2111 dsl_dir_diduse_space(dd, pa->used, pa->comp, pa->uncomp, tx); 2112 origin_ds->ds_phys->ds_unique_bytes = pa->unique; 2113 2114 /* log history record */ 2115 spa_history_internal_log(LOG_DS_PROMOTE, dd->dd_pool->dp_spa, tx, 2116 cr, "dataset = %llu", ds->ds_object); 2117 2118 dsl_dir_close(odd, FTAG); 2119 dsl_dataset_close(origin_ds, DS_MODE_EXCLUSIVE, FTAG); 2120 kmem_free(name, MAXPATHLEN); 2121 } 2122 2123 int 2124 dsl_dataset_promote(const char *name) 2125 { 2126 dsl_dataset_t *ds; 2127 int err; 2128 dmu_object_info_t doi; 2129 struct promotearg pa; 2130 2131 err = dsl_dataset_open(name, DS_MODE_NONE, FTAG, &ds); 2132 if (err) 2133 return (err); 2134 2135 err = dmu_object_info(ds->ds_dir->dd_pool->dp_meta_objset, 2136 ds->ds_phys->ds_snapnames_zapobj, &doi); 2137 if (err) { 2138 dsl_dataset_close(ds, DS_MODE_NONE, FTAG); 2139 return (err); 2140 } 2141 2142 /* 2143 * Add in 128x the snapnames zapobj size, since we will be moving 2144 * a bunch of snapnames to the promoted ds, and dirtying their 2145 * bonus buffers. 2146 */ 2147 err = dsl_sync_task_do(ds->ds_dir->dd_pool, 2148 dsl_dataset_promote_check, 2149 dsl_dataset_promote_sync, ds, &pa, 2 + 2 * doi.doi_physical_blks); 2150 dsl_dataset_close(ds, DS_MODE_NONE, FTAG); 2151 return (err); 2152 } 2153 2154 struct cloneswaparg { 2155 dsl_dataset_t *cds; /* clone dataset */ 2156 dsl_dataset_t *ohds; /* origin's head dataset */ 2157 boolean_t force; 2158 }; 2159 2160 /* ARGSUSED */ 2161 static int 2162 dsl_dataset_clone_swap_check(void *arg1, void *arg2, dmu_tx_t *tx) 2163 { 2164 struct cloneswaparg *csa = arg1; 2165 2166 /* they should both be heads */ 2167 if (dsl_dataset_is_snapshot(csa->cds) || 2168 dsl_dataset_is_snapshot(csa->ohds)) 2169 return (EINVAL); 2170 2171 /* the branch point should be just before them */ 2172 if (csa->cds->ds_prev != csa->ohds->ds_prev) 2173 return (EINVAL); 2174 2175 /* cds should be the clone */ 2176 if (csa->cds->ds_prev->ds_phys->ds_next_snap_obj != 2177 csa->ohds->ds_object) 2178 return (EINVAL); 2179 2180 /* the clone should be a child of the origin */ 2181 if (csa->cds->ds_dir->dd_parent != csa->ohds->ds_dir) 2182 return (EINVAL); 2183 2184 /* ohds shouldn't be modified unless 'force' */ 2185 if (!csa->force && dsl_dataset_modified_since_lastsnap(csa->ohds)) 2186 return (ETXTBSY); 2187 return (0); 2188 } 2189 2190 /* ARGSUSED */ 2191 static void 2192 dsl_dataset_clone_swap_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) 2193 { 2194 struct cloneswaparg *csa = arg1; 2195 dsl_pool_t *dp = csa->cds->ds_dir->dd_pool; 2196 uint64_t itor = 0; 2197 blkptr_t bp; 2198 uint64_t unique = 0; 2199 int err; 2200 2201 dmu_buf_will_dirty(csa->cds->ds_dbuf, tx); 2202 dmu_buf_will_dirty(csa->ohds->ds_dbuf, tx); 2203 dmu_buf_will_dirty(csa->cds->ds_prev->ds_dbuf, tx); 2204 2205 if (csa->cds->ds_user_ptr != NULL) { 2206 csa->cds->ds_user_evict_func(csa->cds, csa->cds->ds_user_ptr); 2207 csa->cds->ds_user_ptr = NULL; 2208 } 2209 2210 if (csa->ohds->ds_user_ptr != NULL) { 2211 csa->ohds->ds_user_evict_func(csa->ohds, 2212 csa->ohds->ds_user_ptr); 2213 csa->ohds->ds_user_ptr = NULL; 2214 } 2215 2216 /* compute unique space */ 2217 while ((err = bplist_iterate(&csa->cds->ds_deadlist, 2218 &itor, &bp)) == 0) { 2219 if (bp.blk_birth > csa->cds->ds_prev->ds_phys->ds_prev_snap_txg) 2220 unique += bp_get_dasize(dp->dp_spa, &bp); 2221 } 2222 VERIFY(err == ENOENT); 2223 2224 /* reset origin's unique bytes */ 2225 csa->cds->ds_prev->ds_phys->ds_unique_bytes = unique; 2226 2227 /* swap blkptrs */ 2228 { 2229 blkptr_t tmp; 2230 tmp = csa->ohds->ds_phys->ds_bp; 2231 csa->ohds->ds_phys->ds_bp = csa->cds->ds_phys->ds_bp; 2232 csa->cds->ds_phys->ds_bp = tmp; 2233 } 2234 2235 /* set dd_*_bytes */ 2236 { 2237 int64_t dused, dcomp, duncomp; 2238 uint64_t cdl_used, cdl_comp, cdl_uncomp; 2239 uint64_t odl_used, odl_comp, odl_uncomp; 2240 2241 VERIFY(0 == bplist_space(&csa->cds->ds_deadlist, &cdl_used, 2242 &cdl_comp, &cdl_uncomp)); 2243 VERIFY(0 == bplist_space(&csa->ohds->ds_deadlist, &odl_used, 2244 &odl_comp, &odl_uncomp)); 2245 dused = csa->cds->ds_phys->ds_used_bytes + cdl_used - 2246 (csa->ohds->ds_phys->ds_used_bytes + odl_used); 2247 dcomp = csa->cds->ds_phys->ds_compressed_bytes + cdl_comp - 2248 (csa->ohds->ds_phys->ds_compressed_bytes + odl_comp); 2249 duncomp = csa->cds->ds_phys->ds_uncompressed_bytes + 2250 cdl_uncomp - 2251 (csa->ohds->ds_phys->ds_uncompressed_bytes + odl_uncomp); 2252 2253 dsl_dir_diduse_space(csa->ohds->ds_dir, 2254 dused, dcomp, duncomp, tx); 2255 dsl_dir_diduse_space(csa->cds->ds_dir, 2256 -dused, -dcomp, -duncomp, tx); 2257 } 2258 2259 #define SWITCH64(x, y) \ 2260 { \ 2261 uint64_t __tmp = (x); \ 2262 (x) = (y); \ 2263 (y) = __tmp; \ 2264 } 2265 2266 /* swap ds_*_bytes */ 2267 SWITCH64(csa->ohds->ds_phys->ds_used_bytes, 2268 csa->cds->ds_phys->ds_used_bytes); 2269 SWITCH64(csa->ohds->ds_phys->ds_compressed_bytes, 2270 csa->cds->ds_phys->ds_compressed_bytes); 2271 SWITCH64(csa->ohds->ds_phys->ds_uncompressed_bytes, 2272 csa->cds->ds_phys->ds_uncompressed_bytes); 2273 2274 /* swap deadlists */ 2275 bplist_close(&csa->cds->ds_deadlist); 2276 bplist_close(&csa->ohds->ds_deadlist); 2277 SWITCH64(csa->ohds->ds_phys->ds_deadlist_obj, 2278 csa->cds->ds_phys->ds_deadlist_obj); 2279 VERIFY(0 == bplist_open(&csa->cds->ds_deadlist, dp->dp_meta_objset, 2280 csa->cds->ds_phys->ds_deadlist_obj)); 2281 VERIFY(0 == bplist_open(&csa->ohds->ds_deadlist, dp->dp_meta_objset, 2282 csa->ohds->ds_phys->ds_deadlist_obj)); 2283 } 2284 2285 /* 2286 * Swap the clone "cosname" with its origin head file system. 2287 */ 2288 int 2289 dsl_dataset_clone_swap(dsl_dataset_t *clone, dsl_dataset_t *origin_head, 2290 boolean_t force) 2291 { 2292 struct cloneswaparg csa; 2293 2294 ASSERT(clone->ds_open_refcount == DS_REF_MAX); 2295 ASSERT(origin_head->ds_open_refcount == DS_REF_MAX); 2296 2297 csa.cds = clone; 2298 csa.ohds = origin_head; 2299 csa.force = force; 2300 return (dsl_sync_task_do(clone->ds_dir->dd_pool, 2301 dsl_dataset_clone_swap_check, 2302 dsl_dataset_clone_swap_sync, &csa, NULL, 9)); 2303 } 2304 2305 /* 2306 * Given a pool name and a dataset object number in that pool, 2307 * return the name of that dataset. 2308 */ 2309 int 2310 dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf) 2311 { 2312 spa_t *spa; 2313 dsl_pool_t *dp; 2314 dsl_dataset_t *ds = NULL; 2315 int error; 2316 2317 if ((error = spa_open(pname, &spa, FTAG)) != 0) 2318 return (error); 2319 dp = spa_get_dsl(spa); 2320 rw_enter(&dp->dp_config_rwlock, RW_READER); 2321 if ((error = dsl_dataset_open_obj(dp, obj, 2322 NULL, DS_MODE_NONE, FTAG, &ds)) != 0) { 2323 rw_exit(&dp->dp_config_rwlock); 2324 spa_close(spa, FTAG); 2325 return (error); 2326 } 2327 dsl_dataset_name(ds, buf); 2328 dsl_dataset_close(ds, DS_MODE_NONE, FTAG); 2329 rw_exit(&dp->dp_config_rwlock); 2330 spa_close(spa, FTAG); 2331 2332 return (0); 2333 } 2334