Deleted Added
full compact
dsl_dataset.c (237643) dsl_dataset.c (243674)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2011 by Delphix. All rights reserved.
23 * Copyright (c) 2012 by Delphix. All rights reserved.
24 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
25 * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
26 * All rights reserved.
27 * Portions Copyright (c) 2011 Martin Matuska <mm@FreeBSD.org>
28 */
29
30#include <sys/dmu_objset.h>
31#include <sys/dsl_dataset.h>
32#include <sys/dsl_dir.h>
33#include <sys/dsl_prop.h>
34#include <sys/dsl_synctask.h>
35#include <sys/dmu_traverse.h>
36#include <sys/dmu_impl.h>
37#include <sys/dmu_tx.h>
38#include <sys/arc.h>
39#include <sys/zio.h>
40#include <sys/zap.h>
24 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
25 * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
26 * All rights reserved.
27 * Portions Copyright (c) 2011 Martin Matuska <mm@FreeBSD.org>
28 */
29
30#include <sys/dmu_objset.h>
31#include <sys/dsl_dataset.h>
32#include <sys/dsl_dir.h>
33#include <sys/dsl_prop.h>
34#include <sys/dsl_synctask.h>
35#include <sys/dmu_traverse.h>
36#include <sys/dmu_impl.h>
37#include <sys/dmu_tx.h>
38#include <sys/arc.h>
39#include <sys/zio.h>
40#include <sys/zap.h>
41#include <sys/zfeature.h>
41#include <sys/unique.h>
42#include <sys/zfs_context.h>
43#include <sys/zfs_ioctl.h>
44#include <sys/spa.h>
45#include <sys/zfs_znode.h>
46#include <sys/zfs_onexit.h>
47#include <sys/zvol.h>
48#include <sys/dsl_scan.h>

--- 49 unchanged lines hidden (view full) ---

98
99 dprintf_bp(bp, "ds=%p", ds);
100
101 ASSERT(dmu_tx_is_syncing(tx));
102 /* It could have been compressed away to nothing */
103 if (BP_IS_HOLE(bp))
104 return;
105 ASSERT(BP_GET_TYPE(bp) != DMU_OT_NONE);
42#include <sys/unique.h>
43#include <sys/zfs_context.h>
44#include <sys/zfs_ioctl.h>
45#include <sys/spa.h>
46#include <sys/zfs_znode.h>
47#include <sys/zfs_onexit.h>
48#include <sys/zvol.h>
49#include <sys/dsl_scan.h>

--- 49 unchanged lines hidden (view full) ---

99
100 dprintf_bp(bp, "ds=%p", ds);
101
102 ASSERT(dmu_tx_is_syncing(tx));
103 /* It could have been compressed away to nothing */
104 if (BP_IS_HOLE(bp))
105 return;
106 ASSERT(BP_GET_TYPE(bp) != DMU_OT_NONE);
106 ASSERT3U(BP_GET_TYPE(bp), <, DMU_OT_NUMTYPES);
107 ASSERT(DMU_OT_IS_VALID(BP_GET_TYPE(bp)));
107 if (ds == NULL) {
108 if (ds == NULL) {
108 /*
109 * Account for the meta-objset space in its placeholder
110 * dsl_dir.
111 */
112 ASSERT3U(compressed, ==, uncompressed); /* it's all metadata */
113 dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, DD_USED_HEAD,
114 used, compressed, uncompressed, tx);
115 dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx);
109 dsl_pool_mos_diduse_space(tx->tx_pool,
110 used, compressed, uncompressed);
116 return;
117 }
118 dmu_buf_will_dirty(ds->ds_dbuf, tx);
119
120 mutex_enter(&ds->ds_dir->dd_lock);
121 mutex_enter(&ds->ds_lock);
122 delta = parent_delta(ds, used);
111 return;
112 }
113 dmu_buf_will_dirty(ds->ds_dbuf, tx);
114
115 mutex_enter(&ds->ds_dir->dd_lock);
116 mutex_enter(&ds->ds_lock);
117 delta = parent_delta(ds, used);
123 ds->ds_phys->ds_used_bytes += used;
118 ds->ds_phys->ds_referenced_bytes += used;
124 ds->ds_phys->ds_compressed_bytes += compressed;
125 ds->ds_phys->ds_uncompressed_bytes += uncompressed;
126 ds->ds_phys->ds_unique_bytes += used;
127 mutex_exit(&ds->ds_lock);
128 dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD, delta,
129 compressed, uncompressed, tx);
130 dsl_dir_transfer_space(ds->ds_dir, used - delta,
131 DD_USED_REFRSRV, DD_USED_HEAD, tx);

--- 11 unchanged lines hidden (view full) ---

143 ASSERT(bp->blk_birth <= tx->tx_txg);
144
145 int used = bp_get_dsize_sync(tx->tx_pool->dp_spa, bp);
146 int compressed = BP_GET_PSIZE(bp);
147 int uncompressed = BP_GET_UCSIZE(bp);
148
149 ASSERT(used > 0);
150 if (ds == NULL) {
119 ds->ds_phys->ds_compressed_bytes += compressed;
120 ds->ds_phys->ds_uncompressed_bytes += uncompressed;
121 ds->ds_phys->ds_unique_bytes += used;
122 mutex_exit(&ds->ds_lock);
123 dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD, delta,
124 compressed, uncompressed, tx);
125 dsl_dir_transfer_space(ds->ds_dir, used - delta,
126 DD_USED_REFRSRV, DD_USED_HEAD, tx);

--- 11 unchanged lines hidden (view full) ---

138 ASSERT(bp->blk_birth <= tx->tx_txg);
139
140 int used = bp_get_dsize_sync(tx->tx_pool->dp_spa, bp);
141 int compressed = BP_GET_PSIZE(bp);
142 int uncompressed = BP_GET_UCSIZE(bp);
143
144 ASSERT(used > 0);
145 if (ds == NULL) {
151 /*
152 * Account for the meta-objset space in its placeholder
153 * dataset.
154 */
155 dsl_free(tx->tx_pool, tx->tx_txg, bp);
146 dsl_free(tx->tx_pool, tx->tx_txg, bp);
156
157 dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, DD_USED_HEAD,
158 -used, -compressed, -uncompressed, tx);
159 dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx);
147 dsl_pool_mos_diduse_space(tx->tx_pool,
148 -used, -compressed, -uncompressed);
160 return (used);
161 }
162 ASSERT3P(tx->tx_pool, ==, ds->ds_dir->dd_pool);
163
164 ASSERT(!dsl_dataset_is_snapshot(ds));
165 dmu_buf_will_dirty(ds->ds_dbuf, tx);
166
167 if (bp->blk_birth > ds->ds_phys->ds_prev_snap_txg) {

--- 41 unchanged lines hidden (view full) ---

209 mutex_exit(&ds->ds_prev->ds_lock);
210 }
211 if (bp->blk_birth > ds->ds_dir->dd_origin_txg) {
212 dsl_dir_transfer_space(ds->ds_dir, used,
213 DD_USED_HEAD, DD_USED_SNAP, tx);
214 }
215 }
216 mutex_enter(&ds->ds_lock);
149 return (used);
150 }
151 ASSERT3P(tx->tx_pool, ==, ds->ds_dir->dd_pool);
152
153 ASSERT(!dsl_dataset_is_snapshot(ds));
154 dmu_buf_will_dirty(ds->ds_dbuf, tx);
155
156 if (bp->blk_birth > ds->ds_phys->ds_prev_snap_txg) {

--- 41 unchanged lines hidden (view full) ---

198 mutex_exit(&ds->ds_prev->ds_lock);
199 }
200 if (bp->blk_birth > ds->ds_dir->dd_origin_txg) {
201 dsl_dir_transfer_space(ds->ds_dir, used,
202 DD_USED_HEAD, DD_USED_SNAP, tx);
203 }
204 }
205 mutex_enter(&ds->ds_lock);
217 ASSERT3U(ds->ds_phys->ds_used_bytes, >=, used);
218 ds->ds_phys->ds_used_bytes -= used;
206 ASSERT3U(ds->ds_phys->ds_referenced_bytes, >=, used);
207 ds->ds_phys->ds_referenced_bytes -= used;
219 ASSERT3U(ds->ds_phys->ds_compressed_bytes, >=, compressed);
220 ds->ds_phys->ds_compressed_bytes -= compressed;
221 ASSERT3U(ds->ds_phys->ds_uncompressed_bytes, >=, uncompressed);
222 ds->ds_phys->ds_uncompressed_bytes -= uncompressed;
223 mutex_exit(&ds->ds_lock);
224
225 return (used);
226}

--- 595 unchanged lines hidden (view full) ---

