fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Common Development and Distribution License (the "License").
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
5afc78aa05e746cd98000659cff9f89d9995b3feChris Kirby * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
40510e8eba18690b9a9843b26393725eeb0f1dacJosef 'Jeff' Sipek * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * Copyright (c) 2014, Joyent, Inc. All rights reserved.
03d1795fa6f720eafbee821ad37f4343c391cfe4Alexander Stetsenko * Copyright (c) 2014 RackTop Systems.
bc9014e6a81272073b9854d9f65dd59e18d18c35Justin Gibbs * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
c3d26abc9ee97b4f60233556aadeb57e0bd30bb9Matthew Ahrens * Copyright (c) 2014 Integros [integros.com]
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved.
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens * The SPA supports block sizes up to 16MB. However, very large blocks
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens * can have an impact on i/o latency (e.g. tying up a spinning disk for
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens * ~300ms), and also potentially on the memory allocator. Therefore,
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens * we do not allow the recordsize to be set larger than zfs_max_recordsize
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens * (default 1MB). Larger blocks can be created by changing this tunable,
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens * and pools with larger blocks can always be imported and used, regardless
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens * of this setting.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbsextern inline dsl_dataset_phys_t *dsl_dataset_phys(dsl_dataset_t *ds);
a9799022bd90b13722204e80112efaa5bf573099ck * Figure out how much of this delta should be propogated to the dsl_dir
a9799022bd90b13722204e80112efaa5bf573099ck * layer. If there's a refreservation, that space has already been
a9799022bd90b13722204e80112efaa5bf573099ck * partially accounted for in our ancestors.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs old_bytes = MAX(ds_phys->ds_unique_bytes, ds->ds_reserved);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs new_bytes = MAX(ds_phys->ds_unique_bytes + delta, ds->ds_reserved);
a9799022bd90b13722204e80112efaa5bf573099ck ASSERT3U(ABS((int64_t)(new_bytes - old_bytes)), <=, ABS(delta));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickdsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick int used = bp_get_dsize_sync(tx->tx_pool->dp_spa, bp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* It could have been compressed away to nothing */
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon ASSERT3U(bp->blk_birth, >, dsl_dataset_phys(ds)->ds_prev_snap_txg);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_referenced_bytes += used;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_compressed_bytes += compressed;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_uncompressed_bytes += uncompressed;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_unique_bytes += used;
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens if (BP_GET_LSIZE(bp) > SPA_OLD_MAXBLOCKSIZE) {
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens ds->ds_feature_activation_needed[SPA_FEATURE_LARGE_BLOCKS] =
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens spa_feature_t f = zio_checksum_to_feature(BP_GET_CHECKSUM(bp));
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens ds->ds_feature_activation_needed[f] = B_TRUE;
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD, delta,
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens dsl_dir_transfer_space(ds->ds_dir, used - delta,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickdsl_dataset_block_kill(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx,
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman int used = bp_get_dsize_sync(tx->tx_pool->dp_spa, bp);
cdb0ab79ea1af7b8fc339a04d4bf7426dc77ec4emaybee return (0);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (bp->blk_birth > dsl_dataset_phys(ds)->ds_prev_snap_txg) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT(dsl_dataset_phys(ds)->ds_unique_bytes >= used ||
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_unique_bytes -= used;
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens dsl_dir_transfer_space(ds->ds_dir, -used - delta,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * We are here as part of zio's write done callback,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * which means we're a zio interrupt thread. We can't
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens * call dsl_deadlist_insert() now because it may block
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * waiting for I/O. Instead, put bp on the deferred
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * queue and let dsl_pool_sync() finish the job.
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens dsl_deadlist_insert(&ds->ds_deadlist, bp, tx);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT(dsl_dataset_phys(ds->ds_prev)->ds_num_children > 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* if (bp->blk_birth > prev prev snap txg) prev unique += bs */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj ==
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds->ds_prev)->ds_prev_snap_txg) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds->ds_prev)->ds_unique_bytes += used;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(dsl_dataset_phys(ds)->ds_referenced_bytes, >=, used);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_referenced_bytes -= used;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(dsl_dataset_phys(ds)->ds_compressed_bytes, >=, compressed);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_compressed_bytes -= compressed;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(dsl_dataset_phys(ds)->ds_uncompressed_bytes, >=, uncompressed);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_uncompressed_bytes -= uncompressed;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The snapshot creation could fail, but that would cause an
fa9e4066f08beec538e775443c5be79dd423fcabahrens * incorrect FALSE return, which would only result in an
fa9e4066f08beec538e775443c5be79dd423fcabahrens * overestimation of the amount of space that an operation would
fa9e4066f08beec538e775443c5be79dd423fcabahrens * consume, which is OK.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * There's also a small window where we could miss a pending
fa9e4066f08beec538e775443c5be79dd423fcabahrens * snapshot, because we could set the sync task in the quiescing
fa9e4066f08beec538e775443c5be79dd423fcabahrens * phase. So this should only be used as a guess.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs return (MAX(dsl_dataset_phys(ds)->ds_prev_snap_txg, trysnap));
c7cd242109c82107ec2e50013369e92be9d77702George Wilsondsl_dataset_block_freeable(dsl_dataset_t *ds, const blkptr_t *bp,
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman if (blk_birth <= dsl_dataset_prev_snap_txg(ds) ||
40510e8eba18690b9a9843b26393725eeb0f1dacJosef 'Jeff' Sipek * We have to release the fsid syncronously or we risk that a subsequent
40510e8eba18690b9a9843b26393725eeb0f1dacJosef 'Jeff' Sipek * mount of the same dataset will fail to unique_insert the fsid. This
40510e8eba18690b9a9843b26393725eeb0f1dacJosef 'Jeff' Sipek * failure would manifest itself as the fsid of this dataset changing
40510e8eba18690b9a9843b26393725eeb0f1dacJosef 'Jeff' Sipek * between mounts which makes NFS clients quite unhappy.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_next_snap_obj == 0)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs err = dmu_bonus_hold(mos, dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj,
e7437265dc2a4920c197ed4337665539d358b22cahrens headphys->ds_snapnames_zapobj, ds->ds_object, 0, ds->ds_snapname);
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybeedsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name, uint64_t *value)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs uint64_t snapobj = dsl_dataset_phys(ds)->ds_snapnames_zapobj;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinekdsl_dataset_snap_remove(dsl_dataset_t *ds, const char *name, dmu_tx_t *tx,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs uint64_t snapobj = dsl_dataset_phys(ds)->ds_snapnames_zapobj;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
e57a022b8f718889ffa92adbde47a8f08abcdb25Justin T. Gibbsdsl_dataset_try_add_ref(dsl_pool_t *dp, dsl_dataset_t *ds, void *tag)
9d47dec0481d8cd53b2c1053c96bfa3f78357d6aJustin T. Gibbs if (dbuf != NULL && dmu_buf_try_add_ref(dbuf, dp->dp_meta_objset,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
a7f53a5629374ca27c5696ace9a1946c2ca050f4Chris Kirby /* Make sure dsobj has the correct object type. */
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrens if (doi.doi_bonus_type != DMU_OT_DSL_DATASET) {
bc9014e6a81272073b9854d9f65dd59e18d18c35Justin Gibbs ds->ds_is_snapshot = dsl_dataset_phys(ds)->ds_num_children != 0;
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens mutex_init(&ds->ds_opening_lock, NULL, MUTEX_DEFAULT, NULL);
4e3c9f4489a18514e5e8caeb91d4e6db07c98415Bill Pijewski mutex_init(&ds->ds_sendstream_lock, NULL, MUTEX_DEFAULT, NULL);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs mos, dsl_dataset_phys(ds)->ds_deadlist_obj);
4e3c9f4489a18514e5e8caeb91d4e6db07c98415Bill Pijewski list_create(&ds->ds_sendstreams, sizeof (dmu_sendarg_t),
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs list_create(&ds->ds_prop_cbs, sizeof (dsl_prop_cb_record_t),
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens dsl_dataset_phys(ds)->ds_dir_obj, NULL, ds, &ds->ds_dir);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_userrefs_obj != 0) {
cb625fb575ce78c4928c387e0d3bff0c5be9dc07ck if (err == 0) {
40510e8eba18690b9a9843b26393725eeb0f1dacJosef 'Jeff' Sipek dmu_buf_init_user(&ds->ds_dbu, dsl_dataset_evict_sync,
bc9014e6a81272073b9854d9f65dd59e18d18c35Justin Gibbs winner = dmu_buf_set_user_ie(dbuf, &ds->ds_dbu);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs unique_insert(dsl_dataset_phys(ds)->ds_fsid_guid);
40510e8eba18690b9a9843b26393725eeb0f1dacJosef 'Jeff' Sipek "%llx to %llx for pool %s dataset id %llu",
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3P(dsl_dataset_phys(ds), ==, dbuf->db_data);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT(dsl_dataset_phys(ds)->ds_prev_snap_obj != 0 ||
84db2a68825c1a672f664432101f6f0b443679e3ahrens dp->dp_origin_snap == NULL || ds == dp->dp_origin_snap);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_hold(dsl_pool_t *dp, const char *name,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens err = dsl_dir_hold(dp, name, FTAG, &dd, &snapname);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs obj = dsl_dir_phys(dd)->dd_head_dataset_obj;
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagnelie err = dsl_dataset_hold_obj(dp, obj, tag, &ds);
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee /* we may be looking for a snapshot */
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagnelie err = dsl_dataset_snap_lookup(ds, snapname, &obj);
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagnelie err = dsl_dataset_hold_obj(dp, obj, tag, &snap_ds);
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagnelie (void) strlcpy(snap_ds->ds_snapname, snapname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_own_obj(dsl_pool_t *dp, uint64_t dsobj,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens int err = dsl_dataset_hold_obj(dp, dsobj, tag, dsp);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_own(dsl_pool_t *dp, const char *name,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens int err = dsl_dataset_hold(dp, name, tag, dsp);
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee return (0);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * See the comment above dsl_pool_hold() for details. In summary, a long
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * hold is used to prevent destruction of a dataset while the pool hold
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * is dropped, allowing other concurrent operations (e.g. spa_sync()).
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * The dataset and pool must be held when this function is called. After it
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * is called, the pool hold may be released while the dataset is still held
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * and accessed.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_long_hold(dsl_dataset_t *ds, void *tag)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_long_rele(dsl_dataset_t *ds, void *tag)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) refcount_remove(&ds->ds_longholds, tag);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens/* Return B_TRUE if there are any long holds on this dataset. */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens return (!refcount_is_zero(&ds->ds_longholds));
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens VERIFY3U(strlcat(name, "@", ZFS_MAX_DATASET_NAME_LEN),
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee * We use a "recursive" mutex so that we
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee * can call dprintf_ds() with ds_lock held.
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens int len = dsl_dir_namelen(ds->ds_dir) + 1 + strlen(ds->ds_snapname);
503ad85c168c7992ccc310af845a581cff3c72b5Matthew Ahrensdsl_dataset_disown(dsl_dataset_t *ds, void *tag)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_tryown(dsl_dataset_t *ds, void *tag)
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (ds->ds_owner == NULL && !DS_IS_INCONSISTENT(ds)) {
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrensdsl_dataset_activate_feature(uint64_t dsobj, spa_feature_t f, dmu_tx_t *tx)
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens objset_t *mos = dmu_tx_pool(tx)->dp_meta_objset;
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens VERIFY(spa_feature_table[f].fi_flags & ZFEATURE_FLAG_PER_DATASET);
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens dmu_object_zapify(mos, dsobj, DMU_OT_DSL_DATASET, tx);
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens VERIFY0(zap_add(mos, dsobj, spa_feature_table[f].fi_guid,
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrensdsl_dataset_deactivate_feature(uint64_t dsobj, spa_feature_t f, dmu_tx_t *tx)
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens objset_t *mos = dmu_tx_pool(tx)->dp_meta_objset;
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens VERIFY(spa_feature_table[f].fi_flags & ZFEATURE_FLAG_PER_DATASET);
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens VERIFY0(zap_remove(mos, dsobj, spa_feature_table[f].fi_guid, tx));
088f389458728c464569a5506b58070254fa4f7dahrensdsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
3cb34c601f3ef3016f638574f5982e80c3735c71ahrens ASSERT(origin == NULL || origin->ds_dir->dd_pool == dp);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT(origin == NULL || dsl_dataset_phys(origin)->ds_num_children > 0);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT(dsl_dir_phys(dd)->dd_head_dataset_obj == 0);
1649cd4b1641110b549d9f70a902cafc2007bd77tabriz DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dmu_bonus_hold(mos, dsobj, FTAG, &dbuf));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid,
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh zap_create_norm(mos, U8_TEXTPREP_TOUPPER, DMU_OT_DSL_DS_SNAP_MAP,
088f389458728c464569a5506b58070254fa4f7dahrens dsphys->ds_creation_txg = tx->tx_txg == TXG_INITIAL ? 1 : tx->tx_txg;
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens dsphys->ds_deadlist_obj = dsl_deadlist_alloc(mos, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_t *ohds; /* head of the origin snapshot */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin)->ds_referenced_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin)->ds_compressed_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin)->ds_uncompressed_bytes;
c166b69d29138aed7a415fe7cef698e54c6ae945Paul Dagnelie rrw_enter(&origin->ds_bp_rwlock, RW_READER, FTAG);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsphys->ds_bp = dsl_dataset_phys(origin)->ds_bp;
42fcb65ea4f2c6f8cc5a3c6142a486cb49871fd2Matthew Ahrens * Inherit flags that describe the dataset's contents
42fcb65ea4f2c6f8cc5a3c6142a486cb49871fd2Matthew Ahrens * (INCONSISTENT) or properties (Case Insensitive).
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsphys->ds_flags |= dsl_dataset_phys(origin)->ds_flags &
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin)->ds_num_children++;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(origin->ds_dir)->dd_head_dataset_obj,
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens dsphys->ds_deadlist_obj = dsl_deadlist_clone(&ohds->ds_deadlist,
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens dsphys->ds_prev_snap_txg, dsphys->ds_prev_snap_obj, tx);
088f389458728c464569a5506b58070254fa4f7dahrens if (spa_version(dp->dp_spa) >= SPA_VERSION_NEXT_CLONES) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(origin)->ds_next_clones_obj == 0) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin)->ds_next_clones_obj =
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin)->ds_next_clones_obj,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(dd)->dd_origin_obj = origin->ds_object;
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dir_phys(origin->ds_dir)->dd_clones == 0) {
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens dmu_buf_will_dirty(origin->ds_dir->dd_dbuf, tx);
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(dd)->dd_head_dataset_obj = dsobj;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_zero_zil(dsl_dataset_t *ds, dmu_tx_t *tx)
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon if (bcmp(&os->os_zil_header, &zero_zil, sizeof (zero_zil)) != 0) {
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon bzero(&os->os_zil_header, sizeof (os->os_zil_header));
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon /* dsl_dataset_sync_done will drop this reference. */
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timhdsl_dataset_create_sync(dsl_dir_t *pdd, const char *lastname,
ab04eb8ef60d9dc9614d6cccffc474f24ca1d162timh dsl_dataset_t *origin, uint64_t flags, cred_t *cr, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dir_hold_obj(dp, ddobj, lastname, FTAG, &dd));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsobj = dsl_dataset_create_sync_dd(dd, origin,
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * Since we're creating a new node we know it's a leaf, so we can
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * initialize the counts if the limit feature is active.
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek if (spa_feature_is_active(dp->dp_spa, SPA_FEATURE_FS_SS_LIMIT)) {
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek VERIFY0(zap_add(os, dd->dd_object, DD_FIELD_FILESYSTEM_COUNT,
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek VERIFY0(zap_add(os, dd->dd_object, DD_FIELD_SNAPSHOT_COUNT,
feaa74e41c407fe56e66a47e097c2842d4f65b9fMark Maybee * If we are creating a clone, make sure we zero out any stale
feaa74e41c407fe56e66a47e097c2842d4f65b9fMark Maybee * data from the origin snapshots zil header.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (origin != NULL && !(flags & DS_CREATE_FLAG_NODIRTY)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * The unique space in the head dataset can be calculated by subtracting
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * the space used in the most recent snapshot, that is still being used
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * in this file system, from the space currently in use. To figure out
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * the space in the most recent snapshot still in use, we need to take
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * the total space used in the snapshot and subtract out the space that
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * has been freed up since the snapshot was taken.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_recalc_head_uniq(dsl_dataset_t *ds)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs mrs_used = dsl_dataset_phys(ds->ds_prev)->ds_referenced_bytes;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_deadlist_space(&ds->ds_deadlist, &dlused, &dlcomp, &dluncomp);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_referenced_bytes - (mrs_used - dlused);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (spa_version(ds->ds_dir->dd_pool->dp_spa) >=
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_flags |= DS_FLAG_UNIQUE_ACCURATE;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_remove_from_next_clones(dsl_dataset_t *ds, uint64_t obj,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT(dsl_dataset_phys(ds)->ds_num_children >= 2);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs err = zap_remove_int(mos, dsl_dataset_phys(ds)->ds_next_clones_obj,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * The err should not be ENOENT, but a bug in a previous version
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * of the code could cause upgrade_clones_cb() to not set
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * ds_next_snap_obj when it should, leading to a missing entry.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * If we knew that the pool was created after
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * SPA_VERSION_NEXT_CLONES, we could assert that it isn't
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * ENOENT. However, at least we can check that we don't have
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * too many entries in the next_clones_obj even after failing to
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * remove this one.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT0(zap_count(mos, dsl_dataset_phys(ds)->ds_next_clones_obj,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(count, <=, dsl_dataset_phys(ds)->ds_num_children - 2);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (ds == NULL) /* this is the meta-objset */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_next_snap_obj != 0)
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon /* Must not dirty a dataset in the same txg where it got snapshotted. */
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon ASSERT3U(tx->tx_txg, >, dsl_dataset_phys(ds)->ds_prev_snap_txg);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (txg_list_add(&dp->dp_dirty_datasets, ds, tx->tx_txg)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* up the hold count until we can be written out */
2e2c135528b3edfe9aaf67d1f004dc0202fa1a54Matthew Ahrens for (int t = 0; t < TXG_SIZE; t++) {
2e2c135528b3edfe9aaf67d1f004dc0202fa1a54Matthew Ahrens if (txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_snapshot_reserve_space(dsl_dataset_t *ds, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * If there's an fs-only reservation, any blocks that might become
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * owned by the snapshot dataset must be accommodated by space
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * outside of the reservation.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ASSERT(ds->ds_reserved == 0 || DS_UNIQUE_IS_ACCURATE(ds));
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs asize = MIN(dsl_dataset_phys(ds)->ds_unique_bytes, ds->ds_reserved);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (asize > dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE))
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Propagate any reserved space for this snapshot to other
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * snapshot checks in this sync group.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_willuse_space(ds->ds_dir, asize, tx);
e19302335c33c8c6e0b0b5e426fc1f6352c84b5dbonwick return (0);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname,
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek dmu_tx_t *tx, boolean_t recv, uint64_t cnt, cred_t *cr)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * We don't allow multiple snapshots of the same txg. If there
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * is already one, try again.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_prev_snap_txg >= tx->tx_txg)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Check for conflicting snapshot name.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_snap_lookup(ds, snapname, &value);
ca48f36f20f6098ceb19d5b084b6b3d4b8eca9faKeith M Wesolowski * We don't allow taking snapshots of inconsistent datasets, such as
ca48f36f20f6098ceb19d5b084b6b3d4b8eca9faKeith M Wesolowski * those into which we are currently receiving. However, if we are
ca48f36f20f6098ceb19d5b084b6b3d4b8eca9faKeith M Wesolowski * creating this snapshot as part of a receive, this check will be
ca48f36f20f6098ceb19d5b084b6b3d4b8eca9faKeith M Wesolowski * executed atomically with respect to the completion of the receive
ca48f36f20f6098ceb19d5b084b6b3d4b8eca9faKeith M Wesolowski * itself but prior to the clearing of DS_FLAG_INCONSISTENT; in this
ca48f36f20f6098ceb19d5b084b6b3d4b8eca9faKeith M Wesolowski * case we ignore this, knowing it will be fixed up for us shortly in
ca48f36f20f6098ceb19d5b084b6b3d4b8eca9faKeith M Wesolowski * dmu_recv_end_sync().
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * Skip the check for temporary snapshots or if we have already checked
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * the counts in dsl_dataset_snapshot_check. This means we really only
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * check the count here when we're receiving a stream.
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek error = dsl_fs_ss_limit_check(ds->ds_dir, cnt,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_snapshot_reserve_space(ds, tx);
1d452cf5123cb6ac0a013a4dbd4dcceeb0da314dahrens return (0);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_snapshot_check(void *arg, dmu_tx_t *tx)
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * Pre-compute how many total new snapshots will be created for each
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * level in the tree and below. This is needed for validating the
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * snapshot limit when either taking a recursive snapshot or when
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * taking multiple snapshots.
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * The problem is that the counts are not actually adjusted when
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * we are checking, only when we finally sync. For a single snapshot,
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * this is easy, the count will increase by 1 at each node up the tree,
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * but its more complicated for the recursive/multiple snapshot case.
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * The dsl_fs_ss_limit_check function does recursively check the count
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * at each level up the tree but since it is validating each snapshot
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * independently we need to be sure that we are validating the complete
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * count for the entire set of snapshots. We do this by rolling up the
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * counts for each component of the name into an nvlist and then
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * checking each of those cases with the aggregated count.
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * This approach properly handles not only the recursive snapshot
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * case (where we get all of those on the ddsa_snaps list) but also
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * the sibling case (e.g. snapshot a/b and a/c so that we will also
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * validate the limit on 'a' using a count of 2).
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * We validate the snapshot names in the third loop and only report
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek * name errors once.
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek /* Rollup aggregated counts into the cnt_track list */
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek for (pair = nvlist_next_nvpair(ddsa->ddsa_snaps, NULL);
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek pair = nvlist_next_nvpair(ddsa->ddsa_snaps, pair)) {
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek (void) strlcpy(nm, nvpair_name(pair), sizeof (nm));
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek /* update existing entry */
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek /* add to list */
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek /* Check aggregated counts at each level */
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek for (pair = nvlist_next_nvpair(cnt_track, NULL);
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek pair != NULL; pair = nvlist_next_nvpair(cnt_track, pair)) {
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek error = dsl_dataset_hold(dp, name, FTAG, &ds);
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek error = dsl_fs_ss_limit_check(ds->ds_dir, cnt,
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek /* only report one error for this check */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens for (pair = nvlist_next_nvpair(ddsa->ddsa_snaps, NULL);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens pair != NULL; pair = nvlist_next_nvpair(ddsa->ddsa_snaps, pair)) {
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens if (strlen(name) >= ZFS_MAX_DATASET_NAME_LEN)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) strlcpy(dsname, name, atp - name + 1);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_hold(dp, dsname, FTAG, &ds);
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek /* passing 0/NULL skips dsl_fs_ss_limit_check */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * If we are on an old pool, the zil must not be active, in which
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * case it will be zeroed. Usually zil_suspend() accomplishes this.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ASSERT(spa_version(dmu_tx_pool(tx)->dp_spa) >= SPA_VERSION_FAST_SNAP ||
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens sizeof (zero_zil)) == 0);
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon /* Should not snapshot a dirty dataset. */
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon ASSERT(!txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets,
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek dsl_fs_ss_count_adjust(ds->ds_dir, 1, DD_FIELD_SNAPSHOT_COUNT, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * The origin's ds_creation_txg has to be < TXG_INITIAL
1649cd4b1641110b549d9f70a902cafc2007bd77tabriz DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dmu_bonus_hold(mos, dsobj, FTAG, &dbuf));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsphys->ds_prev_snap_obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsphys->ds_prev_snap_txg = dsl_dataset_phys(ds)->ds_prev_snap_txg;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsphys->ds_deadlist_obj = dsl_dataset_phys(ds)->ds_deadlist_obj;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsphys->ds_referenced_bytes = dsl_dataset_phys(ds)->ds_referenced_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsphys->ds_compressed_bytes = dsl_dataset_phys(ds)->ds_compressed_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_uncompressed_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsphys->ds_flags = dsl_dataset_phys(ds)->ds_flags;
c166b69d29138aed7a415fe7cef698e54c6ae945Paul Dagnelie rrw_enter(&ds->ds_bp_rwlock, RW_READER, FTAG);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsphys->ds_bp = dsl_dataset_phys(ds)->ds_bp;
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_prev_snap_obj != 0);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds->ds_prev)->ds_next_clones_obj;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT(dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj ==
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds->ds_prev)->ds_num_children > 1);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj ==
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(dsl_dataset_phys(ds)->ds_prev_snap_txg, ==,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds->ds_prev)->ds_creation_txg);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj = dsobj;
088f389458728c464569a5506b58070254fa4f7dahrens } else if (next_clones_obj != 0) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_remove_from_next_clones(ds->ds_prev,
a9799022bd90b13722204e80112efaa5bf573099ck * If we have a reference-reservation on this dataset, we will
a9799022bd90b13722204e80112efaa5bf573099ck * need to increase the amount of refreservation being charged
a9799022bd90b13722204e80112efaa5bf573099ck * since our unique space is going to zero.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs delta = MIN(dsl_dataset_phys(ds)->ds_unique_bytes,
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_deadlist_clone(&ds->ds_deadlist, UINT64_MAX,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_prev_snap_obj, tx);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_prev_snap_txg, tx);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(dsl_dataset_phys(ds)->ds_prev_snap_txg, <, tx->tx_txg);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_prev_snap_obj = dsobj;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_prev_snap_txg = crtxg;
a9799022bd90b13722204e80112efaa5bf573099ck if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_flags |= DS_FLAG_UNIQUE_ACCURATE;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs VERIFY0(zap_add(mos, dsl_dataset_phys(ds)->ds_snapnames_zapobj,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_prev_snap_obj, ds, &ds->ds_prev));
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, "");
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens for (pair = nvlist_next_nvpair(ddsa->ddsa_snaps, NULL);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens pair != NULL; pair = nvlist_next_nvpair(ddsa->ddsa_snaps, pair)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) strlcpy(dsname, name, atp - name + 1);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold(dp, dsname, FTAG, &ds));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_snapshot_sync_impl(ds, atp + 1, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * The snapshots must all be in the same pool.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * All-or-nothing: if there are any failures, nothing will be modified.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) strlcpy(fsname, snapname, atp - snapname + 1);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_sync_task(firstname, dsl_dataset_snapshot_check,
7d46dc6ca63a6f3f0d51aa655bfcf10cf2405a9eMatthew Ahrens fnvlist_num_pairs(snaps) * 3, ZFS_SPACE_CHECK_NORMAL);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens for (pair = nvlist_next_nvpair(suspended, NULL); pair != NULL;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens pair = nvlist_next_nvpair(suspended, pair)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_snapshot_tmp_check(void *arg, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_hold(dp, ddsta->ddsta_fsname, FTAG, &ds);
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek /* NULL cred means no limit check for tmp snapshot */
ca48f36f20f6098ceb19d5b084b6b3d4b8eca9faKeith M Wesolowski error = dsl_dataset_snapshot_check_impl(ds, ddsta->ddsta_snapname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (spa_version(dp->dp_spa) < SPA_VERSION_USERREFS) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_user_hold_check_one(NULL, ddsta->ddsta_htag,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_snapshot_tmp_sync(void *arg, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold(dp, ddsta->ddsta_fsname, FTAG, &ds));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_snapshot_sync_impl(ds, ddsta->ddsta_snapname, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_user_hold_sync_one(ds->ds_prev, ddsta->ddsta_htag,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ddsta->ddsta_cleanup_minor, gethrestime_sec(), tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_destroy_snapshot_sync_impl(ds->ds_prev, B_TRUE, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_snapshot_tmp(const char *fsname, const char *snapname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_sync_task(fsname, dsl_dataset_snapshot_tmp_check,
7d46dc6ca63a6f3f0d51aa655bfcf10cf2405a9eMatthew Ahrens dsl_dataset_snapshot_tmp_sync, &ddsta, 3, ZFS_SPACE_CHECK_RESERVED);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT(dsl_dataset_phys(ds)->ds_next_snap_obj == 0);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * in case we had to change ds_fsid_guid when we opened it,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * sync it out now.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_fsid_guid = ds->ds_fsid_guid;
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (ds->ds_resume_bytes[tx->tx_txg & TXG_MASK] != 0) {
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens VERIFY0(zap_update(tx->tx_pool->dp_meta_objset,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens &ds->ds_resume_object[tx->tx_txg & TXG_MASK], tx));
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens VERIFY0(zap_update(tx->tx_pool->dp_meta_objset,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens &ds->ds_resume_offset[tx->tx_txg & TXG_MASK], tx));
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens VERIFY0(zap_update(tx->tx_pool->dp_meta_objset,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens &ds->ds_resume_bytes[tx->tx_txg & TXG_MASK], tx));
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens ds->ds_resume_object[tx->tx_txg & TXG_MASK] = 0;
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens ds->ds_resume_offset[tx->tx_txg & TXG_MASK] = 0;
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens ds->ds_resume_bytes[tx->tx_txg & TXG_MASK] = 0;
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens dsl_dataset_activate_feature(ds->ds_object, f, tx);
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapondeadlist_enqueue_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapondsl_dataset_sync_done(dsl_dataset_t *ds, dmu_tx_t *tx)
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon ASSERT(!dmu_objset_is_dirty(os, dmu_tx_get_txg(tx)));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensget_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * There may be missing entries in ds_next_clones_obj
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * due to a bug in a previous version of the code.
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * Only trust it if it has the right number of entries.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_next_clones_obj != 0) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs VERIFY0(zap_count(mos, dsl_dataset_phys(ds)->ds_next_clones_obj,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (count != dsl_dataset_phys(ds)->ds_num_children - 1)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fnvlist_add_nvlist(propval, ZPROP_VALUE, val);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fnvlist_add_nvlist(nv, zfs_prop_to_name(ZFS_PROP_CLONES), propval);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrensget_receive_resume_stats(dsl_dataset_t *ds, nvlist_t *nv)
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (dsl_dataset_has_resume_receive_state(ds)) {
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (zap_lookup(dp->dp_meta_objset, ds->ds_object,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens DS_FIELD_RESUME_FROMGUID, sizeof (val), 1, &val) == 0) {
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens fnvlist_add_uint64(token_nv, "fromguid", val);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (zap_lookup(dp->dp_meta_objset, ds->ds_object,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens DS_FIELD_RESUME_OBJECT, sizeof (val), 1, &val) == 0) {
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (zap_lookup(dp->dp_meta_objset, ds->ds_object,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens DS_FIELD_RESUME_OFFSET, sizeof (val), 1, &val) == 0) {
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (zap_lookup(dp->dp_meta_objset, ds->ds_object,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens DS_FIELD_RESUME_BYTES, sizeof (val), 1, &val) == 0) {
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (zap_lookup(dp->dp_meta_objset, ds->ds_object,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens DS_FIELD_RESUME_TOGUID, sizeof (val), 1, &val) == 0) {
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (zap_lookup(dp->dp_meta_objset, ds->ds_object,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens DS_FIELD_RESUME_TONAME, 1, sizeof (buf), buf) == 0) {
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel if (zap_contains(dp->dp_meta_objset, ds->ds_object,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (zap_contains(dp->dp_meta_objset, ds->ds_object,
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel if (zap_contains(dp->dp_meta_objset, ds->ds_object,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens packed = fnvlist_pack(token_nv, &packed_size);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens compressed = kmem_alloc(packed_size, KM_SLEEP);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens compressed_size = gzip_compress(packed, compressed,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens fletcher_4_native(compressed, compressed_size, NULL, &cksum);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens str = kmem_alloc(compressed_size * 2 + 1, KM_SLEEP);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens for (int i = 0; i < compressed_size; i++) {
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens (void) sprintf(str + i * 2, "%02x", compressed[i]);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens char *propval = kmem_asprintf("%u-%llx-%llx-%s",
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ratio = dsl_dataset_phys(ds)->ds_compressed_bytes == 0 ? 100 :
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs (dsl_dataset_phys(ds)->ds_uncompressed_bytes * 100 /
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
77372cb0f35e8d3615ca2e16044f033397e88e21Matthew Ahrens dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_LOGICALREFERENCED,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_uncompressed_bytes);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED,
b461c7460e5e77cf65f00151162e654220c6e2fbMatthew Ahrens if (ds->ds_prev != NULL && ds->ds_prev != dp->dp_origin_snap) {
b461c7460e5e77cf65f00151162e654220c6e2fbMatthew Ahrens dsl_prop_nvlist_add_string(nv, ZFS_PROP_PREV_SNAP, buf);
a9799022bd90b13722204e80112efaa5bf573099ck dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_AVAILABLE, avail);
a9799022bd90b13722204e80112efaa5bf573099ck dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFERENCED, refd);
1d7132005da8d75994a6ad204e6ec05ef5ffaa4bEric Schrock dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_UNIQUE,
1d7132005da8d75994a6ad204e6ec05ef5ffaa4bEric Schrock dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_OBJSETID,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USERREFS,
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_DEFER_DESTROY,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &prev);
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens err = dsl_dataset_space_written(prev, ds, &written,
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_WRITTEN,
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens * A failed "newfs" (e.g. full) resumable receive leaves
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens * the stats set on this dataset. Check here for the prop.
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens * A failed incremental resumable receive leaves the
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens * stats set on our child named "%recv". Check the child
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens * for the prop.
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens /* 6 extra bytes for /%recv */
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens if (strlcat(recvname, "/", sizeof (recvname)) <
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens strlcat(recvname, recv_clone_name, sizeof (recvname)) <
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens dsl_dataset_hold(dp, recvname, FTAG, &recv_ds) == 0) {
a2eea2e101e6a163a537dcc6d4e3c4da2a0ea5b2ahrensdsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs stat->dds_creation_txg = dsl_dataset_phys(ds)->ds_creation_txg;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_flags & DS_FLAG_INCONSISTENT;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs stat->dds_guid = dsl_dataset_phys(ds)->ds_guid;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs *refdbytesp = dsl_dataset_phys(ds)->ds_referenced_bytes;
a2eea2e101e6a163a537dcc6d4e3c4da2a0ea5b2ahrens *availbytesp = dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (ds->ds_reserved > dsl_dataset_phys(ds)->ds_unique_bytes)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ds->ds_reserved - dsl_dataset_phys(ds)->ds_unique_bytes;
a9799022bd90b13722204e80112efaa5bf573099ck * Adjust available bytes according to refquota
c166b69d29138aed7a415fe7cef698e54c6ae945Paul Dagnelie rrw_enter(&ds->ds_bp_rwlock, RW_READER, FTAG);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs *usedobjsp = BP_GET_FILL(&dsl_dataset_phys(ds)->ds_bp);
34f2f8cf94052481c81be2e134b94a00b501bf21Matthew Ahrensdsl_dataset_modified_since_snap(dsl_dataset_t *ds, dsl_dataset_t *snap)
c166b69d29138aed7a415fe7cef698e54c6ae945Paul Dagnelie rrw_enter(&ds->ds_bp_rwlock, RW_READER, FTAG);
c166b69d29138aed7a415fe7cef698e54c6ae945Paul Dagnelie birth = dsl_dataset_get_blkptr(ds)->blk_birth;
c166b69d29138aed7a415fe7cef698e54c6ae945Paul Dagnelie if (birth > dsl_dataset_phys(snap)->ds_creation_txg) {
6e0cbcaa0c6f2bc34634a4cc17b099f9ecef03d1Matthew Ahrens * It may be that only the ZIL differs, because it was
6e0cbcaa0c6f2bc34634a4cc17b099f9ecef03d1Matthew Ahrens * reset in the head. Don't count that as being
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrenstypedef struct dsl_dataset_rename_snapshot_arg {
1d452cf5123cb6ac0a013a4dbd4dcceeb0da314dahrens/* ARGSUSED */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_rename_snapshot_check_impl(dsl_pool_t *dp,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_snap_lookup(hds, ddrsa->ddrsa_oldsnapname, &val);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* ignore nonexistent snapshots */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* new name should not exist */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_snap_lookup(hds, ddrsa->ddrsa_newsnapname, &val);
cdf5b4ca0fa5ca7622b06bcb271be9e8a8245fecmmusante /* dataset name + 1 for the "@" + the new snapshot name must fit */
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens strlen(ddrsa->ddrsa_newsnapname) >= ZFS_MAX_DATASET_NAME_LEN)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_rename_snapshot_check(void *arg, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_hold(dp, ddrsa->ddrsa_fsname, FTAG, &hds);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dmu_objset_find_dp(dp, hds->ds_dir->dd_object,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_rename_snapshot_check_impl, ddrsa,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_rename_snapshot_check_impl(dp, hds, ddrsa);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_rename_snapshot_sync_impl(dsl_pool_t *dp,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_snap_lookup(hds, ddrsa->ddrsa_oldsnapname, &val);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* ignore nonexistent snapshots */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold_obj(dp, val, FTAG, &ds));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* log before we change the name */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens spa_history_log_internal_ds(ds, "rename", tx,
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek VERIFY0(dsl_dataset_snap_remove(hds, ddrsa->ddrsa_oldsnapname, tx,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) strcpy(ds->ds_snapname, ddrsa->ddrsa_newsnapname);
cdf5b4ca0fa5ca7622b06bcb271be9e8a8245fecmmusante return (0);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_rename_snapshot_sync(void *arg, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold(dp, ddrsa->ddrsa_fsname, FTAG, &hds));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dmu_objset_find_dp(dp, hds->ds_dir->dd_object,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_rename_snapshot_sync_impl, ddrsa,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_rename_snapshot_sync_impl(dp, hds, ddrsa));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_rename_snapshot(const char *fsname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens const char *oldsnapname, const char *newsnapname, boolean_t recursive)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens return (dsl_sync_task(fsname, dsl_dataset_rename_snapshot_check,
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * If we're doing an ownership handoff, we need to make sure that there is
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * only one long hold on the dataset. We're not allowed to change anything here
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * so we don't permanently release the long hold or regular hold here. We want
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * to do this only when syncing to avoid the dataset unexpectedly going away
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * when we release the long hold.
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowskidsl_dataset_handoff_check(dsl_dataset_t *ds, void *owner, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski error = dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* must not be a snapshot */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* must have a most recent snapshot */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_prev_snap_txg < TXG_INITIAL) {
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon * No rollback to a snapshot created in the current txg, because
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon * the rollback may dirty the dataset and create blocks that are
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon * not reachable from the rootbp while having a birth txg that
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon * falls into the snapshot's range.
bfaed0b91e57062c38bc16b4f89db3c8f0052a9bAndriy Gapon dsl_dataset_phys(ds)->ds_prev_snap_txg >= tx->tx_txg) {
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens /* must not have any bookmarks after the most recent snapshot */
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens fnvlist_add_boolean(proprequest, zfs_prop_to_name(ZFS_PROP_CREATETXG));
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens error = dsl_get_bookmarks_impl(ds, proprequest, bookmarks);
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens for (nvpair_t *pair = nvlist_next_nvpair(bookmarks, NULL);
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens pair != NULL; pair = nvlist_next_nvpair(bookmarks, pair)) {
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens fnvlist_lookup_nvlist(fnvpair_value_nvlist(pair),
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens uint64_t createtxg = fnvlist_lookup_uint64(valuenv, "value");
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (createtxg > dsl_dataset_phys(ds)->ds_prev_snap_txg) {
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski error = dsl_dataset_handoff_check(ds, ddra->ddra_owner, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Check if the snap we are rolling back to uses more than
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * the refquota.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds->ds_prev)->ds_referenced_bytes > ds->ds_quota) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * When we do the clone swap, we will temporarily use more space
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * due to the refreservation (the head will no longer have any
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * unique space, so the entire amount of the refreservation will need
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * to be free). We will immediately destroy the clone, freeing
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * this space, but the freeing happens over many txg's.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens unused_refres_delta = (int64_t)MIN(ds->ds_reserved,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx)
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski VERIFY0(dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds));
a7027df17fad220a20367b9d1eb251bc6300d203Matthew Ahrens fnvlist_add_string(ddra->ddra_result, "target", namebuf);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens cloneobj = dsl_dataset_create_sync(ds->ds_dir, "%rollback",
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ds->ds_prev, DS_CREATE_FLAG_NODIRTY, kcred, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold_obj(dp, cloneobj, FTAG, &clone));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_clone_swap_sync_impl(clone, ds, tx);
a7027df17fad220a20367b9d1eb251bc6300d203Matthew Ahrens * Rolls back the given filesystem or volume to the most recent snapshot.
a7027df17fad220a20367b9d1eb251bc6300d203Matthew Ahrens * The name of the most recent snapshot will be returned under key "target"
a7027df17fad220a20367b9d1eb251bc6300d203Matthew Ahrens * in the result nvlist.
a7027df17fad220a20367b9d1eb251bc6300d203Matthew Ahrens * If owner != NULL:
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * - The existing dataset MUST be owned by the specified owner at entry
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * - Upon return, dataset will still be held by the same owner, whether we
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * succeed or not.
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * This mode is required any time the existing filesystem is mounted. See
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * notes above zfs_suspend_fs() for further details.
a7027df17fad220a20367b9d1eb251bc6300d203Matthew Ahrensdsl_dataset_rollback(const char *fsname, void *owner, nvlist_t *result)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens return (dsl_sync_task(fsname, dsl_dataset_rollback_check,
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens list_t shared_snaps, origin_snaps, clone_snaps;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_t *origin_origin; /* origin of the origin */
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens uint64_t used, comp, uncomp, unique, cloneusedsnap, originusedsnap;
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrensstatic int snaplist_space(list_t *l, uint64_t mintxg, uint64_t *spacep);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensstatic int promote_hold(dsl_dataset_promote_arg_t *ddpa, dsl_pool_t *dp,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensstatic void promote_rele(dsl_dataset_promote_arg_t *ddpa, void *tag);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_promote_check(void *arg, dmu_tx_t *tx)
cb5842f8b0caaad0ed53535bd77042e933fdbafeAndriy Gapon max_snap_len = MAXNAMELEN - strlen(ddpa->ddpa_clonename) - 1;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(hds)->ds_flags & DS_FLAG_NOPROMOTE) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Compute and check the amount of space to transfer. Since this is
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * so expensive, don't do the preliminary check.
3cb34c601f3ef3016f638574f5982e80c3735c71ahrens /* compute origin's new unique space */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(dsl_dataset_phys(snap->ds)->ds_prev_snap_obj, ==,
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens dsl_deadlist_space_range(&snap->ds->ds_deadlist,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin_ds)->ds_prev_snap_txg, UINT64_MAX,
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee * Walk the snapshots that we are moving
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * Compute space to transfer. Consider the incremental changes
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * to used by each snapshot:
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * (my used) = (prev's used) + (blocks born) - (blocks killed)
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * So each snapshot gave birth to:
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * (blocks born) = (my used) - (prev's used) + (blocks killed)
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee * So a sequence would look like:
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * (uN - u(N-1) + kN) + ... + (u1 - u0 + k1) + (u0 - 0 + k0)
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee * Which simplifies to:
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * uN + kN + kN-1 + ... + k1 + k0
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee * Note however, if we stop before we reach the ORIGIN we get:
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * uN + kN + kN-1 + ... + kM - uM-1
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ddpa->used = dsl_dataset_phys(origin_ds)->ds_referenced_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ddpa->comp = dsl_dataset_phys(origin_ds)->ds_compressed_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ddpa->uncomp = dsl_dataset_phys(origin_ds)->ds_uncompressed_bytes;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens for (snap = list_head(&ddpa->shared_snaps); snap;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens snap = list_next(&ddpa->shared_snaps, snap)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * If there are long holds, we won't be able to evict
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * the objset.
99653d4ee642c6528e88224f12409a5f23060994eschrock /* Check that the snapshot name does not conflict */
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee err = dsl_dataset_snap_lookup(hds, ds->ds_snapname, &val);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) strcpy(ddpa->err_ds, snap->ds->ds_snapname);
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee /* The very first snapshot does not have a deadlist */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_prev_snap_obj == 0)
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee * If we are a clone of a clone then we never reached ORIGIN,
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee * so we need to subtract out the clone origin's used space.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ddpa->origin_origin)->ds_referenced_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ddpa->origin_origin)->ds_compressed_bytes;
a2afb611b30628fb74ad9eade4ae465f9031e262Jerry Jelinek /* Check that there is enough space and limit headroom here */
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens err = dsl_dir_transfer_possible(origin_ds->ds_dir, hds->ds_dir,
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * Compute the amounts of space that will be used by snapshots
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * after the promotion (for both origin and clone). For each,
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * it is the amount of space that will be on all of their
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * deadlists (that was not born before their new origin).
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dir_phys(hds->ds_dir)->dd_flags & DD_FLAG_USED_BREAKDOWN) {
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * Note, typically this will not be a clone of a clone,
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * so dd_origin_txg will be < TXG_INITIAL, so
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens * these snaplist_space() -> dsl_deadlist_space_range()
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * calls will be fast because they do not have to
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * iterate over all bps.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens snap->ds->ds_dir->dd_origin_txg, &ddpa->cloneusedsnap);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dir_phys(origin_ds->ds_dir)->dd_flags &
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin_ds)->ds_creation_txg,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_promote_sync(void *arg, dmu_tx_t *tx)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT0(dsl_dataset_phys(hds)->ds_flags & DS_FLAG_NOPROMOTE);
3cb34c601f3ef3016f638574f5982e80c3735c71ahrens * We need to explicitly open odd, since origin_ds's dd will be
0b69c2f001a429251e2d38f25aca860396551214ahrens * changing.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dir_hold_obj(dp, origin_ds->ds_dir->dd_object,
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee /* change origin's next snap */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs oldnext_obj = dsl_dataset_phys(origin_ds)->ds_next_snap_obj;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(dsl_dataset_phys(snap->ds)->ds_prev_snap_obj, ==,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin_ds)->ds_next_snap_obj = snap->ds->ds_object;
088f389458728c464569a5506b58070254fa4f7dahrens /* change the origin's next clone */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(origin_ds)->ds_next_clones_obj) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dataset_remove_from_next_clones(origin_ds,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin_ds)->ds_next_clones_obj,
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee /* change origin */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(dsl_dir_phys(dd)->dd_origin_obj, ==, origin_ds->ds_object);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(dd)->dd_origin_obj = dsl_dir_phys(odd)->dd_origin_obj;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling dd->dd_origin_txg = origin_head->ds_dir->dd_origin_txg;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(odd)->dd_origin_obj = origin_ds->ds_object;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin_ds)->ds_creation_txg;
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens /* change dd_clone entries */
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(odd)->dd_clones, hds->ds_object, tx));
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(ddpa->origin_origin->ds_dir)->dd_clones,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(ddpa->origin_origin->ds_dir)->dd_clones,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs zap_create(dp->dp_meta_objset, DMU_OT_DSL_CLONES,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(dd)->dd_clones, origin_head->ds_object, tx));
99653d4ee642c6528e88224f12409a5f23060994eschrock /* move snapshots to this dir */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens for (snap = list_head(&ddpa->shared_snaps); snap;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens snap = list_next(&ddpa->shared_snaps, snap)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Property callbacks are registered to a particular
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * dsl_dir. Since ours is changing, evict the objset
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * so that they will be unregistered from the old dsl_dir.
99653d4ee642c6528e88224f12409a5f23060994eschrock /* move snap name entry */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(hds)->ds_snapnames_zapobj, ds->ds_snapname,
99653d4ee642c6528e88224f12409a5f23060994eschrock /* change containing dsl_dir */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(dsl_dataset_phys(ds)->ds_dir_obj, ==, odd->dd_object);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_dir_obj = dd->dd_object;
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens /* move any clone references */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_next_clones_obj &&
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens for (zap_cursor_init(&zc, dp->dp_meta_objset,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * We've already moved the
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * origin's reference.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Change space accounting.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * both be valid, or both be 0 (resulting in delta == 0). This
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * is true for each of {clone,origin} independently.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_SNAP];
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_diduse_space(dd, DD_USED_SNAP, delta, 0, 0, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ddpa->used - delta, ddpa->comp, ddpa->uncomp, tx);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(odd)->dd_used_breakdown[DD_USED_SNAP];
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_diduse_space(odd, DD_USED_SNAP, delta, 0, 0, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens -ddpa->used - delta, -ddpa->comp, -ddpa->uncomp, tx);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin_ds)->ds_unique_bytes = ddpa->unique;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* log history record */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens spa_history_log_internal_ds(hds, "promote", tx, "");
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Make a list of dsl_dataset_t's for the snapshots between first_obj
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * (exclusive) and last_obj (inclusive). The list will be in reverse
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * order (last_obj will be the list_head()). If first_obj == 0, do all
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * snapshots back to this dataset's origin.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens uint64_t first_obj, uint64_t last_obj, list_t *l, void *tag)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens err = dsl_dataset_hold_obj(dp, obj, tag, &ds);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs first_obj = dsl_dir_phys(ds->ds_dir)->dd_origin_obj;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
a9799022bd90b13722204e80112efaa5bf573099ck return (0);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrenssnaplist_space(list_t *l, uint64_t mintxg, uint64_t *spacep)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens for (snap = list_head(l); snap; snap = list_next(l, snap)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_deadlist_space_range(&snap->ds->ds_deadlist,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (l == NULL || !list_link_active(&l->list_head))
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrenspromote_hold(dsl_dataset_promote_arg_t *ddpa, dsl_pool_t *dp, void *tag)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_hold(dp, ddpa->ddpa_clonename, tag,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs error = snaplist_make(dp, 0, dsl_dir_phys(dd)->dd_origin_obj,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = snaplist_make(dp, 0, ddpa->ddpa_clone->ds_object,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ASSERT3U(snap->ds->ds_object, ==, dsl_dir_phys(dd)->dd_origin_obj);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs error = snaplist_make(dp, dsl_dir_phys(dd)->dd_origin_obj,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(snap->ds->ds_dir)->dd_head_dataset_obj,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dir_phys(snap->ds->ds_dir)->dd_origin_obj != 0) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(snap->ds->ds_dir)->dd_origin_obj,
a9799022bd90b13722204e80112efaa5bf573099ckstatic void
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrenspromote_rele(dsl_dataset_promote_arg_t *ddpa, void *tag)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Promote a clone.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * If it fails due to a conflicting snapshot name, "conflsnap" will be filled
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens * in with the name. (It must be at least ZFS_MAX_DATASET_NAME_LEN bytes long.)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_promote(const char *name, char *conflsnap)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * We will modify space proportional to the number of
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * snapshots. Compute numsnaps.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = zap_count(dmu_objset_pool(os)->dp_meta_objset,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(dmu_objset_ds(os))->ds_snapnames_zapobj,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens return (dsl_sync_task(name, dsl_dataset_promote_check,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski dsl_dataset_t *origin_head, boolean_t force, void *owner, dmu_tx_t *tx)
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * "slack" factor for received datasets with refquota set on them.
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * See the bottom of this function for details on its use.
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald uint64_t refquota_slack = DMU_MAX_ACCESS * spa_asize_inflation;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* they should both be heads */
34f2f8cf94052481c81be2e134b94a00b501bf21Matthew Ahrens /* if we are not forcing, the branch point should be just before them */
34f2f8cf94052481c81be2e134b94a00b501bf21Matthew Ahrens if (!force && clone->ds_prev != origin_head->ds_prev)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* clone should be the clone (unless they are unrelated) */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens clone->ds_prev != clone->ds_dir->dd_pool->dp_origin_snap &&
34f2f8cf94052481c81be2e134b94a00b501bf21Matthew Ahrens origin_head->ds_dir != clone->ds_prev->ds_dir)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* the clone should be a child of the origin */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (clone->ds_dir->dd_parent != origin_head->ds_dir)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* origin_head shouldn't be modified unless 'force' */
34f2f8cf94052481c81be2e134b94a00b501bf21Matthew Ahrens dsl_dataset_modified_since_snap(origin_head, origin_head->ds_prev))
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* origin_head should have no long holds (e.g. is not mounted) */
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski if (dsl_dataset_handoff_check(origin_head, owner, tx))
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* check amount of any unconsumed refreservation */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin_head)->ds_unique_bytes) -
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_space_available(origin_head->ds_dir, NULL, 0, TRUE))
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * The clone can't be too much over the head's refquota.
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * To ensure that the entire refquota can be used, we allow one
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * transaction to exceed the the refquota. Therefore, this check
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * needs to also allow for the space referenced to be more than the
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * refquota. The maximum amount of space that one transaction can use
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * on disk is DMU_MAX_ACCESS * spa_asize_inflation. Allowing this
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * overage ensures that we are able to receive a filesystem that
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * exceeds the refquota on the source system.
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * So that overage is the refquota_slack we use below.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(clone)->ds_referenced_bytes >
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * NOTE: On DEBUG kernels there could be a race between this and
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald * the check function if spa_asize_inflation is adjusted...
5f7a8e6d750cb070a3347f045201c6206caee6aaDan McDonald dsl_dataset_phys(clone)->ds_unique_bytes <= origin_head->ds_quota +
34f2f8cf94052481c81be2e134b94a00b501bf21Matthew Ahrens ASSERT3P(clone->ds_prev, ==, origin_head->ds_prev);
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens * Swap per-dataset feature flags.
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens boolean_t clone_inuse = clone->ds_feature_inuse[f];
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens boolean_t origin_head_inuse = origin_head->ds_feature_inuse[f];
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens dsl_dataset_deactivate_feature(clone->ds_object, f, tx);
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens dsl_dataset_deactivate_feature(origin_head->ds_object,
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens dsl_dataset_activate_feature(origin_head->ds_object,
ca0cc3918a1789fa839194af2a9245f801a06b1aMatthew Ahrens dsl_dataset_activate_feature(clone->ds_object, f, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dmu_buf_will_dirty(origin_head->ds_dbuf, tx);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin_head)->ds_unique_bytes) -
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Reset origin's unique bytes, if it exists.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_deadlist_space_range(&clone->ds_deadlist,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin)->ds_prev_snap_txg, UINT64_MAX,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs &dsl_dataset_phys(origin)->ds_unique_bytes, &comp, &uncomp);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* swap blkptrs */
c166b69d29138aed7a415fe7cef698e54c6ae945Paul Dagnelie rrw_enter(&clone->ds_bp_rwlock, RW_WRITER, FTAG);
c166b69d29138aed7a415fe7cef698e54c6ae945Paul Dagnelie rrw_enter(&origin_head->ds_bp_rwlock, RW_WRITER, FTAG);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* set dd_*_bytes */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_deadlist_space(&origin_head->ds_deadlist,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dused = dsl_dataset_phys(clone)->ds_referenced_bytes +
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs (dsl_dataset_phys(origin_head)->ds_referenced_bytes +
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dcomp = dsl_dataset_phys(clone)->ds_compressed_bytes +
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs (dsl_dataset_phys(origin_head)->ds_compressed_bytes +
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs duncomp = dsl_dataset_phys(clone)->ds_uncompressed_bytes +
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs (dsl_dataset_phys(origin_head)->ds_uncompressed_bytes +
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_diduse_space(origin_head->ds_dir, DD_USED_HEAD,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_diduse_space(clone->ds_dir, DD_USED_HEAD,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * The difference in the space used by snapshots is the
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * difference in snapshot space due to the head's
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * deadlist (since that's the only thing that's
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * changing that affects the snapused).
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_deadlist_space_range(&clone->ds_deadlist,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens origin_head->ds_dir->dd_origin_txg, UINT64_MAX,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_deadlist_space_range(&origin_head->ds_deadlist,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens origin_head->ds_dir->dd_origin_txg, UINT64_MAX,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_transfer_space(origin_head->ds_dir, cdl_used - odl_used,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* swap ds_*_bytes */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs SWITCH64(dsl_dataset_phys(origin_head)->ds_referenced_bytes,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(clone)->ds_referenced_bytes);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs SWITCH64(dsl_dataset_phys(origin_head)->ds_compressed_bytes,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(clone)->ds_compressed_bytes);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs SWITCH64(dsl_dataset_phys(origin_head)->ds_uncompressed_bytes,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(clone)->ds_uncompressed_bytes);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs SWITCH64(dsl_dataset_phys(origin_head)->ds_unique_bytes,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens /* apply any parent delta for change in unconsumed refreservation */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_diduse_space(origin_head->ds_dir, DD_USED_REFRSRV,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Swap deadlists.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_deadlist_close(&origin_head->ds_deadlist);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs SWITCH64(dsl_dataset_phys(origin_head)->ds_deadlist_obj,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_deadlist_open(&clone->ds_deadlist, dp->dp_meta_objset,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_deadlist_open(&origin_head->ds_deadlist, dp->dp_meta_objset,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(origin_head)->ds_deadlist_obj);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_scan_ds_clone_swapped(origin_head, clone, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens spa_history_log_internal_ds(clone, "clone swap", tx,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens "parent=%s", origin_head->ds_dir->dd_myname);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Given a pool name and a dataset object number in that pool,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * return the name of that dataset.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_hold_obj(dp, obj, FTAG, &ds);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_check_quota(dsl_dataset_t *ds, boolean_t check_quota,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens uint64_t asize, uint64_t inflight, uint64_t *used, uint64_t *ref_rsrv)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * *ref_rsrv is the portion of asize that will come from any
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * unconsumed refreservation space.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Make a space adjustment for reserved bytes.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (ds->ds_reserved > dsl_dataset_phys(ds)->ds_unique_bytes) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs ds->ds_reserved - dsl_dataset_phys(ds)->ds_unique_bytes);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs (ds->ds_reserved - dsl_dataset_phys(ds)->ds_unique_bytes);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens asize - MIN(asize, parent_delta(ds, asize + inflight));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * If they are requesting more space, and our current estimate
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * is over quota, they get to try again unless the actual
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * on-disk is over quota and there are no pending changes (which
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * may free up space for us).
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_referenced_bytes + inflight >=
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_referenced_bytes < ds->ds_quota)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens/* ARGSUSED */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_set_refquota_check(void *arg, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (spa_version(dp->dp_spa) < SPA_VERSION_REFQUOTA)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ddsqra->ddsqra_source, ddsqra->ddsqra_value, &newval);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (newval < dsl_dataset_phys(ds)->ds_referenced_bytes ||
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_set_refquota_sync(void *arg, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_REFQUOTA), &newval));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_set_refquota(const char *dsname, zprop_source_t source,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens return (dsl_sync_task(dsname, dsl_dataset_set_refquota_check,
7d46dc6ca63a6f3f0d51aa655bfcf10cf2405a9eMatthew Ahrens dsl_dataset_set_refquota_sync, &ddsqra, 0, ZFS_SPACE_CHECK_NONE));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_set_refreservation_check(void *arg, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (spa_version(dp->dp_spa) < SPA_VERSION_REFRESERVATION)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ddsqra->ddsqra_source, ddsqra->ddsqra_value, &newval);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * If we are doing the preliminary check in open context, the
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * space estimates may be inaccurate.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs unique = dsl_dataset_phys(ds)->ds_unique_bytes;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens if (MAX(unique, newval) > MAX(unique, ds->ds_reserved)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_space_available(ds->ds_dir, NULL, 0, B_TRUE) ||
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (ds->ds_quota > 0 && newval > ds->ds_quota)) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_set_refreservation_sync_impl(dsl_dataset_t *ds,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zprop_source_t source, uint64_t value, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_REFRESERVATION),
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_REFRESERVATION), &newval));
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs unique = dsl_dataset_phys(ds)->ds_unique_bytes;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_set_refreservation_sync(void *arg, dmu_tx_t *tx)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ddsqra->ddsqra_source, ddsqra->ddsqra_value, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_dataset_set_refreservation(const char *dsname, zprop_source_t source,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens return (dsl_sync_task(dsname, dsl_dataset_set_refreservation_check,
7d46dc6ca63a6f3f0d51aa655bfcf10cf2405a9eMatthew Ahrens dsl_dataset_set_refreservation_sync, &ddsqra,
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * Return (in *usedp) the amount of space written in new that is not
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * present in oldsnap. New may be a snapshot or the head. Old must be
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * a snapshot before new, in new's filesystem (or its origin). If not then
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * fail and return EINVAL.
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * The written space is calculated by considering two components: First, we
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * ignore any freed space, and calculate the written as new's used space
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * minus old's used space. Next, we add in the amount of space that was freed
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * between the two snapshots, thus reducing new's used space relative to old's.
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * Specifically, this is the space that was born before old->ds_creation_txg,
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * and freed before new (ie. on new's deadlist or a previous deadlist).
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * space freed [---------------------]
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * snapshots ---O-------O--------O-------O------
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * oldsnap new
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrensdsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new,
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs *usedp += dsl_dataset_phys(new)->ds_referenced_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs *usedp -= dsl_dataset_phys(oldsnap)->ds_referenced_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs *compp += dsl_dataset_phys(new)->ds_compressed_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs *compp -= dsl_dataset_phys(oldsnap)->ds_compressed_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs *uncompp += dsl_dataset_phys(new)->ds_uncompressed_bytes;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs *uncompp -= dsl_dataset_phys(oldsnap)->ds_uncompressed_bytes;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &snap);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(snap)->ds_prev_snap_txg ==
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(oldsnap)->ds_creation_txg) {
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * The blocks in the deadlist can not be born after
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * ds_prev_snap_txg, so get the whole deadlist space,
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * which is more efficient (especially for old-format
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * deadlists). Unfortunately the deadlist code
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * doesn't have enough information to make this
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * optimization itself.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs 0, dsl_dataset_phys(oldsnap)->ds_creation_txg,
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * If we get to the beginning of the chain of snapshots
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * (ds_prev_snap_obj == 0) before oldsnap, then oldsnap
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * was not a snapshot of/before new.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs snapobj = dsl_dataset_phys(snap)->ds_prev_snap_obj;
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * Return (in *usedp) the amount of space that will be reclaimed if firstsnap,
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * lastsnap, and all snapshots in between are deleted.
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * blocks that would be freed [---------------------------]
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * snapshots ---O-------O--------O-------O--------O
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * firstsnap lastsnap
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * This is the set of blocks that were born after the snap before firstsnap,
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * (birth > firstsnap->prev_snap_txg) and died before the snap after the
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * last snap (ie, is on lastsnap->ds_next->ds_deadlist or an earlier deadlist).
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * We calculate this by iterating over the relevant deadlists (from the snap
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * after lastsnap, backward to the snap after firstsnap), summing up the
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * space on the deadlist that was born after the snap before firstsnap.
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrensdsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap,
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * Check that the snapshots are in the same dsl_dir, and firstsnap
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens * is before lastsnap.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(firstsnap)->ds_creation_txg >
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(lastsnap)->ds_creation_txg)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs snapobj = dsl_dataset_phys(lastsnap)->ds_next_snap_obj;
19b94df933188a15d4f0d6c568f0bab3f127892eMatthew Ahrens err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &ds);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(firstsnap)->ds_prev_snap_txg, UINT64_MAX,
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs snapobj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Return TRUE if 'earlier' is an earlier snapshot in 'later's timeline.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * For example, they could both be snapshots of the same filesystem, and
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * 'earlier' is before 'later'. Or 'earlier' could be the origin of
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * 'later's filesystem. Or 'earlier' could be an older snapshot in the origin's
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * filesystem. Or 'earlier' could be the origin's origin.
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens * If non-zero, earlier_txg is used instead of earlier's ds_creation_txg.
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrensdsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier,
bc9014e6a81272073b9854d9f65dd59e18d18c35Justin Gibbs ASSERT(earlier->ds_is_snapshot || earlier_txg != 0);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs earlier_txg = dsl_dataset_phys(earlier)->ds_creation_txg;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs earlier_txg >= dsl_dataset_phys(later)->ds_creation_txg)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dir_phys(later->ds_dir)->dd_origin_obj == earlier->ds_object)
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(later->ds_dir)->dd_origin_obj, FTAG, &origin);
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens ret = dsl_dataset_is_before(origin, earlier, earlier_txg);
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrensdsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx)
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrens objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrens dmu_object_zapify(mos, ds->ds_object, DMU_OT_DSL_DATASET, tx);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens return (doi.doi_type == DMU_OTN_ZAP_METADATA);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrensdsl_dataset_has_resume_receive_state(dsl_dataset_t *ds)
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens zap_contains(ds->ds_dir->dd_pool->dp_meta_objset,