annotate usr/src/uts/common/fs/zfs/dsl_dataset.c @ 5094:71a3e95fb9e2

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