822 if (origin == NULL) {
823 dsphys->ds_deadlist_obj = dsl_deadlist_alloc(mos, tx);
824 } else {
825 dsl_dataset_t *ohds;
826
827 dsphys->ds_prev_snap_obj = origin->ds_object;
828 dsphys->ds_prev_snap_txg =
829 origin->ds_phys->ds_creation_txg;
208 ASSERT3U(ds->ds_phys->ds_compressed_bytes, >=, compressed);
209 ds->ds_phys->ds_compressed_bytes -= compressed;
210 ASSERT3U(ds->ds_phys->ds_uncompressed_bytes, >=, uncompressed);
211 ds->ds_phys->ds_uncompressed_bytes -= uncompressed;
212 mutex_exit(&ds->ds_lock);
213
214 return (used);
215}

--- 595 unchanged lines hidden (view full) ---

811 if (origin == NULL) {
812 dsphys->ds_deadlist_obj = dsl_deadlist_alloc(mos, tx);
813 } else {
814 dsl_dataset_t *ohds;
815
816 dsphys->ds_prev_snap_obj = origin->ds_object;
817 dsphys->ds_prev_snap_txg =
818 origin->ds_phys->ds_creation_txg;
830 dsphys->ds_used_bytes =
831 origin->ds_phys->ds_used_bytes;
819 dsphys->ds_referenced_bytes =
820 origin->ds_phys->ds_referenced_bytes;
832 dsphys->ds_compressed_bytes =
833 origin->ds_phys->ds_compressed_bytes;
834 dsphys->ds_uncompressed_bytes =
835 origin->ds_phys->ds_uncompressed_bytes;
836 dsphys->ds_bp = origin->ds_phys->ds_bp;
837 dsphys->ds_flags |= origin->ds_phys->ds_flags;
838
839 dmu_buf_will_dirty(origin->ds_dbuf, tx);

--- 136 unchanged lines hidden (view full) ---

976 err = spa_open(nvpair_name(pair), &spa, FTAG);
977 if (err)
978 return (err);
979 dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
980
981 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
982 pair = nvlist_next_nvpair(snaps, pair)) {
983 dsl_dataset_t *ds;
821 dsphys->ds_compressed_bytes =
822 origin->ds_phys->ds_compressed_bytes;
823 dsphys->ds_uncompressed_bytes =
824 origin->ds_phys->ds_uncompressed_bytes;
825 dsphys->ds_bp = origin->ds_phys->ds_bp;
826 dsphys->ds_flags |= origin->ds_phys->ds_flags;
827
828 dmu_buf_will_dirty(origin->ds_dbuf, tx);

--- 136 unchanged lines hidden (view full) ---

965 err = spa_open(nvpair_name(pair), &spa, FTAG);
966 if (err)
967 return (err);
968 dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
969
970 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
971 pair = nvlist_next_nvpair(snaps, pair)) {
972 dsl_dataset_t *ds;
984 int err;
985
986 err = dsl_dataset_own(nvpair_name(pair), B_TRUE, dstg, &ds);
987 if (err == 0) {
988 struct dsl_ds_destroyarg *dsda;
989
990 dsl_dataset_make_exclusive(ds, dstg);
991 dsda = kmem_zalloc(sizeof (struct dsl_ds_destroyarg),
992 KM_SLEEP);

--- 118 unchanged lines hidden (view full) ---

1111 err = EINVAL;
1112 goto out;
1113 }
1114
1115 dd = ds->ds_dir;
1116 dummy_ds.ds_dir = dd;
1117 dummy_ds.ds_object = ds->ds_object;
1118
973
974 err = dsl_dataset_own(nvpair_name(pair), B_TRUE, dstg, &ds);
975 if (err == 0) {
976 struct dsl_ds_destroyarg *dsda;
977
978 dsl_dataset_make_exclusive(ds, dstg);
979 dsda = kmem_zalloc(sizeof (struct dsl_ds_destroyarg),
980 KM_SLEEP);

--- 118 unchanged lines hidden (view full) ---

1099 err = EINVAL;
1100 goto out;
1101 }
1102
1103 dd = ds->ds_dir;
1104 dummy_ds.ds_dir = dd;
1105 dummy_ds.ds_object = ds->ds_object;
1106
1119 /*
1120 * Check for errors and mark this ds as inconsistent, in
1121 * case we crash while freeing the objects.
1122 */
1123 err = dsl_sync_task_do(dd->dd_pool, dsl_dataset_destroy_begin_check,
1124 dsl_dataset_destroy_begin_sync, ds, NULL, 0);
1125 if (err)
1126 goto out;
1107 if (!spa_feature_is_enabled(dsl_dataset_get_spa(ds),
1108 &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
1109 /*
1110 * Check for errors and mark this ds as inconsistent, in
1111 * case we crash while freeing the objects.
1112 */
1113 err = dsl_sync_task_do(dd->dd_pool,
1114 dsl_dataset_destroy_begin_check,
1115 dsl_dataset_destroy_begin_sync, ds, NULL, 0);
1116 if (err)
1117 goto out;
1127
1118
1128 err = dmu_objset_from_ds(ds, &os);
1129 if (err)
1130 goto out;
1119 err = dmu_objset_from_ds(ds, &os);
1120 if (err)
1121 goto out;
1131
1122
1132 /*
1133 * remove the objects in open context, so that we won't
1134 * have too much to do in syncing context.
1135 */
1136 for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE,
1137 ds->ds_phys->ds_prev_snap_txg)) {
1138 /*
1123 /*
1139 * Ignore errors, if there is not enough disk space
1140 * we will deal with it in dsl_dataset_destroy_sync().
1124 * Remove all objects while in the open context so that
1125 * there is less work to do in the syncing context.
1141 */
1126 */
1142 (void) dmu_free_object(os, obj);
1143 }
1144 if (err != ESRCH)
1145 goto out;
1127 for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE,
1128 ds->ds_phys->ds_prev_snap_txg)) {
1129 /*
1130 * Ignore errors, if there is not enough disk space
1131 * we will deal with it in dsl_dataset_destroy_sync().
1132 */
1133 (void) dmu_free_object(os, obj);
1134 }
1135 if (err != ESRCH)
1136 goto out;
1146
1137
1147 /*
1148 * Only the ZIL knows how to free log blocks.
1149 */
1150 zil_destroy(dmu_objset_zil(os), B_FALSE);
1138 /*
1139 * Sync out all in-flight IO.
1140 */
1141 txg_wait_synced(dd->dd_pool, 0);
1151
1142
1152 /*
1153 * Sync out all in-flight IO.
1154 */
1155 txg_wait_synced(dd->dd_pool, 0);
1143 /*
1144 * If we managed to free all the objects in open
1145 * context, the user space accounting should be zero.
1146 */
1147 if (ds->ds_phys->ds_bp.blk_fill == 0 &&
1148 dmu_objset_userused_enabled(os)) {
1149 uint64_t count;
1156
1150
1157 /*
1158 * If we managed to free all the objects in open
1159 * context, the user space accounting should be zero.
1160 */
1161 if (ds->ds_phys->ds_bp.blk_fill == 0 &&
1162 dmu_objset_userused_enabled(os)) {
1163 uint64_t count;
1164
1165 ASSERT(zap_count(os, DMU_USERUSED_OBJECT, &count) != 0 ||
1166 count == 0);
1167 ASSERT(zap_count(os, DMU_GROUPUSED_OBJECT, &count) != 0 ||
1168 count == 0);
1151 ASSERT(zap_count(os, DMU_USERUSED_OBJECT,
1152 &count) != 0 || count == 0);
1153 ASSERT(zap_count(os, DMU_GROUPUSED_OBJECT,
1154 &count) != 0 || count == 0);
1155 }
1169 }
1170
1171 rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER);
1172 err = dsl_dir_open_obj(dd->dd_pool, dd->dd_object, NULL, FTAG, &dd);
1173 rw_exit(&dd->dd_pool->dp_config_rwlock);
1174
1175 if (err)
1176 goto out;

--- 89 unchanged lines hidden (view full) ---

1266 dp = ds->ds_dir->dd_pool;
1267
1268 if (txg_list_add(&dp->dp_dirty_datasets, ds, tx->tx_txg) == 0) {
1269 /* up the hold count until we can be written out */
1270 dmu_buf_add_ref(ds->ds_dbuf, ds);
1271 }
1272}
1273
1156 }
1157
1158 rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER);
1159 err = dsl_dir_open_obj(dd->dd_pool, dd->dd_object, NULL, FTAG, &dd);
1160 rw_exit(&dd->dd_pool->dp_config_rwlock);
1161
1162 if (err)
1163 goto out;

--- 89 unchanged lines hidden (view full) ---

1253 dp = ds->ds_dir->dd_pool;
1254
1255 if (txg_list_add(&dp->dp_dirty_datasets, ds, tx->tx_txg) == 0) {
1256 /* up the hold count until we can be written out */
1257 dmu_buf_add_ref(ds->ds_dbuf, ds);
1258 }
1259}
1260
1261boolean_t
1262dsl_dataset_is_dirty(dsl_dataset_t *ds)
1263{
1264 for (int t = 0; t < TXG_SIZE; t++) {
1265 if (txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets,
1266 ds, t))
1267 return (B_TRUE);
1268 }
1269 return (B_FALSE);
1270}
1271
1274/*
1275 * The unique space in the head dataset can be calculated by subtracting
1276 * the space used in the most recent snapshot, that is still being used
1277 * in this file system, from the space currently in use. To figure out
1278 * the space in the most recent snapshot still in use, we need to take
1279 * the total space used in the snapshot and subtract out the space that
1280 * has been freed up since the snapshot was taken.
1281 */
1282static void
1283dsl_dataset_recalc_head_uniq(dsl_dataset_t *ds)
1284{
1285 uint64_t mrs_used;
1286 uint64_t dlused, dlcomp, dluncomp;
1287
1288 ASSERT(!dsl_dataset_is_snapshot(ds));
1289
1290 if (ds->ds_phys->ds_prev_snap_obj != 0)
1272/*
1273 * The unique space in the head dataset can be calculated by subtracting
1274 * the space used in the most recent snapshot, that is still being used
1275 * in this file system, from the space currently in use. To figure out
1276 * the space in the most recent snapshot still in use, we need to take
1277 * the total space used in the snapshot and subtract out the space that
1278 * has been freed up since the snapshot was taken.
1279 */
1280static void
1281dsl_dataset_recalc_head_uniq(dsl_dataset_t *ds)
1282{
1283 uint64_t mrs_used;
1284 uint64_t dlused, dlcomp, dluncomp;
1285
1286 ASSERT(!dsl_dataset_is_snapshot(ds));
1287
1288 if (ds->ds_phys->ds_prev_snap_obj != 0)
1291 mrs_used = ds->ds_prev->ds_phys->ds_used_bytes;
1289 mrs_used = ds->ds_prev->ds_phys->ds_referenced_bytes;
1292 else
1293 mrs_used = 0;
1294
1295 dsl_deadlist_space(&ds->ds_deadlist, &dlused, &dlcomp, &dluncomp);
1296
1297 ASSERT3U(dlused, <=, mrs_used);
1298 ds->ds_phys->ds_unique_bytes =
1290 else
1291 mrs_used = 0;
1292
1293 dsl_deadlist_space(&ds->ds_deadlist, &dlused, &dlcomp, &dluncomp);
1294
1295 ASSERT3U(dlused, <=, mrs_used);
1296 ds->ds_phys->ds_unique_bytes =
1299 ds->ds_phys->ds_used_bytes - (mrs_used - dlused);
1297 ds->ds_phys->ds_referenced_bytes - (mrs_used - dlused);
1300
1301 if (spa_version(ds->ds_dir->dd_pool->dp_spa) >=
1302 SPA_VERSION_UNIQUE_ACCURATE)
1303 ds->ds_phys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE;
1304}
1305
1306struct killarg {
1307 dsl_dataset_t *ds;

--- 238 unchanged lines hidden (view full) ---

1546 * ds_next_snap_obj when it should, leading to a missing entry.
1547 * If we knew that the pool was created after
1548 * SPA_VERSION_NEXT_CLONES, we could assert that it isn't
1549 * ENOENT. However, at least we can check that we don't have
1550 * too many entries in the next_clones_obj even after failing to
1551 * remove this one.
1552 */
1553 if (err != ENOENT) {
1298
1299 if (spa_version(ds->ds_dir->dd_pool->dp_spa) >=
1300 SPA_VERSION_UNIQUE_ACCURATE)
1301 ds->ds_phys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE;
1302}
1303
1304struct killarg {
1305 dsl_dataset_t *ds;

--- 238 unchanged lines hidden (view full) ---

1544 * ds_next_snap_obj when it should, leading to a missing entry.
1545 * If we knew that the pool was created after
1546 * SPA_VERSION_NEXT_CLONES, we could assert that it isn't
1547 * ENOENT. However, at least we can check that we don't have
1548 * too many entries in the next_clones_obj even after failing to
1549 * remove this one.
1550 */
1551 if (err != ENOENT) {
1554 VERIFY3U(err, ==, 0);
1552 VERIFY0(err);
1555 }
1556 ASSERT3U(0, ==, zap_count(mos, ds->ds_phys->ds_next_clones_obj,
1557 &count));
1558 ASSERT3U(count, <=, ds->ds_phys->ds_num_children - 2);
1559}
1560
1561static void
1562dsl_dataset_remove_clones_key(dsl_dataset_t *ds, uint64_t mintxg, dmu_tx_t *tx)

--- 70 unchanged lines hidden (view full) ---

1633 ASSERT(ds_next->ds_deadlist.dl_oldfmt);
1634
1635 poa.ds = ds;
1636 poa.ds_prev = ds_prev;
1637 poa.after_branch_point = after_branch_point;
1638 poa.pio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
1639 VERIFY3U(0, ==, bpobj_iterate(&ds_next->ds_deadlist.dl_bpobj,
1640 process_old_cb, &poa, tx));
1553 }
1554 ASSERT3U(0, ==, zap_count(mos, ds->ds_phys->ds_next_clones_obj,
1555 &count));
1556 ASSERT3U(count, <=, ds->ds_phys->ds_num_children - 2);
1557}
1558
1559static void
1560dsl_dataset_remove_clones_key(dsl_dataset_t *ds, uint64_t mintxg, dmu_tx_t *tx)

--- 70 unchanged lines hidden (view full) ---

1631 ASSERT(ds_next->ds_deadlist.dl_oldfmt);
1632
1633 poa.ds = ds;
1634 poa.ds_prev = ds_prev;
1635 poa.after_branch_point = after_branch_point;
1636 poa.pio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
1637 VERIFY3U(0, ==, bpobj_iterate(&ds_next->ds_deadlist.dl_bpobj,
1638 process_old_cb, &poa, tx));
1641 VERIFY3U(zio_wait(poa.pio), ==, 0);
1639 VERIFY0(zio_wait(poa.pio));
1642 ASSERT3U(poa.used, ==, ds->ds_phys->ds_unique_bytes);
1643
1644 /* change snapused */
1645 dsl_dir_diduse_space(ds->ds_dir, DD_USED_SNAP,
1646 -poa.used, -poa.comp, -poa.uncomp, tx);
1647
1648 /* swap next's deadlist to our deadlist */
1649 dsl_deadlist_close(&ds->ds_deadlist);
1650 dsl_deadlist_close(&ds_next->ds_deadlist);
1651 SWITCH64(ds_next->ds_phys->ds_deadlist_obj,
1652 ds->ds_phys->ds_deadlist_obj);
1653 dsl_deadlist_open(&ds->ds_deadlist, mos, ds->ds_phys->ds_deadlist_obj);
1654 dsl_deadlist_open(&ds_next->ds_deadlist, mos,
1655 ds_next->ds_phys->ds_deadlist_obj);
1656}
1657
1640 ASSERT3U(poa.used, ==, ds->ds_phys->ds_unique_bytes);
1641
1642 /* change snapused */
1643 dsl_dir_diduse_space(ds->ds_dir, DD_USED_SNAP,
1644 -poa.used, -poa.comp, -poa.uncomp, tx);
1645
1646 /* swap next's deadlist to our deadlist */
1647 dsl_deadlist_close(&ds->ds_deadlist);
1648 dsl_deadlist_close(&ds_next->ds_deadlist);
1649 SWITCH64(ds_next->ds_phys->ds_deadlist_obj,
1650 ds->ds_phys->ds_deadlist_obj);
1651 dsl_deadlist_open(&ds->ds_deadlist, mos, ds->ds_phys->ds_deadlist_obj);
1652 dsl_deadlist_open(&ds_next->ds_deadlist, mos,
1653 ds_next->ds_phys->ds_deadlist_obj);
1654}
1655
1656static int
1657old_synchronous_dataset_destroy(dsl_dataset_t *ds, dmu_tx_t *tx)
1658{
1659 int err;
1660 struct killarg ka;
1661
1662 /*
1663 * Free everything that we point to (that's born after
1664 * the previous snapshot, if we are a clone)
1665 *
1666 * NB: this should be very quick, because we already
1667 * freed all the objects in open context.
1668 */
1669 ka.ds = ds;
1670 ka.tx = tx;
1671 err = traverse_dataset(ds,
1672 ds->ds_phys->ds_prev_snap_txg, TRAVERSE_POST,
1673 kill_blkptr, &ka);
1674 ASSERT0(err);
1675 ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) || ds->ds_phys->ds_unique_bytes == 0);
1676
1677 return (err);
1678}
1679
1658void
1659dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
1660{
1661 struct dsl_ds_destroyarg *dsda = arg1;
1662 dsl_dataset_t *ds = dsda->ds;
1663 int err;
1664 int after_branch_point = FALSE;
1665 dsl_pool_t *dp = ds->ds_dir->dd_pool;

--- 30 unchanged lines hidden (view full) ---

1696 uint64_t value = 0;
1697
1698 dsl_prop_setarg_init_uint64(&psa, "refreservation",
1699 (ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED),
1700 &value);
1701 psa.psa_effective_value = 0; /* predict default value */
1702
1703 dsl_dataset_set_reservation_sync(ds, &psa, tx);
1680void
1681dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
1682{
1683 struct dsl_ds_destroyarg *dsda = arg1;
1684 dsl_dataset_t *ds = dsda->ds;
1685 int err;
1686 int after_branch_point = FALSE;
1687 dsl_pool_t *dp = ds->ds_dir->dd_pool;

--- 30 unchanged lines hidden (view full) ---

1718 uint64_t value = 0;
1719
1720 dsl_prop_setarg_init_uint64(&psa, "refreservation",
1721 (ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED),
1722 &value);
1723 psa.psa_effective_value = 0; /* predict default value */
1724
1725 dsl_dataset_set_reservation_sync(ds, &psa, tx);
1704 ASSERT3U(ds->ds_reserved, ==, 0);
1726 ASSERT0(ds->ds_reserved);
1705 }
1706
1707 ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock));
1708
1709 dsl_scan_ds_destroyed(ds, tx);
1710
1711 obj = ds->ds_object;
1712

--- 83 unchanged lines hidden (view full) ---

1796 -used, -comp, -uncomp, tx);
1797
1798 /* Move blocks to be freed to pool's free list. */
1799 dsl_deadlist_move_bpobj(&ds_next->ds_deadlist,
1800 &dp->dp_free_bpobj, ds->ds_phys->ds_prev_snap_txg,
1801 tx);
1802 dsl_dir_diduse_space(tx->tx_pool->dp_free_dir,
1803 DD_USED_HEAD, used, comp, uncomp, tx);
1727 }
1728
1729 ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock));
1730
1731 dsl_scan_ds_destroyed(ds, tx);
1732
1733 obj = ds->ds_object;
1734

--- 83 unchanged lines hidden (view full) ---

1818 -used, -comp, -uncomp, tx);
1819
1820 /* Move blocks to be freed to pool's free list. */
1821 dsl_deadlist_move_bpobj(&ds_next->ds_deadlist,
1822 &dp->dp_free_bpobj, ds->ds_phys->ds_prev_snap_txg,
1823 tx);
1824 dsl_dir_diduse_space(tx->tx_pool->dp_free_dir,
1825 DD_USED_HEAD, used, comp, uncomp, tx);
1804 dsl_dir_dirty(tx->tx_pool->dp_free_dir, tx);
1805
1806 /* Merge our deadlist into next's and free it. */
1807 dsl_deadlist_merge(&ds_next->ds_deadlist,
1808 ds->ds_phys->ds_deadlist_obj, tx);
1809 }
1810 dsl_deadlist_close(&ds->ds_deadlist);
1811 dsl_deadlist_free(mos, ds->ds_phys->ds_deadlist_obj, tx);
1812

--- 59 unchanged lines hidden (view full) ---

1872 mrsdelta = MIN(new_unique - old_unique,
1873 ds_next->ds_reserved - old_unique);
1874 dsl_dir_diduse_space(ds->ds_dir,
1875 DD_USED_REFRSRV, -mrsdelta, 0, 0, tx);
1876 }
1877 }
1878 dsl_dataset_rele(ds_next, FTAG);
1879 } else {
1826
1827 /* Merge our deadlist into next's and free it. */
1828 dsl_deadlist_merge(&ds_next->ds_deadlist,
1829 ds->ds_phys->ds_deadlist_obj, tx);
1830 }
1831 dsl_deadlist_close(&ds->ds_deadlist);
1832 dsl_deadlist_free(mos, ds->ds_phys->ds_deadlist_obj, tx);
1833

--- 59 unchanged lines hidden (view full) ---

1893 mrsdelta = MIN(new_unique - old_unique,
1894 ds_next->ds_reserved - old_unique);
1895 dsl_dir_diduse_space(ds->ds_dir,
1896 DD_USED_REFRSRV, -mrsdelta, 0, 0, tx);
1897 }
1898 }
1899 dsl_dataset_rele(ds_next, FTAG);
1900 } else {
1901 zfeature_info_t *async_destroy =
1902 &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY];
1903 objset_t *os;
1904
1880 /*
1881 * There's no next snapshot, so this is a head dataset.
1882 * Destroy the deadlist. Unless it's a clone, the
1883 * deadlist should be empty. (If it's a clone, it's
1884 * safe to ignore the deadlist contents.)
1885 */
1905 /*
1906 * There's no next snapshot, so this is a head dataset.
1907 * Destroy the deadlist. Unless it's a clone, the
1908 * deadlist should be empty. (If it's a clone, it's
1909 * safe to ignore the deadlist contents.)
1910 */
1886 struct killarg ka;
1887
1888 dsl_deadlist_close(&ds->ds_deadlist);
1889 dsl_deadlist_free(mos, ds->ds_phys->ds_deadlist_obj, tx);
1890 ds->ds_phys->ds_deadlist_obj = 0;
1891
1911 dsl_deadlist_close(&ds->ds_deadlist);
1912 dsl_deadlist_free(mos, ds->ds_phys->ds_deadlist_obj, tx);
1913 ds->ds_phys->ds_deadlist_obj = 0;
1914
1892 /*
1893 * Free everything that we point to (that's born after
1894 * the previous snapshot, if we are a clone)
1895 *
1896 * NB: this should be very quick, because we already
1897 * freed all the objects in open context.
1898 */
1899 ka.ds = ds;
1900 ka.tx = tx;
1901 err = traverse_dataset(ds, ds->ds_phys->ds_prev_snap_txg,
1902 TRAVERSE_POST, kill_blkptr, &ka);
1903 ASSERT3U(err, ==, 0);
1904 ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
1905 ds->ds_phys->ds_unique_bytes == 0);
1915 VERIFY3U(0, ==, dmu_objset_from_ds(ds, &os));
1906
1916
1917 if (!spa_feature_is_enabled(dp->dp_spa, async_destroy)) {
1918 err = old_synchronous_dataset_destroy(ds, tx);
1919 } else {
1920 /*
1921 * Move the bptree into the pool's list of trees to
1922 * clean up and update space accounting information.
1923 */
1924 uint64_t used, comp, uncomp;
1925
1926 zil_destroy_sync(dmu_objset_zil(os), tx);
1927
1928 if (!spa_feature_is_active(dp->dp_spa, async_destroy)) {
1929 spa_feature_incr(dp->dp_spa, async_destroy, tx);
1930 dp->dp_bptree_obj = bptree_alloc(mos, tx);
1931 VERIFY(zap_add(mos,
1932 DMU_POOL_DIRECTORY_OBJECT,
1933 DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1,
1934 &dp->dp_bptree_obj, tx) == 0);
1935 }
1936
1937 used = ds->ds_dir->dd_phys->dd_used_bytes;
1938 comp = ds->ds_dir->dd_phys->dd_compressed_bytes;
1939 uncomp = ds->ds_dir->dd_phys->dd_uncompressed_bytes;
1940
1941 ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
1942 ds->ds_phys->ds_unique_bytes == used);
1943
1944 bptree_add(mos, dp->dp_bptree_obj,
1945 &ds->ds_phys->ds_bp, ds->ds_phys->ds_prev_snap_txg,
1946 used, comp, uncomp, tx);
1947 dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
1948 -used, -comp, -uncomp, tx);
1949 dsl_dir_diduse_space(dp->dp_free_dir, DD_USED_HEAD,
1950 used, comp, uncomp, tx);
1951 }
1952
1907 if (ds->ds_prev != NULL) {
1908 if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
1909 VERIFY3U(0, ==, zap_remove_int(mos,
1910 ds->ds_prev->ds_dir->dd_phys->dd_clones,
1911 ds->ds_object, tx));
1912 }
1913 dsl_dataset_rele(ds->ds_prev, ds);
1914 ds->ds_prev = ds_prev = NULL;

--- 24 unchanged lines hidden (view full) ---

1939 ds->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &ds_head));
1940 VERIFY(0 == dsl_dataset_get_snapname(ds));
1941#ifdef ZFS_DEBUG
1942 {
1943 uint64_t val;
1944
1945 err = dsl_dataset_snap_lookup(ds_head,
1946 ds->ds_snapname, &val);
1953 if (ds->ds_prev != NULL) {
1954 if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
1955 VERIFY3U(0, ==, zap_remove_int(mos,
1956 ds->ds_prev->ds_dir->dd_phys->dd_clones,
1957 ds->ds_object, tx));
1958 }
1959 dsl_dataset_rele(ds->ds_prev, ds);
1960 ds->ds_prev = ds_prev = NULL;

--- 24 unchanged lines hidden (view full) ---

1985 ds->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &ds_head));
1986 VERIFY(0 == dsl_dataset_get_snapname(ds));
1987#ifdef ZFS_DEBUG
1988 {
1989 uint64_t val;
1990
1991 err = dsl_dataset_snap_lookup(ds_head,
1992 ds->ds_snapname, &val);
1947 ASSERT3U(err, ==, 0);
1993 ASSERT0(err);
1948 ASSERT3U(val, ==, obj);
1949 }
1950#endif
1951 err = dsl_dataset_snap_remove(ds_head, ds->ds_snapname, tx);
1952 ASSERT(err == 0);
1953 dsl_dataset_rele(ds_head, FTAG);
1954 }
1955

--- 134 unchanged lines hidden (view full) ---

2090 } while (dsphys->ds_guid == 0);
2091 dsphys->ds_prev_snap_obj = ds->ds_phys->ds_prev_snap_obj;
2092 dsphys->ds_prev_snap_txg = ds->ds_phys->ds_prev_snap_txg;
2093 dsphys->ds_next_snap_obj = ds->ds_object;
2094 dsphys->ds_num_children = 1;
2095 dsphys->ds_creation_time = gethrestime_sec();
2096 dsphys->ds_creation_txg = crtxg;
2097 dsphys->ds_deadlist_obj = ds->ds_phys->ds_deadlist_obj;
1994 ASSERT3U(val, ==, obj);
1995 }
1996#endif
1997 err = dsl_dataset_snap_remove(ds_head, ds->ds_snapname, tx);
1998 ASSERT(err == 0);
1999 dsl_dataset_rele(ds_head, FTAG);
2000 }
2001

--- 134 unchanged lines hidden (view full) ---

2136 } while (dsphys->ds_guid == 0);
2137 dsphys->ds_prev_snap_obj = ds->ds_phys->ds_prev_snap_obj;
2138 dsphys->ds_prev_snap_txg = ds->ds_phys->ds_prev_snap_txg;
2139 dsphys->ds_next_snap_obj = ds->ds_object;
2140 dsphys->ds_num_children = 1;
2141 dsphys->ds_creation_time = gethrestime_sec();
2142 dsphys->ds_creation_txg = crtxg;
2143 dsphys->ds_deadlist_obj = ds->ds_phys->ds_deadlist_obj;
2098 dsphys->ds_used_bytes = ds->ds_phys->ds_used_bytes;
2144 dsphys->ds_referenced_bytes = ds->ds_phys->ds_referenced_bytes;
2099 dsphys->ds_compressed_bytes = ds->ds_phys->ds_compressed_bytes;
2100 dsphys->ds_uncompressed_bytes = ds->ds_phys->ds_uncompressed_bytes;
2101 dsphys->ds_flags = ds->ds_phys->ds_flags;
2102 dsphys->ds_bp = ds->ds_phys->ds_bp;
2103 dmu_buf_rele(dbuf, FTAG);
2104
2105 ASSERT3U(ds->ds_prev != 0, ==, ds->ds_phys->ds_prev_snap_obj != 0);
2106 if (ds->ds_prev) {

--- 72 unchanged lines hidden (view full) ---

2179
2180 /*
2181 * in case we had to change ds_fsid_guid when we opened it,
2182 * sync it out now.
2183 */
2184 dmu_buf_will_dirty(ds->ds_dbuf, tx);
2185 ds->ds_phys->ds_fsid_guid = ds->ds_fsid_guid;
2186
2145 dsphys->ds_compressed_bytes = ds->ds_phys->ds_compressed_bytes;
2146 dsphys->ds_uncompressed_bytes = ds->ds_phys->ds_uncompressed_bytes;
2147 dsphys->ds_flags = ds->ds_phys->ds_flags;
2148 dsphys->ds_bp = ds->ds_phys->ds_bp;
2149 dmu_buf_rele(dbuf, FTAG);
2150
2151 ASSERT3U(ds->ds_prev != 0, ==, ds->ds_phys->ds_prev_snap_obj != 0);
2152 if (ds->ds_prev) {

--- 72 unchanged lines hidden (view full) ---

2225
2226 /*
2227 * in case we had to change ds_fsid_guid when we opened it,
2228 * sync it out now.
2229 */
2230 dmu_buf_will_dirty(ds->ds_dbuf, tx);
2231 ds->ds_phys->ds_fsid_guid = ds->ds_fsid_guid;
2232
2187 dsl_dir_dirty(ds->ds_dir, tx);
2188 dmu_objset_sync(ds->ds_objset, zio, tx);
2189}
2190
2191static void
2192get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
2193{
2194 uint64_t count = 0;
2195 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;

--- 18 unchanged lines hidden (view full) ---

2214 if (count != ds->ds_phys->ds_num_children - 1) {
2215 goto fail;
2216 }
2217 for (zap_cursor_init(&zc, mos, ds->ds_phys->ds_next_clones_obj);
2218 zap_cursor_retrieve(&zc, &za) == 0;
2219 zap_cursor_advance(&zc)) {
2220 dsl_dataset_t *clone;
2221 char buf[ZFS_MAXNAMELEN];
2233 dmu_objset_sync(ds->ds_objset, zio, tx);
2234}
2235
2236static void
2237get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
2238{
2239 uint64_t count = 0;
2240 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;

--- 18 unchanged lines hidden (view full) ---

2259 if (count != ds->ds_phys->ds_num_children - 1) {
2260 goto fail;
2261 }
2262 for (zap_cursor_init(&zc, mos, ds->ds_phys->ds_next_clones_obj);
2263 zap_cursor_retrieve(&zc, &za) == 0;
2264 zap_cursor_advance(&zc)) {
2265 dsl_dataset_t *clone;
2266 char buf[ZFS_MAXNAMELEN];
2267 /*
2268 * Even though we hold the dp_config_rwlock, the dataset
2269 * may fail to open, returning ENOENT. If there is a
2270 * thread concurrently attempting to destroy this
2271 * dataset, it will have the ds_rwlock held for
2272 * RW_WRITER. Our call to dsl_dataset_hold_obj() ->
2273 * dsl_dataset_hold_ref() will fail its
2274 * rw_tryenter(&ds->ds_rwlock, RW_READER), drop the
2275 * dp_config_rwlock, and wait for the destroy progress
2276 * and signal ds_exclusive_cv. If the destroy was
2277 * successful, we will see that
2278 * DSL_DATASET_IS_DESTROYED(), and return ENOENT.
2279 */
2222 if (dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
2280 if (dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
2223 za.za_first_integer, FTAG, &clone) != 0) {
2224 goto fail;
2225 }
2281 za.za_first_integer, FTAG, &clone) != 0)
2282 continue;
2226 dsl_dir_name(clone->ds_dir, buf);
2227 VERIFY(nvlist_add_boolean(val, buf) == 0);
2228 dsl_dataset_rele(clone, FTAG);
2229 }
2230 zap_cursor_fini(&zc);
2231 VERIFY(nvlist_add_nvlist(propval, ZPROP_VALUE, val) == 0);
2232 VERIFY(nvlist_add_nvlist(nv, zfs_prop_to_name(ZFS_PROP_CLONES),
2233 propval) == 0);

--- 47 unchanged lines hidden (view full) ---

2281 &comp, &uncomp);
2282 dsl_dataset_rele(prev, FTAG);
2283 if (err == 0) {
2284 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_WRITTEN,
2285 written);
2286 }
2287 }
2288 }
2283 dsl_dir_name(clone->ds_dir, buf);
2284 VERIFY(nvlist_add_boolean(val, buf) == 0);
2285 dsl_dataset_rele(clone, FTAG);
2286 }
2287 zap_cursor_fini(&zc);
2288 VERIFY(nvlist_add_nvlist(propval, ZPROP_VALUE, val) == 0);
2289 VERIFY(nvlist_add_nvlist(nv, zfs_prop_to_name(ZFS_PROP_CLONES),
2290 propval) == 0);

--- 47 unchanged lines hidden (view full) ---

2338 &comp, &uncomp);
2339 dsl_dataset_rele(prev, FTAG);
2340 if (err == 0) {
2341 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_WRITTEN,
2342 written);
2343 }
2344 }
2345 }
2289
2290 ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 :
2291 (ds->ds_phys->ds_uncompressed_bytes * 100 /
2292 ds->ds_phys->ds_compressed_bytes);
2293 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
2294
2295 if (ds->ds_phys->ds_next_snap_obj) {
2296 /*
2297 * This is a snapshot; override the dd's space used with

--- 42 unchanged lines hidden (view full) ---

2340 return (ds->ds_fsid_guid);
2341}
2342
2343void
2344dsl_dataset_space(dsl_dataset_t *ds,
2345 uint64_t *refdbytesp, uint64_t *availbytesp,
2346 uint64_t *usedobjsp, uint64_t *availobjsp)
2347{
2346 ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 :
2347 (ds->ds_phys->ds_uncompressed_bytes * 100 /
2348 ds->ds_phys->ds_compressed_bytes);
2349 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
2350
2351 if (ds->ds_phys->ds_next_snap_obj) {
2352 /*
2353 * This is a snapshot; override the dd's space used with

--- 42 unchanged lines hidden (view full) ---

2396 return (ds->ds_fsid_guid);
2397}
2398
2399void
2400dsl_dataset_space(dsl_dataset_t *ds,
2401 uint64_t *refdbytesp, uint64_t *availbytesp,
2402 uint64_t *usedobjsp, uint64_t *availobjsp)
2403{
2348 *refdbytesp = ds->ds_phys->ds_used_bytes;
2404 *refdbytesp = ds->ds_phys->ds_referenced_bytes;
2349 *availbytesp = dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE);
2350 if (ds->ds_reserved > ds->ds_phys->ds_unique_bytes)
2351 *availbytesp += ds->ds_reserved - ds->ds_phys->ds_unique_bytes;
2352 if (ds->ds_quota != 0) {
2353 /*
2354 * Adjust available bytes according to refquota
2355 */
2356 if (*refdbytesp < ds->ds_quota)

--- 79 unchanged lines hidden (view full) ---

2436
2437 ASSERT(ds->ds_phys->ds_next_snap_obj != 0);
2438
2439 VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool,
2440 dd->dd_phys->dd_head_dataset_obj, FTAG, &hds));
2441
2442 VERIFY(0 == dsl_dataset_get_snapname(ds));
2443 err = dsl_dataset_snap_remove(hds, ds->ds_snapname, tx);
2405 *availbytesp = dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE);
2406 if (ds->ds_reserved > ds->ds_phys->ds_unique_bytes)
2407 *availbytesp += ds->ds_reserved - ds->ds_phys->ds_unique_bytes;
2408 if (ds->ds_quota != 0) {
2409 /*
2410 * Adjust available bytes according to refquota
2411 */
2412 if (*refdbytesp < ds->ds_quota)

--- 79 unchanged lines hidden (view full) ---

2492
2493 ASSERT(ds->ds_phys->ds_next_snap_obj != 0);
2494
2495 VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool,
2496 dd->dd_phys->dd_head_dataset_obj, FTAG, &hds));
2497
2498 VERIFY(0 == dsl_dataset_get_snapname(ds));
2499 err = dsl_dataset_snap_remove(hds, ds->ds_snapname, tx);
2444 ASSERT3U(err, ==, 0);
2500 ASSERT0(err);
2445 dsl_dataset_name(ds, oldname);
2446 mutex_enter(&ds->ds_lock);
2447 (void) strcpy(ds->ds_snapname, newsnapname);
2448 mutex_exit(&ds->ds_lock);
2449 err = zap_add(mos, hds->ds_phys->ds_snapnames_zapobj,
2450 ds->ds_snapname, 8, 1, &ds->ds_object, tx);
2501 dsl_dataset_name(ds, oldname);
2502 mutex_enter(&ds->ds_lock);
2503 (void) strcpy(ds->ds_snapname, newsnapname);
2504 mutex_exit(&ds->ds_lock);
2505 err = zap_add(mos, hds->ds_phys->ds_snapnames_zapobj,
2506 ds->ds_snapname, 8, 1, &ds->ds_object, tx);
2451 ASSERT3U(err, ==, 0);
2507 ASSERT0(err);
2452 dsl_dataset_name(ds, newname);
2453#ifdef _KERNEL
2454 zvol_rename_minors(oldname, newname);
2455#endif
2456
2457 spa_history_log_internal(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx,
2458 "dataset = %llu", ds->ds_object);
2459 dsl_dataset_rele(hds, FTAG);

--- 223 unchanged lines hidden (view full) ---

2683 * (blocks born) = (my used) - (prev's used) + (blocks killed)
2684 * So a sequence would look like:
2685 * (uN - u(N-1) + kN) + ... + (u1 - u0 + k1) + (u0 - 0 + k0)
2686 * Which simplifies to:
2687 * uN + kN + kN-1 + ... + k1 + k0
2688 * Note however, if we stop before we reach the ORIGIN we get:
2689 * uN + kN + kN-1 + ... + kM - uM-1
2690 */
2508 dsl_dataset_name(ds, newname);
2509#ifdef _KERNEL
2510 zvol_rename_minors(oldname, newname);
2511#endif
2512
2513 spa_history_log_internal(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx,
2514 "dataset = %llu", ds->ds_object);
2515 dsl_dataset_rele(hds, FTAG);

--- 223 unchanged lines hidden (view full) ---

2739 * (blocks born) = (my used) - (prev's used) + (blocks killed)
2740 * So a sequence would look like:
2741 * (uN - u(N-1) + kN) + ... + (u1 - u0 + k1) + (u0 - 0 + k0)
2742 * Which simplifies to:
2743 * uN + kN + kN-1 + ... + k1 + k0
2744 * Note however, if we stop before we reach the ORIGIN we get:
2745 * uN + kN + kN-1 + ... + kM - uM-1
2746 */
2691 pa->used = origin_ds->ds_phys->ds_used_bytes;
2747 pa->used = origin_ds->ds_phys->ds_referenced_bytes;
2692 pa->comp = origin_ds->ds_phys->ds_compressed_bytes;
2693 pa->uncomp = origin_ds->ds_phys->ds_uncompressed_bytes;
2694 for (snap = list_head(&pa->shared_snaps); snap;
2695 snap = list_next(&pa->shared_snaps, snap)) {
2696 uint64_t val, dlused, dlcomp, dluncomp;
2697 dsl_dataset_t *ds = snap->ds;
2698
2699 /* Check that the snapshot name does not conflict */

--- 17 unchanged lines hidden (view full) ---

2717 pa->uncomp += dluncomp;
2718 }
2719
2720 /*
2721 * If we are a clone of a clone then we never reached ORIGIN,
2722 * so we need to subtract out the clone origin's used space.
2723 */
2724 if (pa->origin_origin) {
2748 pa->comp = origin_ds->ds_phys->ds_compressed_bytes;
2749 pa->uncomp = origin_ds->ds_phys->ds_uncompressed_bytes;
2750 for (snap = list_head(&pa->shared_snaps); snap;
2751 snap = list_next(&pa->shared_snaps, snap)) {
2752 uint64_t val, dlused, dlcomp, dluncomp;
2753 dsl_dataset_t *ds = snap->ds;
2754
2755 /* Check that the snapshot name does not conflict */

--- 17 unchanged lines hidden (view full) ---

2773 pa->uncomp += dluncomp;
2774 }
2775
2776 /*
2777 * If we are a clone of a clone then we never reached ORIGIN,
2778 * so we need to subtract out the clone origin's used space.
2779 */
2780 if (pa->origin_origin) {
2725 pa->used -= pa->origin_origin->ds_phys->ds_used_bytes;
2781 pa->used -= pa->origin_origin->ds_phys->ds_referenced_bytes;
2726 pa->comp -= pa->origin_origin->ds_phys->ds_compressed_bytes;
2727 pa->uncomp -= pa->origin_origin->ds_phys->ds_uncompressed_bytes;
2728 }
2729
2730 /* Check that there is enough space here */
2731 err = dsl_dir_transfer_possible(origin_ds->ds_dir, hds->ds_dir,
2732 pa->used);
2733 if (err)

--- 167 unchanged lines hidden (view full) ---

2901 odd->dd_phys->dd_clones, o, tx), ==, 0);
2902 VERIFY3U(zap_add_int(dp->dp_meta_objset,
2903 dd->dd_phys->dd_clones, o, tx), ==, 0);
2904 dsl_dataset_rele(cnds, FTAG);
2905 }
2906 zap_cursor_fini(&zc);
2907 }
2908
2782 pa->comp -= pa->origin_origin->ds_phys->ds_compressed_bytes;
2783 pa->uncomp -= pa->origin_origin->ds_phys->ds_uncompressed_bytes;
2784 }
2785
2786 /* Check that there is enough space here */
2787 err = dsl_dir_transfer_possible(origin_ds->ds_dir, hds->ds_dir,
2788 pa->used);
2789 if (err)

--- 167 unchanged lines hidden (view full) ---

2957 odd->dd_phys->dd_clones, o, tx), ==, 0);
2958 VERIFY3U(zap_add_int(dp->dp_meta_objset,
2959 dd->dd_phys->dd_clones, o, tx), ==, 0);
2960 dsl_dataset_rele(cnds, FTAG);
2961 }
2962 zap_cursor_fini(&zc);
2963 }
2964
2909 ASSERT3U(dsl_prop_numcb(ds), ==, 0);
2965 ASSERT0(dsl_prop_numcb(ds));
2910 }
2911
2912 /*
2913 * Change space accounting.
2914 * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either
2915 * both be valid, or both be 0 (resulting in delta == 0). This
2916 * is true for each of {clone,origin} independently.
2917 */

--- 315 unchanged lines hidden (view full) ---

3233 ASSERT3U(csa->cds->ds_dir->dd_phys->
3234 dd_used_breakdown[DD_USED_SNAP], ==, 0);
3235
3236 dsl_deadlist_space(&csa->cds->ds_deadlist,
3237 &cdl_used, &cdl_comp, &cdl_uncomp);
3238 dsl_deadlist_space(&csa->ohds->ds_deadlist,
3239 &odl_used, &odl_comp, &odl_uncomp);
3240
2966 }
2967
2968 /*
2969 * Change space accounting.
2970 * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either
2971 * both be valid, or both be 0 (resulting in delta == 0). This
2972 * is true for each of {clone,origin} independently.
2973 */

--- 315 unchanged lines hidden (view full) ---

3289 ASSERT3U(csa->cds->ds_dir->dd_phys->
3290 dd_used_breakdown[DD_USED_SNAP], ==, 0);
3291
3292 dsl_deadlist_space(&csa->cds->ds_deadlist,
3293 &cdl_used, &cdl_comp, &cdl_uncomp);
3294 dsl_deadlist_space(&csa->ohds->ds_deadlist,
3295 &odl_used, &odl_comp, &odl_uncomp);
3296
3241 dused = csa->cds->ds_phys->ds_used_bytes + cdl_used -
3242 (csa->ohds->ds_phys->ds_used_bytes + odl_used);
3297 dused = csa->cds->ds_phys->ds_referenced_bytes + cdl_used -
3298 (csa->ohds->ds_phys->ds_referenced_bytes + odl_used);
3243 dcomp = csa->cds->ds_phys->ds_compressed_bytes + cdl_comp -
3244 (csa->ohds->ds_phys->ds_compressed_bytes + odl_comp);
3245 duncomp = csa->cds->ds_phys->ds_uncompressed_bytes +
3246 cdl_uncomp -
3247 (csa->ohds->ds_phys->ds_uncompressed_bytes + odl_uncomp);
3248
3249 dsl_dir_diduse_space(csa->ohds->ds_dir, DD_USED_HEAD,
3250 dused, dcomp, duncomp, tx);

--- 12 unchanged lines hidden (view full) ---

3263 dsl_deadlist_space_range(&csa->ohds->ds_deadlist,
3264 csa->ohds->ds_dir->dd_origin_txg, UINT64_MAX,
3265 &odl_used, &odl_comp, &odl_uncomp);
3266 dsl_dir_transfer_space(csa->ohds->ds_dir, cdl_used - odl_used,
3267 DD_USED_HEAD, DD_USED_SNAP, tx);
3268 }
3269
3270 /* swap ds_*_bytes */
3299 dcomp = csa->cds->ds_phys->ds_compressed_bytes + cdl_comp -
3300 (csa->ohds->ds_phys->ds_compressed_bytes + odl_comp);
3301 duncomp = csa->cds->ds_phys->ds_uncompressed_bytes +
3302 cdl_uncomp -
3303 (csa->ohds->ds_phys->ds_uncompressed_bytes + odl_uncomp);
3304
3305 dsl_dir_diduse_space(csa->ohds->ds_dir, DD_USED_HEAD,
3306 dused, dcomp, duncomp, tx);

--- 12 unchanged lines hidden (view full) ---

3319 dsl_deadlist_space_range(&csa->ohds->ds_deadlist,
3320 csa->ohds->ds_dir->dd_origin_txg, UINT64_MAX,
3321 &odl_used, &odl_comp, &odl_uncomp);
3322 dsl_dir_transfer_space(csa->ohds->ds_dir, cdl_used - odl_used,
3323 DD_USED_HEAD, DD_USED_SNAP, tx);
3324 }
3325
3326 /* swap ds_*_bytes */
3271 SWITCH64(csa->ohds->ds_phys->ds_used_bytes,
3272 csa->cds->ds_phys->ds_used_bytes);
3327 SWITCH64(csa->ohds->ds_phys->ds_referenced_bytes,
3328 csa->cds->ds_phys->ds_referenced_bytes);
3273 SWITCH64(csa->ohds->ds_phys->ds_compressed_bytes,
3274 csa->cds->ds_phys->ds_compressed_bytes);
3275 SWITCH64(csa->ohds->ds_phys->ds_uncompressed_bytes,
3276 csa->cds->ds_phys->ds_uncompressed_bytes);
3277 SWITCH64(csa->ohds->ds_phys->ds_unique_bytes,
3278 csa->cds->ds_phys->ds_unique_bytes);
3279
3280 /* apply any parent delta for change in unconsumed refreservation */

--- 112 unchanged lines hidden (view full) ---

3393 return (0);
3394 }
3395 /*
3396 * If they are requesting more space, and our current estimate
3397 * is over quota, they get to try again unless the actual
3398 * on-disk is over quota and there are no pending changes (which
3399 * may free up space for us).
3400 */
3329 SWITCH64(csa->ohds->ds_phys->ds_compressed_bytes,
3330 csa->cds->ds_phys->ds_compressed_bytes);
3331 SWITCH64(csa->ohds->ds_phys->ds_uncompressed_bytes,
3332 csa->cds->ds_phys->ds_uncompressed_bytes);
3333 SWITCH64(csa->ohds->ds_phys->ds_unique_bytes,
3334 csa->cds->ds_phys->ds_unique_bytes);
3335
3336 /* apply any parent delta for change in unconsumed refreservation */

--- 112 unchanged lines hidden (view full) ---

3449 return (0);
3450 }
3451 /*
3452 * If they are requesting more space, and our current estimate
3453 * is over quota, they get to try again unless the actual
3454 * on-disk is over quota and there are no pending changes (which
3455 * may free up space for us).
3456 */
3401 if (ds->ds_phys->ds_used_bytes + inflight >= ds->ds_quota) {
3402 if (inflight > 0 || ds->ds_phys->ds_used_bytes < ds->ds_quota)
3457 if (ds->ds_phys->ds_referenced_bytes + inflight >= ds->ds_quota) {
3458 if (inflight > 0 ||
3459 ds->ds_phys->ds_referenced_bytes < ds->ds_quota)
3403 error = ERESTART;
3404 else
3405 error = EDQUOT;
3406 }
3407 mutex_exit(&ds->ds_lock);
3408
3409 return (error);
3410}

--- 10 unchanged lines hidden (view full) ---

3421 return (ENOTSUP);
3422
3423 if ((err = dsl_prop_predict_sync(ds->ds_dir, psa)) != 0)
3424 return (err);
3425
3426 if (psa->psa_effective_value == 0)
3427 return (0);
3428
3460 error = ERESTART;
3461 else
3462 error = EDQUOT;
3463 }
3464 mutex_exit(&ds->ds_lock);
3465
3466 return (error);
3467}

--- 10 unchanged lines hidden (view full) ---

3478 return (ENOTSUP);
3479
3480 if ((err = dsl_prop_predict_sync(ds->ds_dir, psa)) != 0)
3481 return (err);
3482
3483 if (psa->psa_effective_value == 0)
3484 return (0);
3485
3429 if (psa->psa_effective_value < ds->ds_phys->ds_used_bytes ||
3486 if (psa->psa_effective_value < ds->ds_phys->ds_referenced_bytes ||
3430 psa->psa_effective_value < ds->ds_reserved)
3431 return (ENOSPC);
3432
3433 return (0);
3434}
3435
3436extern void dsl_prop_set_sync(void *, void *, dmu_tx_t *);
3437

--- 5 unchanged lines hidden (view full) ---

3443 uint64_t effective_value = psa->psa_effective_value;
3444
3445 dsl_prop_set_sync(ds, psa, tx);
3446 DSL_PROP_CHECK_PREDICTION(ds->ds_dir, psa);
3447
3448 if (ds->ds_quota != effective_value) {
3449 dmu_buf_will_dirty(ds->ds_dbuf, tx);
3450 ds->ds_quota = effective_value;
3487 psa->psa_effective_value < ds->ds_reserved)
3488 return (ENOSPC);
3489
3490 return (0);
3491}
3492
3493extern void dsl_prop_set_sync(void *, void *, dmu_tx_t *);
3494

--- 5 unchanged lines hidden (view full) ---

3500 uint64_t effective_value = psa->psa_effective_value;
3501
3502 dsl_prop_set_sync(ds, psa, tx);
3503 DSL_PROP_CHECK_PREDICTION(ds->ds_dir, psa);
3504
3505 if (ds->ds_quota != effective_value) {
3506 dmu_buf_will_dirty(ds->ds_dbuf, tx);
3507 ds->ds_quota = effective_value;
3451
3452 spa_history_log_internal(LOG_DS_REFQUOTA,
3453 ds->ds_dir->dd_pool->dp_spa, tx, "%lld dataset = %llu ",
3454 (longlong_t)ds->ds_quota, ds->ds_object);
3455 }
3456}
3457
3458int
3459dsl_dataset_set_quota(const char *dsname, zprop_source_t source, uint64_t quota)
3460{
3461 dsl_dataset_t *ds;
3462 dsl_prop_setarg_t psa;

--- 87 unchanged lines hidden (view full) ---

3550 unique = ds->ds_phys->ds_unique_bytes;
3551 delta = MAX(0, (int64_t)(effective_value - unique)) -
3552 MAX(0, (int64_t)(ds->ds_reserved - unique));
3553 ds->ds_reserved = effective_value;
3554 mutex_exit(&ds->ds_lock);
3555
3556 dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
3557 mutex_exit(&ds->ds_dir->dd_lock);
3508 }
3509}
3510
3511int
3512dsl_dataset_set_quota(const char *dsname, zprop_source_t source, uint64_t quota)
3513{
3514 dsl_dataset_t *ds;
3515 dsl_prop_setarg_t psa;

--- 87 unchanged lines hidden (view full) ---

3603 unique = ds->ds_phys->ds_unique_bytes;
3604 delta = MAX(0, (int64_t)(effective_value - unique)) -
3605 MAX(0, (int64_t)(ds->ds_reserved - unique));
3606 ds->ds_reserved = effective_value;
3607 mutex_exit(&ds->ds_lock);
3608
3609 dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
3610 mutex_exit(&ds->ds_dir->dd_lock);
3558
3559 spa_history_log_internal(LOG_DS_REFRESERV,
3560 ds->ds_dir->dd_pool->dp_spa, tx, "%lld dataset = %llu",
3561 (longlong_t)effective_value, ds->ds_object);
3562}
3563
3564int
3565dsl_dataset_set_reservation(const char *dsname, zprop_source_t source,
3566 uint64_t reservation)
3567{
3568 dsl_dataset_t *ds;
3569 dsl_prop_setarg_t psa;

--- 332 unchanged lines hidden (view full) ---

3902 mutex_enter(&ds->ds_lock);
3903 ds->ds_userrefs--;
3904 refs = ds->ds_userrefs;
3905 mutex_exit(&ds->ds_lock);
3906 error = dsl_pool_user_release(dp, ds->ds_object, ra->htag, tx);
3907 VERIFY(error == 0 || error == ENOENT);
3908 zapobj = ds->ds_phys->ds_userrefs_obj;
3909 VERIFY(0 == zap_remove(mos, zapobj, ra->htag, tx));
3611}
3612
3613int
3614dsl_dataset_set_reservation(const char *dsname, zprop_source_t source,
3615 uint64_t reservation)
3616{
3617 dsl_dataset_t *ds;
3618 dsl_prop_setarg_t psa;

--- 332 unchanged lines hidden (view full) ---

3951 mutex_enter(&ds->ds_lock);
3952 ds->ds_userrefs--;
3953 refs = ds->ds_userrefs;
3954 mutex_exit(&ds->ds_lock);
3955 error = dsl_pool_user_release(dp, ds->ds_object, ra->htag, tx);
3956 VERIFY(error == 0 || error == ENOENT);
3957 zapobj = ds->ds_phys->ds_userrefs_obj;
3958 VERIFY(0 == zap_remove(mos, zapobj, ra->htag, tx));
3959
3960 spa_history_log_internal(LOG_DS_USER_RELEASE,
3961 dp->dp_spa, tx, "<%s> %lld dataset = %llu",
3962 ra->htag, (longlong_t)refs, dsobj);
3963
3910 if (ds->ds_userrefs == 0 && ds->ds_phys->ds_num_children == 1 &&
3911 DS_IS_DEFER_DESTROY(ds)) {
3912 struct dsl_ds_destroyarg dsda = {0};
3913
3914 ASSERT(ra->own);
3915 dsda.ds = ds;
3916 dsda.releasing = B_TRUE;
3917 /* We already did the destroy_check */
3918 dsl_dataset_destroy_sync(&dsda, tag, tx);
3919 }
3964 if (ds->ds_userrefs == 0 && ds->ds_phys->ds_num_children == 1 &&
3965 DS_IS_DEFER_DESTROY(ds)) {
3966 struct dsl_ds_destroyarg dsda = {0};
3967
3968 ASSERT(ra->own);
3969 dsda.ds = ds;
3970 dsda.releasing = B_TRUE;
3971 /* We already did the destroy_check */
3972 dsl_dataset_destroy_sync(&dsda, tag, tx);
3973 }
3920
3921 spa_history_log_internal(LOG_DS_USER_RELEASE,
3922 dp->dp_spa, tx, "<%s> %lld dataset = %llu",
3923 ra->htag, (longlong_t)refs, dsobj);
3924}
3925
3926static int
3927dsl_dataset_user_release_one(const char *dsname, void *arg)
3928{
3929 struct dsl_ds_holdarg *ha = arg;
3930 struct dsl_ds_releasearg *ra;
3931 dsl_dataset_t *ds;

--- 243 unchanged lines hidden (view full) ---

4175dsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new,
4176 uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
4177{
4178 int err = 0;
4179 uint64_t snapobj;
4180 dsl_pool_t *dp = new->ds_dir->dd_pool;
4181
4182 *usedp = 0;
3974}
3975
3976static int
3977dsl_dataset_user_release_one(const char *dsname, void *arg)
3978{
3979 struct dsl_ds_holdarg *ha = arg;
3980 struct dsl_ds_releasearg *ra;
3981 dsl_dataset_t *ds;

--- 243 unchanged lines hidden (view full) ---

4225dsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new,
4226 uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
4227{
4228 int err = 0;
4229 uint64_t snapobj;
4230 dsl_pool_t *dp = new->ds_dir->dd_pool;
4231
4232 *usedp = 0;
4183 *usedp += new->ds_phys->ds_used_bytes;
4184 *usedp -= oldsnap->ds_phys->ds_used_bytes;
4233 *usedp += new->ds_phys->ds_referenced_bytes;
4234 *usedp -= oldsnap->ds_phys->ds_referenced_bytes;
4185
4186 *compp = 0;
4187 *compp += new->ds_phys->ds_compressed_bytes;
4188 *compp -= oldsnap->ds_phys->ds_compressed_bytes;
4189
4190 *uncompp = 0;
4191 *uncompp += new->ds_phys->ds_uncompressed_bytes;
4192 *uncompp -= oldsnap->ds_phys->ds_uncompressed_bytes;
4193
4194 rw_enter(&dp->dp_config_rwlock, RW_READER);
4195 snapobj = new->ds_object;
4196 while (snapobj != oldsnap->ds_object) {
4197 dsl_dataset_t *snap;
4198 uint64_t used, comp, uncomp;
4199
4235
4236 *compp = 0;
4237 *compp += new->ds_phys->ds_compressed_bytes;
4238 *compp -= oldsnap->ds_phys->ds_compressed_bytes;
4239
4240 *uncompp = 0;
4241 *uncompp += new->ds_phys->ds_uncompressed_bytes;
4242 *uncompp -= oldsnap->ds_phys->ds_uncompressed_bytes;
4243
4244 rw_enter(&dp->dp_config_rwlock, RW_READER);
4245 snapobj = new->ds_object;
4246 while (snapobj != oldsnap->ds_object) {
4247 dsl_dataset_t *snap;
4248 uint64_t used, comp, uncomp;
4249
4200 err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &snap);
4201 if (err != 0)
4202 break;
4250 if (snapobj == new->ds_object) {
4251 snap = new;
4252 } else {
4253 err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &snap);
4254 if (err != 0)
4255 break;
4256 }
4203
4204 if (snap->ds_phys->ds_prev_snap_txg ==
4205 oldsnap->ds_phys->ds_creation_txg) {
4206 /*
4207 * The blocks in the deadlist can not be born after
4208 * ds_prev_snap_txg, so get the whole deadlist space,
4209 * which is more efficient (especially for old-format
4210 * deadlists). Unfortunately the deadlist code

--- 12 unchanged lines hidden (view full) ---

4223 *uncompp += uncomp;
4224
4225 /*
4226 * If we get to the beginning of the chain of snapshots
4227 * (ds_prev_snap_obj == 0) before oldsnap, then oldsnap
4228 * was not a snapshot of/before new.
4229 */
4230 snapobj = snap->ds_phys->ds_prev_snap_obj;
4257
4258 if (snap->ds_phys->ds_prev_snap_txg ==
4259 oldsnap->ds_phys->ds_creation_txg) {
4260 /*
4261 * The blocks in the deadlist can not be born after
4262 * ds_prev_snap_txg, so get the whole deadlist space,
4263 * which is more efficient (especially for old-format
4264 * deadlists). Unfortunately the deadlist code

--- 12 unchanged lines hidden (view full) ---

4277 *uncompp += uncomp;
4278
4279 /*
4280 * If we get to the beginning of the chain of snapshots
4281 * (ds_prev_snap_obj == 0) before oldsnap, then oldsnap
4282 * was not a snapshot of/before new.
4283 */
4284 snapobj = snap->ds_phys->ds_prev_snap_obj;
4231 dsl_dataset_rele(snap, FTAG);
4285 if (snap != new)
4286 dsl_dataset_rele(snap, FTAG);
4232 if (snapobj == 0) {
4233 err = EINVAL;
4234 break;
4235 }
4236
4237 }
4238 rw_exit(&dp->dp_config_rwlock);
4239 return (err);

--- 64 unchanged lines hidden ---
4287 if (snapobj == 0) {
4288 err = EINVAL;
4289 break;
4290 }
4291
4292 }
4293 rw_exit(&dp->dp_config_rwlock);
4294 return (err);

--- 64 unchanged lines hidden ---