Mercurial > illumos > illumos-gate
annotate usr/src/uts/common/fs/zfs/dsl_dataset.c @ 7385:f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
6734875 assertion failed: list_head(&osi->os_meta_dnode->dn_dbufs) == 0L
6728399 [f]truncate(2) to non-zero offset broken on ZFS for files < max-blocksize
6730750 pool shows disk space in used but no related files/dirs
6737329 dmu_offset_next() does not find holes
author | Mark Maybee <Mark.Maybee@Sun.COM> |
---|---|
date | Thu, 21 Aug 2008 14:27:33 -0600 |
parents | 3992f9a413c2 |
children | 6d408f0a5fbd |
rev | line source |
---|---|
789 | 1 /* |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
1544 | 5 * Common Development and Distribution License (the "License"). |
6 * You may not use this file except in compliance with the License. | |
789 | 7 * |
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 * or http://www.opensolaris.org/os/licensing. | |
10 * See the License for the specific language governing permissions | |
11 * and limitations under the License. | |
12 * | |
13 * When distributing Covered Code, include this CDDL HEADER in each | |
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 * If applicable, add the following below this CDDL HEADER, with the | |
16 * fields enclosed by brackets "[]" replaced with your own identifying | |
17 * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 * | |
19 * CDDL HEADER END | |
20 */ | |
21 /* | |
5831
48655d6b290b
6630761 In sub-filesystem, available space is less than refreservation space
ck153898
parents:
5712
diff
changeset
|
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
789 | 23 * Use is subject to license terms. |
24 */ | |
25 | |
26 #include <sys/dmu_objset.h> | |
27 #include <sys/dsl_dataset.h> | |
28 #include <sys/dsl_dir.h> | |
2082 | 29 #include <sys/dsl_prop.h> |
2199 | 30 #include <sys/dsl_synctask.h> |
789 | 31 #include <sys/dmu_traverse.h> |
32 #include <sys/dmu_tx.h> | |
33 #include <sys/arc.h> | |
34 #include <sys/zio.h> | |
35 #include <sys/zap.h> | |
36 #include <sys/unique.h> | |
37 #include <sys/zfs_context.h> | |
4007 | 38 #include <sys/zfs_ioctl.h> |
4543 | 39 #include <sys/spa.h> |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
40 #include <sys/zfs_znode.h> |
4543 | 41 #include <sys/sunddi.h> |
789 | 42 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
43 static char *dsl_reaper = "the grim reaper"; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
44 |
2199 | 45 static dsl_checkfunc_t dsl_dataset_destroy_begin_check; |
46 static dsl_syncfunc_t dsl_dataset_destroy_begin_sync; | |
47 static dsl_checkfunc_t dsl_dataset_rollback_check; | |
48 static dsl_syncfunc_t dsl_dataset_rollback_sync; | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
49 static dsl_syncfunc_t dsl_dataset_set_reservation_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 | 52 |
53 #define DSL_DEADLIST_BLOCKSIZE SPA_MAXBLOCKSIZE | |
54 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
55 #define DSL_DATASET_IS_DESTROYED(ds) ((ds)->ds_owner == dsl_reaper) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
56 |
789 | 57 |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
58 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
59 * Figure out how much of this delta should be propogated to the dsl_dir |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
60 * layer. If there's a refreservation, that space has already been |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
61 * partially accounted for in our ancestors. |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
62 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
63 static int64_t |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
64 parent_delta(dsl_dataset_t *ds, int64_t delta) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
65 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
66 uint64_t old_bytes, new_bytes; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
67 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
68 if (ds->ds_reserved == 0) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
69 return (delta); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
70 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
71 old_bytes = MAX(ds->ds_phys->ds_unique_bytes, ds->ds_reserved); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
72 new_bytes = MAX(ds->ds_phys->ds_unique_bytes + delta, ds->ds_reserved); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
73 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
74 ASSERT3U(ABS((int64_t)(new_bytes - old_bytes)), <=, ABS(delta)); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
75 return (new_bytes - old_bytes); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
76 } |
789 | 77 |
78 void | |
79 dsl_dataset_block_born(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx) | |
80 { | |
2082 | 81 int used = bp_get_dasize(tx->tx_pool->dp_spa, bp); |
789 | 82 int compressed = BP_GET_PSIZE(bp); |
83 int uncompressed = BP_GET_UCSIZE(bp); | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
84 int64_t delta; |
789 | 85 |
86 dprintf_bp(bp, "born, ds=%p\n", ds); | |
87 | |
88 ASSERT(dmu_tx_is_syncing(tx)); | |
89 /* It could have been compressed away to nothing */ | |
90 if (BP_IS_HOLE(bp)) | |
91 return; | |
92 ASSERT(BP_GET_TYPE(bp) != DMU_OT_NONE); | |
93 ASSERT3U(BP_GET_TYPE(bp), <, DMU_OT_NUMTYPES); | |
94 if (ds == NULL) { | |
95 /* | |
96 * Account for the meta-objset space in its placeholder | |
97 * dsl_dir. | |
98 */ | |
99 ASSERT3U(compressed, ==, uncompressed); /* it's all metadata */ | |
100 dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, | |
101 used, compressed, uncompressed, tx); | |
102 dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx); | |
103 return; | |
104 } | |
105 dmu_buf_will_dirty(ds->ds_dbuf, tx); | |
106 mutex_enter(&ds->ds_lock); | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
107 delta = parent_delta(ds, used); |
789 | 108 ds->ds_phys->ds_used_bytes += used; |
109 ds->ds_phys->ds_compressed_bytes += compressed; | |
110 ds->ds_phys->ds_uncompressed_bytes += uncompressed; | |
111 ds->ds_phys->ds_unique_bytes += used; | |
112 mutex_exit(&ds->ds_lock); | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
113 dsl_dir_diduse_space(ds->ds_dir, delta, compressed, uncompressed, tx); |
789 | 114 } |
115 | |
6992 | 116 int |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
117 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
|
118 dmu_tx_t *tx) |
789 | 119 { |
2082 | 120 int used = bp_get_dasize(tx->tx_pool->dp_spa, bp); |
789 | 121 int compressed = BP_GET_PSIZE(bp); |
122 int uncompressed = BP_GET_UCSIZE(bp); | |
123 | |
124 ASSERT(dmu_tx_is_syncing(tx)); | |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
125 /* No block pointer => nothing to free */ |
789 | 126 if (BP_IS_HOLE(bp)) |
6992 | 127 return (0); |
789 | 128 |
129 ASSERT(used > 0); | |
130 if (ds == NULL) { | |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
131 int err; |
789 | 132 /* |
133 * Account for the meta-objset space in its placeholder | |
134 * dataset. | |
135 */ | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
136 err = dsl_free(pio, tx->tx_pool, |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
137 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
|
138 ASSERT(err == 0); |
789 | 139 |
140 dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, | |
141 -used, -compressed, -uncompressed, tx); | |
142 dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx); | |
6992 | 143 return (used); |
789 | 144 } |
145 ASSERT3P(tx->tx_pool, ==, ds->ds_dir->dd_pool); | |
146 | |
147 dmu_buf_will_dirty(ds->ds_dbuf, tx); | |
148 | |
149 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
|
150 int err; |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
151 int64_t delta; |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
152 |
789 | 153 dprintf_bp(bp, "freeing: %s", ""); |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
154 err = dsl_free(pio, tx->tx_pool, |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
155 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
|
156 ASSERT(err == 0); |
789 | 157 |
158 mutex_enter(&ds->ds_lock); | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
159 ASSERT(ds->ds_phys->ds_unique_bytes >= used || |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
160 !DS_UNIQUE_IS_ACCURATE(ds)); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
161 delta = parent_delta(ds, -used); |
789 | 162 ds->ds_phys->ds_unique_bytes -= used; |
163 mutex_exit(&ds->ds_lock); | |
164 dsl_dir_diduse_space(ds->ds_dir, | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
165 delta, -compressed, -uncompressed, tx); |
789 | 166 } else { |
167 dprintf_bp(bp, "putting on dead list: %s", ""); | |
1544 | 168 VERIFY(0 == bplist_enqueue(&ds->ds_deadlist, bp, tx)); |
5712
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
169 ASSERT3U(ds->ds_prev->ds_object, ==, |
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
170 ds->ds_phys->ds_prev_snap_obj); |
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
171 ASSERT(ds->ds_prev->ds_phys->ds_num_children > 0); |
789 | 172 /* if (bp->blk_birth > prev prev snap txg) prev unique += bs */ |
5712
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
173 if (ds->ds_prev->ds_phys->ds_next_snap_obj == |
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
174 ds->ds_object && bp->blk_birth > |
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
175 ds->ds_prev->ds_phys->ds_prev_snap_txg) { |
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
176 dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx); |
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
177 mutex_enter(&ds->ds_prev->ds_lock); |
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
178 ds->ds_prev->ds_phys->ds_unique_bytes += used; |
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
179 mutex_exit(&ds->ds_prev->ds_lock); |
789 | 180 } |
181 } | |
182 mutex_enter(&ds->ds_lock); | |
183 ASSERT3U(ds->ds_phys->ds_used_bytes, >=, used); | |
184 ds->ds_phys->ds_used_bytes -= used; | |
185 ASSERT3U(ds->ds_phys->ds_compressed_bytes, >=, compressed); | |
186 ds->ds_phys->ds_compressed_bytes -= compressed; | |
187 ASSERT3U(ds->ds_phys->ds_uncompressed_bytes, >=, uncompressed); | |
188 ds->ds_phys->ds_uncompressed_bytes -= uncompressed; | |
189 mutex_exit(&ds->ds_lock); | |
6992 | 190 |
191 return (used); | |
789 | 192 } |
193 | |
1544 | 194 uint64_t |
195 dsl_dataset_prev_snap_txg(dsl_dataset_t *ds) | |
789 | 196 { |
2885 | 197 uint64_t trysnap = 0; |
198 | |
789 | 199 if (ds == NULL) |
1544 | 200 return (0); |
789 | 201 /* |
202 * The snapshot creation could fail, but that would cause an | |
203 * incorrect FALSE return, which would only result in an | |
204 * overestimation of the amount of space that an operation would | |
205 * consume, which is OK. | |
206 * | |
207 * There's also a small window where we could miss a pending | |
208 * snapshot, because we could set the sync task in the quiescing | |
209 * phase. So this should only be used as a guess. | |
210 */ | |
2885 | 211 if (ds->ds_trysnap_txg > |
212 spa_last_synced_txg(ds->ds_dir->dd_pool->dp_spa)) | |
213 trysnap = ds->ds_trysnap_txg; | |
214 return (MAX(ds->ds_phys->ds_prev_snap_txg, trysnap)); | |
1544 | 215 } |
216 | |
217 int | |
218 dsl_dataset_block_freeable(dsl_dataset_t *ds, uint64_t blk_birth) | |
219 { | |
220 return (blk_birth > dsl_dataset_prev_snap_txg(ds)); | |
789 | 221 } |
222 | |
223 /* ARGSUSED */ | |
224 static void | |
225 dsl_dataset_evict(dmu_buf_t *db, void *dsv) | |
226 { | |
227 dsl_dataset_t *ds = dsv; | |
228 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
229 ASSERT(ds->ds_owner == NULL || DSL_DATASET_IS_DESTROYED(ds)); |
789 | 230 |
231 dprintf_ds(ds, "evicting %s\n", ""); | |
232 | |
4787 | 233 unique_remove(ds->ds_fsid_guid); |
789 | 234 |
235 if (ds->ds_user_ptr != NULL) | |
236 ds->ds_user_evict_func(ds, ds->ds_user_ptr); | |
237 | |
238 if (ds->ds_prev) { | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
239 dsl_dataset_drop_ref(ds->ds_prev, ds); |
789 | 240 ds->ds_prev = NULL; |
241 } | |
242 | |
243 bplist_close(&ds->ds_deadlist); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
244 if (ds->ds_dir) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
245 dsl_dir_close(ds->ds_dir, ds); |
789 | 246 |
4787 | 247 ASSERT(!list_link_active(&ds->ds_synced_link)); |
789 | 248 |
2856 | 249 mutex_destroy(&ds->ds_lock); |
4787 | 250 mutex_destroy(&ds->ds_opening_lock); |
2856 | 251 mutex_destroy(&ds->ds_deadlist.bpl_lock); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
252 rw_destroy(&ds->ds_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
253 cv_destroy(&ds->ds_exclusive_cv); |
2856 | 254 |
789 | 255 kmem_free(ds, sizeof (dsl_dataset_t)); |
256 } | |
257 | |
1544 | 258 static int |
789 | 259 dsl_dataset_get_snapname(dsl_dataset_t *ds) |
260 { | |
261 dsl_dataset_phys_t *headphys; | |
262 int err; | |
263 dmu_buf_t *headdbuf; | |
264 dsl_pool_t *dp = ds->ds_dir->dd_pool; | |
265 objset_t *mos = dp->dp_meta_objset; | |
266 | |
267 if (ds->ds_snapname[0]) | |
1544 | 268 return (0); |
789 | 269 if (ds->ds_phys->ds_next_snap_obj == 0) |
1544 | 270 return (0); |
789 | 271 |
1544 | 272 err = dmu_bonus_hold(mos, ds->ds_dir->dd_phys->dd_head_dataset_obj, |
273 FTAG, &headdbuf); | |
274 if (err) | |
275 return (err); | |
789 | 276 headphys = headdbuf->db_data; |
277 err = zap_value_search(dp->dp_meta_objset, | |
4577 | 278 headphys->ds_snapnames_zapobj, ds->ds_object, 0, ds->ds_snapname); |
1544 | 279 dmu_buf_rele(headdbuf, FTAG); |
280 return (err); | |
789 | 281 } |
282 | |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
283 static int |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
284 dsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name, uint64_t *value) |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
285 { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
286 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
287 uint64_t snapobj = ds->ds_phys->ds_snapnames_zapobj; |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
288 matchtype_t mt; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
289 int err; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
290 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
291 if (ds->ds_phys->ds_flags & DS_FLAG_CI_DATASET) |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
292 mt = MT_FIRST; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
293 else |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
294 mt = MT_EXACT; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
295 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
296 err = zap_lookup_norm(mos, snapobj, name, 8, 1, |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
297 value, mt, NULL, 0, NULL); |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
298 if (err == ENOTSUP && mt == MT_FIRST) |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
299 err = zap_lookup(mos, snapobj, name, 8, 1, value); |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
300 return (err); |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
301 } |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
302 |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
303 static int |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
304 dsl_dataset_snap_remove(dsl_dataset_t *ds, char *name, dmu_tx_t *tx) |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
305 { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
306 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
307 uint64_t snapobj = ds->ds_phys->ds_snapnames_zapobj; |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
308 matchtype_t mt; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
309 int err; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
310 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
311 if (ds->ds_phys->ds_flags & DS_FLAG_CI_DATASET) |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
312 mt = MT_FIRST; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
313 else |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
314 mt = MT_EXACT; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
315 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
316 err = zap_remove_norm(mos, snapobj, name, mt, tx); |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
317 if (err == ENOTSUP && mt == MT_FIRST) |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
318 err = zap_remove(mos, snapobj, name, tx); |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
319 return (err); |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
320 } |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
321 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
322 static int |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
323 dsl_dataset_get_ref(dsl_pool_t *dp, uint64_t dsobj, void *tag, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
324 dsl_dataset_t **dsp) |
789 | 325 { |
326 objset_t *mos = dp->dp_meta_objset; | |
327 dmu_buf_t *dbuf; | |
328 dsl_dataset_t *ds; | |
1544 | 329 int err; |
789 | 330 |
331 ASSERT(RW_LOCK_HELD(&dp->dp_config_rwlock) || | |
332 dsl_pool_sync_context(dp)); | |
333 | |
1544 | 334 err = dmu_bonus_hold(mos, dsobj, tag, &dbuf); |
335 if (err) | |
336 return (err); | |
789 | 337 ds = dmu_buf_get_user(dbuf); |
338 if (ds == NULL) { | |
339 dsl_dataset_t *winner; | |
340 | |
341 ds = kmem_zalloc(sizeof (dsl_dataset_t), KM_SLEEP); | |
342 ds->ds_dbuf = dbuf; | |
343 ds->ds_object = dsobj; | |
344 ds->ds_phys = dbuf->db_data; | |
345 | |
2856 | 346 mutex_init(&ds->ds_lock, NULL, MUTEX_DEFAULT, NULL); |
4787 | 347 mutex_init(&ds->ds_opening_lock, NULL, MUTEX_DEFAULT, NULL); |
2856 | 348 mutex_init(&ds->ds_deadlist.bpl_lock, NULL, MUTEX_DEFAULT, |
349 NULL); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
350 rw_init(&ds->ds_rwlock, 0, 0, 0); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
351 cv_init(&ds->ds_exclusive_cv, NULL, CV_DEFAULT, NULL); |
2856 | 352 |
1544 | 353 err = bplist_open(&ds->ds_deadlist, |
789 | 354 mos, ds->ds_phys->ds_deadlist_obj); |
1544 | 355 if (err == 0) { |
356 err = dsl_dir_open_obj(dp, | |
357 ds->ds_phys->ds_dir_obj, NULL, ds, &ds->ds_dir); | |
358 } | |
359 if (err) { | |
360 /* | |
361 * we don't really need to close the blist if we | |
362 * just opened it. | |
363 */ | |
2856 | 364 mutex_destroy(&ds->ds_lock); |
4787 | 365 mutex_destroy(&ds->ds_opening_lock); |
2856 | 366 mutex_destroy(&ds->ds_deadlist.bpl_lock); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
367 rw_destroy(&ds->ds_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
368 cv_destroy(&ds->ds_exclusive_cv); |
1544 | 369 kmem_free(ds, sizeof (dsl_dataset_t)); |
370 dmu_buf_rele(dbuf, tag); | |
371 return (err); | |
372 } | |
789 | 373 |
374 if (ds->ds_dir->dd_phys->dd_head_dataset_obj == dsobj) { | |
375 ds->ds_snapname[0] = '\0'; | |
376 if (ds->ds_phys->ds_prev_snap_obj) { | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
377 err = dsl_dataset_get_ref(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
378 ds->ds_phys->ds_prev_snap_obj, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
379 ds, &ds->ds_prev); |
789 | 380 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
381 } else if (zfs_flags & ZFS_DEBUG_SNAPNAMES) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
382 err = dsl_dataset_get_snapname(ds); |
789 | 383 } |
384 | |
5475
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
385 if (!dsl_dataset_is_snapshot(ds)) { |
5569
d3caac36d311
6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD
ck153898
parents:
5518
diff
changeset
|
386 /* |
d3caac36d311
6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD
ck153898
parents:
5518
diff
changeset
|
387 * In sync context, we're called with either no lock |
d3caac36d311
6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD
ck153898
parents:
5518
diff
changeset
|
388 * or with the write lock. If we're not syncing, |
d3caac36d311
6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD
ck153898
parents:
5518
diff
changeset
|
389 * we're always called with the read lock held. |
d3caac36d311
6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD
ck153898
parents:
5518
diff
changeset
|
390 */ |
5475
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
391 boolean_t need_lock = |
5569
d3caac36d311
6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD
ck153898
parents:
5518
diff
changeset
|
392 !RW_WRITE_HELD(&dp->dp_config_rwlock) && |
d3caac36d311
6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD
ck153898
parents:
5518
diff
changeset
|
393 dsl_pool_sync_context(dp); |
5475
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
394 |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
395 if (need_lock) |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
396 rw_enter(&dp->dp_config_rwlock, RW_READER); |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
397 |
7265 | 398 err = dsl_prop_get_ds(ds, |
5475
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
399 "refreservation", sizeof (uint64_t), 1, |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
400 &ds->ds_reserved, NULL); |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
401 if (err == 0) { |
7265 | 402 err = dsl_prop_get_ds(ds, |
5475
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
403 "refquota", sizeof (uint64_t), 1, |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
404 &ds->ds_quota, NULL); |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
405 } |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
406 |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
407 if (need_lock) |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
408 rw_exit(&dp->dp_config_rwlock); |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
409 } else { |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
410 ds->ds_reserved = ds->ds_quota = 0; |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
411 } |
e140313199cc
6626338 assertion failed: 0 == dsl_prop_get_ds_locked(ds->ds_dir, "refreservation", sizeof (uint64_t), 1, &d
ck153898
parents:
5446
diff
changeset
|
412 |
1544 | 413 if (err == 0) { |
414 winner = dmu_buf_set_user_ie(dbuf, ds, &ds->ds_phys, | |
415 dsl_dataset_evict); | |
416 } | |
417 if (err || winner) { | |
789 | 418 bplist_close(&ds->ds_deadlist); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
419 if (ds->ds_prev) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
420 dsl_dataset_drop_ref(ds->ds_prev, ds); |
789 | 421 dsl_dir_close(ds->ds_dir, ds); |
2856 | 422 mutex_destroy(&ds->ds_lock); |
4787 | 423 mutex_destroy(&ds->ds_opening_lock); |
2856 | 424 mutex_destroy(&ds->ds_deadlist.bpl_lock); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
425 rw_destroy(&ds->ds_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
426 cv_destroy(&ds->ds_exclusive_cv); |
789 | 427 kmem_free(ds, sizeof (dsl_dataset_t)); |
1544 | 428 if (err) { |
429 dmu_buf_rele(dbuf, tag); | |
430 return (err); | |
431 } | |
789 | 432 ds = winner; |
433 } else { | |
4787 | 434 ds->ds_fsid_guid = |
789 | 435 unique_insert(ds->ds_phys->ds_fsid_guid); |
436 } | |
437 } | |
438 ASSERT3P(ds->ds_dbuf, ==, dbuf); | |
439 ASSERT3P(ds->ds_phys, ==, dbuf->db_data); | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
440 ASSERT(ds->ds_phys->ds_prev_snap_obj != 0 || |
7061
524fec1acf1c
6723703 zpool upgrade -> assertion failed: ds->ds_phys->ds_prev_snap_obj != 0 || ...
ahrens
parents:
7046
diff
changeset
|
441 spa_version(dp->dp_spa) < SPA_VERSION_ORIGIN || |
7077
a63bdc0b8352
6724675 assertion failed in dsl_dataset_get_ref(): ds->ds_phys->ds_prev_snap_obj != 0 ...
ahrens
parents:
7061
diff
changeset
|
442 dp->dp_origin_snap == NULL || ds == dp->dp_origin_snap); |
789 | 443 mutex_enter(&ds->ds_lock); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
444 if (!dsl_pool_sync_context(dp) && DSL_DATASET_IS_DESTROYED(ds)) { |
789 | 445 mutex_exit(&ds->ds_lock); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
446 dmu_buf_rele(ds->ds_dbuf, tag); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
447 return (ENOENT); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
448 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
449 mutex_exit(&ds->ds_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
450 *dsp = ds; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
451 return (0); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
452 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
453 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
454 static int |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
455 dsl_dataset_hold_ref(dsl_dataset_t *ds, void *tag) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
456 { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
457 dsl_pool_t *dp = ds->ds_dir->dd_pool; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
458 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
459 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
460 * In syncing context we don't want the rwlock lock: there |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
461 * may be an existing writer waiting for sync phase to |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
462 * finish. We don't need to worry about such writers, since |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
463 * sync phase is single-threaded, so the writer can't be |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
464 * doing anything while we are active. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
465 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
466 if (dsl_pool_sync_context(dp)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
467 ASSERT(!DSL_DATASET_IS_DESTROYED(ds)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
468 return (0); |
789 | 469 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
470 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
471 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
472 * Normal users will hold the ds_rwlock as a READER until they |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
473 * are finished (i.e., call dsl_dataset_rele()). "Owners" will |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
474 * drop their READER lock after they set the ds_owner field. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
475 * |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
476 * If the dataset is being destroyed, the destroy thread will |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
477 * obtain a WRITER lock for exclusive access after it's done its |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
478 * open-context work and then change the ds_owner to |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
479 * dsl_reaper once destruction is assured. So threads |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
480 * may block here temporarily, until the "destructability" of |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
481 * the dataset is determined. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
482 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
483 ASSERT(!RW_WRITE_HELD(&dp->dp_config_rwlock)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
484 mutex_enter(&ds->ds_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
485 while (!rw_tryenter(&ds->ds_rwlock, RW_READER)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
486 rw_exit(&dp->dp_config_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
487 cv_wait(&ds->ds_exclusive_cv, &ds->ds_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
488 if (DSL_DATASET_IS_DESTROYED(ds)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
489 mutex_exit(&ds->ds_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
490 dsl_dataset_drop_ref(ds, tag); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
491 rw_enter(&dp->dp_config_rwlock, RW_READER); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
492 return (ENOENT); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
493 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
494 rw_enter(&dp->dp_config_rwlock, RW_READER); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
495 } |
789 | 496 mutex_exit(&ds->ds_lock); |
1544 | 497 return (0); |
789 | 498 } |
499 | |
500 int | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
501 dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
502 dsl_dataset_t **dsp) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
503 { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
504 int err = dsl_dataset_get_ref(dp, dsobj, tag, dsp); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
505 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
506 if (err) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
507 return (err); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
508 return (dsl_dataset_hold_ref(*dsp, tag)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
509 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
510 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
511 int |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
512 dsl_dataset_own_obj(dsl_pool_t *dp, uint64_t dsobj, int flags, void *owner, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
513 dsl_dataset_t **dsp) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
514 { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
515 int err = dsl_dataset_hold_obj(dp, dsobj, owner, dsp); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
516 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
517 ASSERT(DS_MODE_TYPE(flags) != DS_MODE_USER); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
518 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
519 if (err) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
520 return (err); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
521 if (!dsl_dataset_tryown(*dsp, DS_MODE_IS_INCONSISTENT(flags), owner)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
522 dsl_dataset_rele(*dsp, owner); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
523 return (EBUSY); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
524 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
525 return (0); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
526 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
527 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
528 int |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
529 dsl_dataset_hold(const char *name, void *tag, dsl_dataset_t **dsp) |
789 | 530 { |
531 dsl_dir_t *dd; | |
532 dsl_pool_t *dp; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
533 const char *snapname; |
789 | 534 uint64_t obj; |
535 int err = 0; | |
536 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
537 err = dsl_dir_open_spa(NULL, name, FTAG, &dd, &snapname); |
1544 | 538 if (err) |
539 return (err); | |
789 | 540 |
541 dp = dd->dd_pool; | |
542 obj = dd->dd_phys->dd_head_dataset_obj; | |
543 rw_enter(&dp->dp_config_rwlock, RW_READER); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
544 if (obj) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
545 err = dsl_dataset_get_ref(dp, obj, tag, dsp); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
546 else |
789 | 547 err = ENOENT; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
548 if (err) |
789 | 549 goto out; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
550 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
551 err = dsl_dataset_hold_ref(*dsp, tag); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
552 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
553 /* we may be looking for a snapshot */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
554 if (err == 0 && snapname != NULL) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
555 dsl_dataset_t *ds = NULL; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
556 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
557 if (*snapname++ != '@') { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
558 dsl_dataset_rele(*dsp, tag); |
789 | 559 err = ENOENT; |
560 goto out; | |
561 } | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
562 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
563 dprintf("looking for snapshot '%s'\n", snapname); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
564 err = dsl_dataset_snap_lookup(*dsp, snapname, &obj); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
565 if (err == 0) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
566 err = dsl_dataset_get_ref(dp, obj, tag, &ds); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
567 dsl_dataset_rele(*dsp, tag); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
568 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
569 ASSERT3U((err == 0), ==, (ds != NULL)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
570 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
571 if (ds) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
572 mutex_enter(&ds->ds_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
573 if (ds->ds_snapname[0] == 0) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
574 (void) strlcpy(ds->ds_snapname, snapname, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
575 sizeof (ds->ds_snapname)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
576 mutex_exit(&ds->ds_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
577 err = dsl_dataset_hold_ref(ds, tag); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
578 *dsp = err ? NULL : ds; |
789 | 579 } |
580 } | |
581 out: | |
582 rw_exit(&dp->dp_config_rwlock); | |
583 dsl_dir_close(dd, FTAG); | |
584 return (err); | |
585 } | |
586 | |
587 int | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
588 dsl_dataset_own(const char *name, int flags, void *owner, dsl_dataset_t **dsp) |
789 | 589 { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
590 int err = dsl_dataset_hold(name, owner, dsp); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
591 if (err) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
592 return (err); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
593 if ((*dsp)->ds_phys->ds_num_children > 0 && |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
594 !DS_MODE_IS_READONLY(flags)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
595 dsl_dataset_rele(*dsp, owner); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
596 return (EROFS); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
597 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
598 if (!dsl_dataset_tryown(*dsp, DS_MODE_IS_INCONSISTENT(flags), owner)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
599 dsl_dataset_rele(*dsp, owner); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
600 return (EBUSY); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
601 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
602 return (0); |
789 | 603 } |
604 | |
605 void | |
606 dsl_dataset_name(dsl_dataset_t *ds, char *name) | |
607 { | |
608 if (ds == NULL) { | |
609 (void) strcpy(name, "mos"); | |
610 } else { | |
611 dsl_dir_name(ds->ds_dir, name); | |
1544 | 612 VERIFY(0 == dsl_dataset_get_snapname(ds)); |
789 | 613 if (ds->ds_snapname[0]) { |
614 (void) strcat(name, "@"); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
615 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
616 * We use a "recursive" mutex so that we |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
617 * can call dprintf_ds() with ds_lock held. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
618 */ |
789 | 619 if (!MUTEX_HELD(&ds->ds_lock)) { |
620 mutex_enter(&ds->ds_lock); | |
621 (void) strcat(name, ds->ds_snapname); | |
622 mutex_exit(&ds->ds_lock); | |
623 } else { | |
624 (void) strcat(name, ds->ds_snapname); | |
625 } | |
626 } | |
627 } | |
628 } | |
629 | |
3978
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
630 static int |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
631 dsl_dataset_namelen(dsl_dataset_t *ds) |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
632 { |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
633 int result; |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
634 |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
635 if (ds == NULL) { |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
636 result = 3; /* "mos" */ |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
637 } else { |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
638 result = dsl_dir_namelen(ds->ds_dir); |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
639 VERIFY(0 == dsl_dataset_get_snapname(ds)); |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
640 if (ds->ds_snapname[0]) { |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
641 ++result; /* adding one for the @-sign */ |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
642 if (!MUTEX_HELD(&ds->ds_lock)) { |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
643 mutex_enter(&ds->ds_lock); |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
644 result += strlen(ds->ds_snapname); |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
645 mutex_exit(&ds->ds_lock); |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
646 } else { |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
647 result += strlen(ds->ds_snapname); |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
648 } |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
649 } |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
650 } |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
651 |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
652 return (result); |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
653 } |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
654 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
655 void |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
656 dsl_dataset_drop_ref(dsl_dataset_t *ds, void *tag) |
789 | 657 { |
1544 | 658 dmu_buf_rele(ds->ds_dbuf, tag); |
789 | 659 } |
660 | |
661 void | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
662 dsl_dataset_rele(dsl_dataset_t *ds, void *tag) |
5367 | 663 { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
664 if (!dsl_pool_sync_context(ds->ds_dir->dd_pool)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
665 rw_exit(&ds->ds_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
666 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
667 dsl_dataset_drop_ref(ds, tag); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
668 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
669 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
670 void |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
671 dsl_dataset_disown(dsl_dataset_t *ds, void *owner) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
672 { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
673 ASSERT((ds->ds_owner == owner && ds->ds_dbuf) || |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
674 (DSL_DATASET_IS_DESTROYED(ds) && ds->ds_dbuf == NULL)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
675 |
5367 | 676 mutex_enter(&ds->ds_lock); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
677 ds->ds_owner = NULL; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
678 if (RW_WRITE_HELD(&ds->ds_rwlock)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
679 rw_exit(&ds->ds_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
680 cv_broadcast(&ds->ds_exclusive_cv); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
681 } |
5367 | 682 mutex_exit(&ds->ds_lock); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
683 if (ds->ds_dbuf) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
684 dsl_dataset_drop_ref(ds, owner); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
685 else |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
686 dsl_dataset_evict(ds->ds_dbuf, ds); |
5367 | 687 } |
688 | |
689 boolean_t | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
690 dsl_dataset_tryown(dsl_dataset_t *ds, boolean_t inconsistentok, void *owner) |
5367 | 691 { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
692 boolean_t gotit = FALSE; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
693 |
5367 | 694 mutex_enter(&ds->ds_lock); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
695 if (ds->ds_owner == NULL && |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
696 (!DS_IS_INCONSISTENT(ds) || inconsistentok)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
697 ds->ds_owner = owner; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
698 if (!dsl_pool_sync_context(ds->ds_dir->dd_pool)) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
699 rw_exit(&ds->ds_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
700 gotit = TRUE; |
5367 | 701 } |
702 mutex_exit(&ds->ds_lock); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
703 return (gotit); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
704 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
705 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
706 void |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
707 dsl_dataset_make_exclusive(dsl_dataset_t *ds, void *owner) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
708 { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
709 ASSERT3P(owner, ==, ds->ds_owner); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
710 if (!RW_WRITE_HELD(&ds->ds_rwlock)) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
711 rw_enter(&ds->ds_rwlock, RW_WRITER); |
5367 | 712 } |
713 | |
2199 | 714 uint64_t |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
715 dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
716 uint64_t flags, dmu_tx_t *tx) |
789 | 717 { |
5367 | 718 dsl_pool_t *dp = dd->dd_pool; |
789 | 719 dmu_buf_t *dbuf; |
720 dsl_dataset_phys_t *dsphys; | |
5367 | 721 uint64_t dsobj; |
789 | 722 objset_t *mos = dp->dp_meta_objset; |
723 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
724 if (origin == NULL) |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
725 origin = dp->dp_origin_snap; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
726 |
5367 | 727 ASSERT(origin == NULL || origin->ds_dir->dd_pool == dp); |
728 ASSERT(origin == NULL || origin->ds_phys->ds_num_children > 0); | |
789 | 729 ASSERT(dmu_tx_is_syncing(tx)); |
5367 | 730 ASSERT(dd->dd_phys->dd_head_dataset_obj == 0); |
789 | 731 |
928
36d72fe4da29
6349314 dmu_object_type names incorrect for DSL Directories and DSL Datasets
tabriz
parents:
885
diff
changeset
|
732 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
|
733 DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx); |
1544 | 734 VERIFY(0 == dmu_bonus_hold(mos, dsobj, FTAG, &dbuf)); |
789 | 735 dmu_buf_will_dirty(dbuf, tx); |
736 dsphys = dbuf->db_data; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
737 bzero(dsphys, sizeof (dsl_dataset_phys_t)); |
789 | 738 dsphys->ds_dir_obj = dd->dd_object; |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
739 dsphys->ds_flags = flags; |
789 | 740 dsphys->ds_fsid_guid = unique_create(); |
741 (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid, | |
742 sizeof (dsphys->ds_guid)); | |
743 dsphys->ds_snapnames_zapobj = | |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
744 zap_create_norm(mos, U8_TEXTPREP_TOUPPER, DMU_OT_DSL_DS_SNAP_MAP, |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
745 DMU_OT_NONE, 0, tx); |
789 | 746 dsphys->ds_creation_time = gethrestime_sec(); |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
747 dsphys->ds_creation_txg = tx->tx_txg == TXG_INITIAL ? 1 : tx->tx_txg; |
789 | 748 dsphys->ds_deadlist_obj = |
749 bplist_create(mos, DSL_DEADLIST_BLOCKSIZE, tx); | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
750 |
5367 | 751 if (origin) { |
752 dsphys->ds_prev_snap_obj = origin->ds_object; | |
789 | 753 dsphys->ds_prev_snap_txg = |
5367 | 754 origin->ds_phys->ds_creation_txg; |
789 | 755 dsphys->ds_used_bytes = |
5367 | 756 origin->ds_phys->ds_used_bytes; |
789 | 757 dsphys->ds_compressed_bytes = |
5367 | 758 origin->ds_phys->ds_compressed_bytes; |
789 | 759 dsphys->ds_uncompressed_bytes = |
5367 | 760 origin->ds_phys->ds_uncompressed_bytes; |
761 dsphys->ds_bp = origin->ds_phys->ds_bp; | |
6502
66aef5f20377
6694731 drc->drc_real_ds->ds_phys->ds_flags & (1ULL<<0), file: ../../common/fs/zfs/dmu_send.c, line: 1069
timh
parents:
6492
diff
changeset
|
762 dsphys->ds_flags |= origin->ds_phys->ds_flags; |
789 | 763 |
5367 | 764 dmu_buf_will_dirty(origin->ds_dbuf, tx); |
765 origin->ds_phys->ds_num_children++; | |
789 | 766 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
767 if (spa_version(dp->dp_spa) >= SPA_VERSION_NEXT_CLONES) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
768 if (origin->ds_phys->ds_next_clones_obj == 0) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
769 origin->ds_phys->ds_next_clones_obj = |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
770 zap_create(mos, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
771 DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
772 } |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
773 VERIFY(0 == zap_add_int(mos, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
774 origin->ds_phys->ds_next_clones_obj, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
775 dsobj, tx)); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
776 } |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
777 |
789 | 778 dmu_buf_will_dirty(dd->dd_dbuf, tx); |
5367 | 779 dd->dd_phys->dd_origin_obj = origin->ds_object; |
789 | 780 } |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
781 |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
782 if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE) |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
783 dsphys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
784 |
1544 | 785 dmu_buf_rele(dbuf, FTAG); |
789 | 786 |
787 dmu_buf_will_dirty(dd->dd_dbuf, tx); | |
788 dd->dd_phys->dd_head_dataset_obj = dsobj; | |
5367 | 789 |
790 return (dsobj); | |
791 } | |
792 | |
793 uint64_t | |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
794 dsl_dataset_create_sync(dsl_dir_t *pdd, const char *lastname, |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
795 dsl_dataset_t *origin, uint64_t flags, cred_t *cr, dmu_tx_t *tx) |
5367 | 796 { |
797 dsl_pool_t *dp = pdd->dd_pool; | |
798 uint64_t dsobj, ddobj; | |
799 dsl_dir_t *dd; | |
800 | |
801 ASSERT(lastname[0] != '@'); | |
802 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
803 ddobj = dsl_dir_create_sync(dp, pdd, lastname, tx); |
5367 | 804 VERIFY(0 == dsl_dir_open_obj(dp, ddobj, lastname, FTAG, &dd)); |
805 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
806 dsobj = dsl_dataset_create_sync_dd(dd, origin, flags, tx); |
5367 | 807 |
808 dsl_deleg_set_create_perms(dd, tx, cr); | |
809 | |
789 | 810 dsl_dir_close(dd, FTAG); |
811 | |
2199 | 812 return (dsobj); |
813 } | |
814 | |
815 struct destroyarg { | |
816 dsl_sync_task_group_t *dstg; | |
817 char *snapname; | |
818 char *failed; | |
819 }; | |
820 | |
821 static int | |
822 dsl_snapshot_destroy_one(char *name, void *arg) | |
823 { | |
824 struct destroyarg *da = arg; | |
825 dsl_dataset_t *ds; | |
826 char *cp; | |
827 int err; | |
828 | |
829 (void) strcat(name, "@"); | |
830 (void) strcat(name, da->snapname); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
831 err = dsl_dataset_own(name, DS_MODE_READONLY | DS_MODE_INCONSISTENT, |
4007 | 832 da->dstg, &ds); |
2199 | 833 cp = strchr(name, '@'); |
834 *cp = '\0'; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
835 if (err == 0) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
836 dsl_dataset_make_exclusive(ds, da->dstg); |
7237
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
837 if (ds->ds_user_ptr) { |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
838 ds->ds_user_evict_func(ds, ds->ds_user_ptr); |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
839 ds->ds_user_ptr = NULL; |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
840 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
841 dsl_sync_task_create(da->dstg, dsl_dataset_destroy_check, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
842 dsl_dataset_destroy_sync, ds, da->dstg, 0); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
843 } else if (err == ENOENT) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
844 err = 0; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
845 } else { |
2199 | 846 (void) strcpy(da->failed, name); |
847 } | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
848 return (err); |
789 | 849 } |
850 | |
2199 | 851 /* |
852 * Destroy 'snapname' in all descendants of 'fsname'. | |
853 */ | |
854 #pragma weak dmu_snapshots_destroy = dsl_snapshots_destroy | |
855 int | |
856 dsl_snapshots_destroy(char *fsname, char *snapname) | |
857 { | |
858 int err; | |
859 struct destroyarg da; | |
860 dsl_sync_task_t *dst; | |
861 spa_t *spa; | |
862 | |
4603
c7840c367d00
6494569 zfs recv -d pool/<doesn't exist> core dumps for top-level filesystem backups
ahrens
parents:
4577
diff
changeset
|
863 err = spa_open(fsname, &spa, FTAG); |
2199 | 864 if (err) |
865 return (err); | |
866 da.dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); | |
867 da.snapname = snapname; | |
868 da.failed = fsname; | |
869 | |
870 err = dmu_objset_find(fsname, | |
2417 | 871 dsl_snapshot_destroy_one, &da, DS_FIND_CHILDREN); |
2199 | 872 |
873 if (err == 0) | |
874 err = dsl_sync_task_group_wait(da.dstg); | |
875 | |
876 for (dst = list_head(&da.dstg->dstg_tasks); dst; | |
877 dst = list_next(&da.dstg->dstg_tasks, dst)) { | |
878 dsl_dataset_t *ds = dst->dst_arg1; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
879 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
880 * Return the file system name that triggered the error |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
881 */ |
2199 | 882 if (dst->dst_err) { |
883 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
|
884 *strchr(fsname, '@') = '\0'; |
2199 | 885 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
886 dsl_dataset_disown(ds, da.dstg); |
2199 | 887 } |
888 | |
889 dsl_sync_task_group_destroy(da.dstg); | |
890 spa_close(spa, FTAG); | |
891 return (err); | |
892 } | |
893 | |
5367 | 894 /* |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
895 * ds must be opened as OWNER. On return (whether successful or not), |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
896 * ds will be closed and caller can no longer dereference it. |
5367 | 897 */ |
789 | 898 int |
5367 | 899 dsl_dataset_destroy(dsl_dataset_t *ds, void *tag) |
789 | 900 { |
901 int err; | |
2199 | 902 dsl_sync_task_group_t *dstg; |
903 objset_t *os; | |
789 | 904 dsl_dir_t *dd; |
2199 | 905 uint64_t obj; |
906 | |
5367 | 907 if (dsl_dataset_is_snapshot(ds)) { |
2199 | 908 /* Destroying a snapshot is simpler */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
909 dsl_dataset_make_exclusive(ds, tag); |
7237
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
910 |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
911 if (ds->ds_user_ptr) { |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
912 ds->ds_user_evict_func(ds, ds->ds_user_ptr); |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
913 ds->ds_user_ptr = NULL; |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
914 } |
2199 | 915 err = dsl_sync_task_do(ds->ds_dir->dd_pool, |
916 dsl_dataset_destroy_check, dsl_dataset_destroy_sync, | |
5367 | 917 ds, tag, 0); |
918 goto out; | |
2199 | 919 } |
920 | |
921 dd = ds->ds_dir; | |
789 | 922 |
2199 | 923 /* |
924 * Check for errors and mark this ds as inconsistent, in | |
925 * case we crash while freeing the objects. | |
926 */ | |
927 err = dsl_sync_task_do(dd->dd_pool, dsl_dataset_destroy_begin_check, | |
928 dsl_dataset_destroy_begin_sync, ds, NULL, 0); | |
5367 | 929 if (err) |
930 goto out; | |
931 | |
932 err = dmu_objset_open_ds(ds, DMU_OST_ANY, &os); | |
933 if (err) | |
934 goto out; | |
2199 | 935 |
936 /* | |
937 * remove the objects in open context, so that we won't | |
938 * have too much to do in syncing context. | |
939 */ | |
3025
4e5ee8301d84
6424466 "panic: data after EOF" when unmounting abused pool
ahrens
parents:
2885
diff
changeset
|
940 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
|
941 ds->ds_phys->ds_prev_snap_txg)) { |
6992 | 942 /* |
943 * Ignore errors, if there is not enough disk space | |
944 * we will deal with it in dsl_dataset_destroy_sync(). | |
945 */ | |
946 (void) dmu_free_object(os, obj); | |
2199 | 947 } |
948 | |
949 dmu_objset_close(os); | |
950 if (err != ESRCH) | |
5367 | 951 goto out; |
2199 | 952 |
6975
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
953 rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); |
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
954 err = dsl_dir_open_obj(dd->dd_pool, dd->dd_object, NULL, FTAG, &dd); |
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
955 rw_exit(&dd->dd_pool->dp_config_rwlock); |
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
956 |
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
957 if (err) |
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
958 goto out; |
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
959 |
5367 | 960 if (ds->ds_user_ptr) { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
961 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
962 * We need to sync out all in-flight IO before we try |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
963 * to evict (the dataset evict func is trying to clear |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
964 * the cached entries for this dataset in the ARC). |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
965 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
966 txg_wait_synced(dd->dd_pool, 0); |
5367 | 967 } |
968 | |
2199 | 969 /* |
970 * Blow away the dsl_dir + head dataset. | |
971 */ | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
972 dsl_dataset_make_exclusive(ds, tag); |
6975
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
973 if (ds->ds_user_ptr) { |
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
974 ds->ds_user_evict_func(ds, ds->ds_user_ptr); |
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
975 ds->ds_user_ptr = NULL; |
c511f317869e
6717522 panic in dmu_objset_stats() due to freed objset_impl_t
maybee
parents:
6689
diff
changeset
|
976 } |
2199 | 977 dstg = dsl_sync_task_group_create(ds->ds_dir->dd_pool); |
978 dsl_sync_task_create(dstg, dsl_dataset_destroy_check, | |
5367 | 979 dsl_dataset_destroy_sync, ds, tag, 0); |
2199 | 980 dsl_sync_task_create(dstg, dsl_dir_destroy_check, |
981 dsl_dir_destroy_sync, dd, FTAG, 0); | |
982 err = dsl_sync_task_group_wait(dstg); | |
983 dsl_sync_task_group_destroy(dstg); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
984 /* if it is successful, dsl_dir_destroy_sync will close the dd */ |
5367 | 985 if (err) |
2199 | 986 dsl_dir_close(dd, FTAG); |
5367 | 987 out: |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
988 dsl_dataset_disown(ds, tag); |
789 | 989 return (err); |
990 } | |
991 | |
992 int | |
5367 | 993 dsl_dataset_rollback(dsl_dataset_t *ds, dmu_objset_type_t ost) |
789 | 994 { |
7385
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
995 int err; |
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
996 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
997 ASSERT(ds->ds_owner); |
5367 | 998 |
7385
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
999 dsl_dataset_make_exclusive(ds, ds->ds_owner); |
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
1000 err = dsl_sync_task_do(ds->ds_dir->dd_pool, |
2199 | 1001 dsl_dataset_rollback_check, dsl_dataset_rollback_sync, |
7385
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
1002 ds, &ost, 0); |
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
1003 /* drop exclusive access */ |
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
1004 mutex_enter(&ds->ds_lock); |
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
1005 rw_exit(&ds->ds_rwlock); |
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
1006 cv_broadcast(&ds->ds_exclusive_cv); |
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
1007 mutex_exit(&ds->ds_lock); |
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
1008 return (err); |
789 | 1009 } |
1010 | |
1011 void * | |
1012 dsl_dataset_set_user_ptr(dsl_dataset_t *ds, | |
1013 void *p, dsl_dataset_evict_func_t func) | |
1014 { | |
1015 void *old; | |
1016 | |
1017 mutex_enter(&ds->ds_lock); | |
1018 old = ds->ds_user_ptr; | |
1019 if (old == NULL) { | |
1020 ds->ds_user_ptr = p; | |
1021 ds->ds_user_evict_func = func; | |
1022 } | |
1023 mutex_exit(&ds->ds_lock); | |
1024 return (old); | |
1025 } | |
1026 | |
1027 void * | |
1028 dsl_dataset_get_user_ptr(dsl_dataset_t *ds) | |
1029 { | |
1030 return (ds->ds_user_ptr); | |
1031 } | |
1032 | |
1033 | |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
1034 blkptr_t * |
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
1035 dsl_dataset_get_blkptr(dsl_dataset_t *ds) |
789 | 1036 { |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
1037 return (&ds->ds_phys->ds_bp); |
789 | 1038 } |
1039 | |
1040 void | |
1041 dsl_dataset_set_blkptr(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx) | |
1042 { | |
1043 ASSERT(dmu_tx_is_syncing(tx)); | |
1044 /* If it's the meta-objset, set dp_meta_rootbp */ | |
1045 if (ds == NULL) { | |
1046 tx->tx_pool->dp_meta_rootbp = *bp; | |
1047 } else { | |
1048 dmu_buf_will_dirty(ds->ds_dbuf, tx); | |
1049 ds->ds_phys->ds_bp = *bp; | |
1050 } | |
1051 } | |
1052 | |
1053 spa_t * | |
1054 dsl_dataset_get_spa(dsl_dataset_t *ds) | |
1055 { | |
1056 return (ds->ds_dir->dd_pool->dp_spa); | |
1057 } | |
1058 | |
1059 void | |
1060 dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx) | |
1061 { | |
1062 dsl_pool_t *dp; | |
1063 | |
1064 if (ds == NULL) /* this is the meta-objset */ | |
1065 return; | |
1066 | |
1067 ASSERT(ds->ds_user_ptr != NULL); | |
2885 | 1068 |
1069 if (ds->ds_phys->ds_next_snap_obj != 0) | |
1070 panic("dirtying snapshot!"); | |
789 | 1071 |
1072 dp = ds->ds_dir->dd_pool; | |
1073 | |
1074 if (txg_list_add(&dp->dp_dirty_datasets, ds, tx->tx_txg) == 0) { | |
1075 /* up the hold count until we can be written out */ | |
1076 dmu_buf_add_ref(ds->ds_dbuf, ds); | |
1077 } | |
1078 } | |
1079 | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1080 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1081 * The unique space in the head dataset can be calculated by subtracting |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1082 * the space used in the most recent snapshot, that is still being used |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1083 * in this file system, from the space currently in use. To figure out |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1084 * the space in the most recent snapshot still in use, we need to take |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1085 * the total space used in the snapshot and subtract out the space that |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1086 * has been freed up since the snapshot was taken. |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1087 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1088 static void |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1089 dsl_dataset_recalc_head_uniq(dsl_dataset_t *ds) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1090 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1091 uint64_t mrs_used; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1092 uint64_t dlused, dlcomp, dluncomp; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1093 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1094 ASSERT(ds->ds_object == ds->ds_dir->dd_phys->dd_head_dataset_obj); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1095 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1096 if (ds->ds_phys->ds_prev_snap_obj != 0) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1097 mrs_used = ds->ds_prev->ds_phys->ds_used_bytes; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1098 else |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1099 mrs_used = 0; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1100 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1101 VERIFY(0 == bplist_space(&ds->ds_deadlist, &dlused, &dlcomp, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1102 &dluncomp)); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1103 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1104 ASSERT3U(dlused, <=, mrs_used); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1105 ds->ds_phys->ds_unique_bytes = |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1106 ds->ds_phys->ds_used_bytes - (mrs_used - dlused); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1107 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1108 if (!DS_UNIQUE_IS_ACCURATE(ds) && |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1109 spa_version(ds->ds_dir->dd_pool->dp_spa) >= |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1110 SPA_VERSION_UNIQUE_ACCURATE) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1111 ds->ds_phys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1112 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1113 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1114 static uint64_t |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1115 dsl_dataset_unique(dsl_dataset_t *ds) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1116 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1117 if (!DS_UNIQUE_IS_ACCURATE(ds) && !dsl_dataset_is_snapshot(ds)) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1118 dsl_dataset_recalc_head_uniq(ds); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1119 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1120 return (ds->ds_phys->ds_unique_bytes); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1121 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1122 |
789 | 1123 struct killarg { |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1124 int64_t *usedp; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1125 int64_t *compressedp; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1126 int64_t *uncompressedp; |
789 | 1127 zio_t *zio; |
1128 dmu_tx_t *tx; | |
1129 }; | |
1130 | |
1131 static int | |
1132 kill_blkptr(traverse_blk_cache_t *bc, spa_t *spa, void *arg) | |
1133 { | |
1134 struct killarg *ka = arg; | |
1135 blkptr_t *bp = &bc->bc_blkptr; | |
1136 | |
1137 ASSERT3U(bc->bc_errno, ==, 0); | |
1138 | |
1139 /* | |
1140 * Since this callback is not called concurrently, no lock is | |
1141 * needed on the accounting values. | |
1142 */ | |
2082 | 1143 *ka->usedp += bp_get_dasize(spa, bp); |
789 | 1144 *ka->compressedp += BP_GET_PSIZE(bp); |
1145 *ka->uncompressedp += BP_GET_UCSIZE(bp); | |
1146 /* XXX check for EIO? */ | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1147 (void) dsl_free(ka->zio, spa_get_dsl(spa), ka->tx->tx_txg, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1148 bp, NULL, NULL, ARC_NOWAIT); |
789 | 1149 return (0); |
1150 } | |
1151 | |
1152 /* ARGSUSED */ | |
2199 | 1153 static int |
1154 dsl_dataset_rollback_check(void *arg1, void *arg2, dmu_tx_t *tx) | |
789 | 1155 { |
2199 | 1156 dsl_dataset_t *ds = arg1; |
5367 | 1157 dmu_objset_type_t *ost = arg2; |
789 | 1158 |
2199 | 1159 /* |
5367 | 1160 * We can only roll back to emptyness if it is a ZPL objset. |
2199 | 1161 */ |
5367 | 1162 if (*ost != DMU_OST_ZFS && ds->ds_phys->ds_prev_snap_txg == 0) |
789 | 1163 return (EINVAL); |
1164 | |
2199 | 1165 /* |
1166 * This must not be a snapshot. | |
1167 */ | |
1168 if (ds->ds_phys->ds_next_snap_obj != 0) | |
1169 return (EINVAL); | |
789 | 1170 |
1171 /* | |
1172 * If we made changes this txg, traverse_dsl_dataset won't find | |
1173 * them. Try again. | |
1174 */ | |
2199 | 1175 if (ds->ds_phys->ds_bp.blk_birth >= tx->tx_txg) |
789 | 1176 return (EAGAIN); |
2199 | 1177 |
1178 return (0); | |
1179 } | |
789 | 1180 |
2199 | 1181 /* ARGSUSED */ |
1182 static void | |
4543 | 1183 dsl_dataset_rollback_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) |
2199 | 1184 { |
1185 dsl_dataset_t *ds = arg1; | |
5367 | 1186 dmu_objset_type_t *ost = arg2; |
2199 | 1187 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; |
789 | 1188 |
1189 dmu_buf_will_dirty(ds->ds_dbuf, tx); | |
1190 | |
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
|
1191 /* |
8d0de61ff354
6597381 BAD TRAP: type=e (#pf Page fault) rp=ffffff00043a48f0 addr=28 occurred in module "<unknown>" due to
perrin
parents:
4935
diff
changeset
|
1192 * 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
|
1193 */ |
8d0de61ff354
6597381 BAD TRAP: type=e (#pf Page fault) rp=ffffff00043a48f0 addr=28 occurred in module "<unknown>" due to
perrin
parents:
4935
diff
changeset
|
1194 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
|
1195 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
|
1196 ((objset_impl_t *)ds->ds_user_ptr)->os_zil, tx); |
5367 | 1197 |
1198 /* | |
1199 * We need to make sure that the objset_impl_t is reopened after | |
1200 * we do the rollback, otherwise it will have the wrong | |
1201 * objset_phys_t. Normally this would happen when this | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1202 * dataset-open is closed, thus causing the |
5367 | 1203 * dataset to be immediately evicted. But when doing "zfs recv |
1204 * -F", we reopen the objset before that, so that there is no | |
1205 * window where the dataset is closed and inconsistent. | |
1206 */ | |
1207 ds->ds_user_evict_func(ds, ds->ds_user_ptr); | |
1208 ds->ds_user_ptr = NULL; | |
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
|
1209 } |
4935
c80bf0e6f4aa
6534949 Stale need for range locking comment in zvol.c
perrin
parents:
4787
diff
changeset
|
1210 |
789 | 1211 /* Zero out the deadlist. */ |
1212 bplist_close(&ds->ds_deadlist); | |
1213 bplist_destroy(mos, ds->ds_phys->ds_deadlist_obj, tx); | |
1214 ds->ds_phys->ds_deadlist_obj = | |
1215 bplist_create(mos, DSL_DEADLIST_BLOCKSIZE, tx); | |
1544 | 1216 VERIFY(0 == bplist_open(&ds->ds_deadlist, mos, |
1217 ds->ds_phys->ds_deadlist_obj)); | |
789 | 1218 |
1219 { | |
1220 /* Free blkptrs that we gave birth to */ | |
1221 zio_t *zio; | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1222 int64_t used = 0, compressed = 0, uncompressed = 0; |
789 | 1223 struct killarg ka; |
5518
85721e07d1fa
6630707 assertion failed: used >= 0 || dd->dd_used_bytes >= -used, file: dsl_dir.c, line: 904
ck153898
parents:
5481
diff
changeset
|
1224 int64_t delta; |
789 | 1225 |
1226 zio = zio_root(tx->tx_pool->dp_spa, NULL, NULL, | |
1227 ZIO_FLAG_MUSTSUCCEED); | |
1228 ka.usedp = &used; | |
1229 ka.compressedp = &compressed; | |
1230 ka.uncompressedp = &uncompressed; | |
1231 ka.zio = zio; | |
1232 ka.tx = tx; | |
1233 (void) traverse_dsl_dataset(ds, ds->ds_phys->ds_prev_snap_txg, | |
1234 ADVANCE_POST, kill_blkptr, &ka); | |
1235 (void) zio_wait(zio); | |
1236 | |
5518
85721e07d1fa
6630707 assertion failed: used >= 0 || dd->dd_used_bytes >= -used, file: dsl_dir.c, line: 904
ck153898
parents:
5481
diff
changeset
|
1237 /* only deduct space beyond any refreservation */ |
85721e07d1fa
6630707 assertion failed: used >= 0 || dd->dd_used_bytes >= -used, file: dsl_dir.c, line: 904
ck153898
parents:
5481
diff
changeset
|
1238 delta = parent_delta(ds, -used); |
2199 | 1239 dsl_dir_diduse_space(ds->ds_dir, |
5518
85721e07d1fa
6630707 assertion failed: used >= 0 || dd->dd_used_bytes >= -used, file: dsl_dir.c, line: 904
ck153898
parents:
5481
diff
changeset
|
1240 delta, -compressed, -uncompressed, tx); |
789 | 1241 } |
1242 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1243 if (ds->ds_prev && ds->ds_prev != ds->ds_dir->dd_pool->dp_origin_snap) { |
5367 | 1244 /* Change our contents to that of the prev snapshot */ |
1245 ASSERT3U(ds->ds_prev->ds_object, ==, | |
1246 ds->ds_phys->ds_prev_snap_obj); | |
1247 ds->ds_phys->ds_bp = ds->ds_prev->ds_phys->ds_bp; | |
1248 ds->ds_phys->ds_used_bytes = | |
1249 ds->ds_prev->ds_phys->ds_used_bytes; | |
1250 ds->ds_phys->ds_compressed_bytes = | |
1251 ds->ds_prev->ds_phys->ds_compressed_bytes; | |
1252 ds->ds_phys->ds_uncompressed_bytes = | |
1253 ds->ds_prev->ds_phys->ds_uncompressed_bytes; | |
1254 ds->ds_phys->ds_flags = ds->ds_prev->ds_phys->ds_flags; | |
1255 ds->ds_phys->ds_unique_bytes = 0; | |
789 | 1256 |
5367 | 1257 if (ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) { |
1258 dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx); | |
1259 ds->ds_prev->ds_phys->ds_unique_bytes = 0; | |
1260 } | |
1261 } else { | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1262 objset_impl_t *osi; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1263 |
5367 | 1264 /* Zero out our contents, recreate objset */ |
1265 bzero(&ds->ds_phys->ds_bp, sizeof (blkptr_t)); | |
1266 ds->ds_phys->ds_used_bytes = 0; | |
1267 ds->ds_phys->ds_compressed_bytes = 0; | |
1268 ds->ds_phys->ds_uncompressed_bytes = 0; | |
1269 ds->ds_phys->ds_flags = 0; | |
1270 ds->ds_phys->ds_unique_bytes = 0; | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1271 osi = dmu_objset_create_impl(ds->ds_dir->dd_pool->dp_spa, ds, |
5367 | 1272 &ds->ds_phys->ds_bp, *ost, tx); |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1273 #ifdef _KERNEL |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1274 zfs_create_fs(&osi->os, kcred, NULL, tx); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1275 #endif |
2532
752725c22841
6448999 panic: used == ds->ds_phys->ds_unique_bytes
ahrens
parents:
2417
diff
changeset
|
1276 } |
4543 | 1277 |
1278 spa_history_internal_log(LOG_DS_ROLLBACK, ds->ds_dir->dd_pool->dp_spa, | |
1279 tx, cr, "dataset = %llu", ds->ds_object); | |
789 | 1280 } |
1281 | |
1731
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1282 /* ARGSUSED */ |
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1283 static int |
2199 | 1284 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
|
1285 { |
2199 | 1286 dsl_dataset_t *ds = arg1; |
5367 | 1287 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; |
1288 uint64_t count; | |
1289 int err; | |
1731
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1290 |
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1291 /* |
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1292 * 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
|
1293 * (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
|
1294 * from.) |
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1295 */ |
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1296 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
|
1297 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
|
1298 return (EINVAL); |
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1299 |
5367 | 1300 /* |
1301 * This is really a dsl_dir thing, but check it here so that | |
1302 * we'll be less likely to leave this dataset inconsistent & | |
1303 * nearly destroyed. | |
1304 */ | |
1305 err = zap_count(mos, ds->ds_dir->dd_phys->dd_child_dir_zapobj, &count); | |
1306 if (err) | |
1307 return (err); | |
1308 if (count != 0) | |
1309 return (EEXIST); | |
1310 | |
1731
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1311 return (0); |
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1312 } |
1efa8b3d1296
6402598 'zfs destroy <fs>' can take a long time, stopping up the txg train
bonwick
parents:
1544
diff
changeset
|
1313 |
2199 | 1314 /* ARGSUSED */ |
1315 static void | |
4543 | 1316 dsl_dataset_destroy_begin_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) |
789 | 1317 { |
2199 | 1318 dsl_dataset_t *ds = arg1; |
4543 | 1319 dsl_pool_t *dp = ds->ds_dir->dd_pool; |
789 | 1320 |
2199 | 1321 /* Mark it as inconsistent on-disk, in case we crash */ |
1322 dmu_buf_will_dirty(ds->ds_dbuf, tx); | |
1323 ds->ds_phys->ds_flags |= DS_FLAG_INCONSISTENT; | |
4543 | 1324 |
1325 spa_history_internal_log(LOG_DS_DESTROY_BEGIN, dp->dp_spa, tx, | |
1326 cr, "dataset = %llu", ds->ds_object); | |
2199 | 1327 } |
789 | 1328 |
2199 | 1329 /* ARGSUSED */ |
5367 | 1330 int |
2199 | 1331 dsl_dataset_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx) |
1332 { | |
1333 dsl_dataset_t *ds = arg1; | |
789 | 1334 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1335 /* we have an owner hold, so noone else can destroy us */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1336 ASSERT(!DSL_DATASET_IS_DESTROYED(ds)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1337 |
789 | 1338 /* Can't delete a branch point. */ |
2199 | 1339 if (ds->ds_phys->ds_num_children > 1) |
1340 return (EEXIST); | |
789 | 1341 |
1342 /* | |
1343 * Can't delete a head dataset if there are snapshots of it. | |
1344 * (Except if the only snapshots are from the branch we cloned | |
1345 * from.) | |
1346 */ | |
1347 if (ds->ds_prev != NULL && | |
2199 | 1348 ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) |
789 | 1349 return (EINVAL); |
1350 | |
1351 /* | |
1352 * If we made changes this txg, traverse_dsl_dataset won't find | |
1353 * them. Try again. | |
1354 */ | |
2199 | 1355 if (ds->ds_phys->ds_bp.blk_birth >= tx->tx_txg) |
789 | 1356 return (EAGAIN); |
2199 | 1357 |
1358 /* XXX we should do some i/o error checking... */ | |
1359 return (0); | |
1360 } | |
1361 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1362 struct refsarg { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1363 kmutex_t lock; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1364 boolean_t gone; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1365 kcondvar_t cv; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1366 }; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1367 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1368 /* ARGSUSED */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1369 static void |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1370 dsl_dataset_refs_gone(dmu_buf_t *db, void *argv) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1371 { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1372 struct refsarg *arg = argv; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1373 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1374 mutex_enter(&arg->lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1375 arg->gone = TRUE; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1376 cv_signal(&arg->cv); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1377 mutex_exit(&arg->lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1378 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1379 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1380 static void |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1381 dsl_dataset_drain_refs(dsl_dataset_t *ds, void *tag) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1382 { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1383 struct refsarg arg; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1384 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1385 mutex_init(&arg.lock, NULL, MUTEX_DEFAULT, NULL); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1386 cv_init(&arg.cv, NULL, CV_DEFAULT, NULL); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1387 arg.gone = FALSE; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1388 (void) dmu_buf_update_user(ds->ds_dbuf, ds, &arg, &ds->ds_phys, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1389 dsl_dataset_refs_gone); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1390 dmu_buf_rele(ds->ds_dbuf, tag); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1391 mutex_enter(&arg.lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1392 while (!arg.gone) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1393 cv_wait(&arg.cv, &arg.lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1394 ASSERT(arg.gone); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1395 mutex_exit(&arg.lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1396 ds->ds_dbuf = NULL; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1397 ds->ds_phys = NULL; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1398 mutex_destroy(&arg.lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1399 cv_destroy(&arg.cv); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1400 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1401 |
5367 | 1402 void |
4543 | 1403 dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) |
2199 | 1404 { |
1405 dsl_dataset_t *ds = arg1; | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1406 int64_t used = 0, compressed = 0, uncompressed = 0; |
2199 | 1407 zio_t *zio; |
1408 int err; | |
1409 int after_branch_point = FALSE; | |
1410 dsl_pool_t *dp = ds->ds_dir->dd_pool; | |
1411 objset_t *mos = dp->dp_meta_objset; | |
1412 dsl_dataset_t *ds_prev = NULL; | |
1413 uint64_t obj; | |
1414 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1415 ASSERT(ds->ds_owner); |
2199 | 1416 ASSERT3U(ds->ds_phys->ds_num_children, <=, 1); |
1417 ASSERT(ds->ds_prev == NULL || | |
1418 ds->ds_prev->ds_phys->ds_next_snap_obj != ds->ds_object); | |
1419 ASSERT3U(ds->ds_phys->ds_bp.blk_birth, <=, tx->tx_txg); | |
1420 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1421 /* signal any waiters that this dataset is going away */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1422 mutex_enter(&ds->ds_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1423 ds->ds_owner = dsl_reaper; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1424 cv_broadcast(&ds->ds_exclusive_cv); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1425 mutex_exit(&ds->ds_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1426 |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1427 /* Remove our reservation */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1428 if (ds->ds_reserved != 0) { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1429 uint64_t val = 0; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1430 dsl_dataset_set_reservation_sync(ds, &val, cr, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1431 ASSERT3U(ds->ds_reserved, ==, 0); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1432 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1433 |
2199 | 1434 ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock)); |
1435 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1436 dsl_pool_ds_destroyed(ds, tx); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1437 |
2199 | 1438 obj = ds->ds_object; |
789 | 1439 |
1440 if (ds->ds_phys->ds_prev_snap_obj != 0) { | |
1441 if (ds->ds_prev) { | |
1442 ds_prev = ds->ds_prev; | |
1443 } else { | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1444 VERIFY(0 == dsl_dataset_hold_obj(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1445 ds->ds_phys->ds_prev_snap_obj, FTAG, &ds_prev)); |
789 | 1446 } |
1447 after_branch_point = | |
1448 (ds_prev->ds_phys->ds_next_snap_obj != obj); | |
1449 | |
1450 dmu_buf_will_dirty(ds_prev->ds_dbuf, tx); | |
1451 if (after_branch_point && | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1452 ds_prev->ds_phys->ds_next_clones_obj != 0) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1453 VERIFY(0 == zap_remove_int(mos, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1454 ds_prev->ds_phys->ds_next_clones_obj, obj, tx)); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1455 if (ds->ds_phys->ds_next_snap_obj != 0) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1456 VERIFY(0 == zap_add_int(mos, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1457 ds_prev->ds_phys->ds_next_clones_obj, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1458 ds->ds_phys->ds_next_snap_obj, tx)); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1459 } |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1460 } |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1461 if (after_branch_point && |
789 | 1462 ds->ds_phys->ds_next_snap_obj == 0) { |
1463 /* This clone is toast. */ | |
1464 ASSERT(ds_prev->ds_phys->ds_num_children > 1); | |
1465 ds_prev->ds_phys->ds_num_children--; | |
1466 } else if (!after_branch_point) { | |
1467 ds_prev->ds_phys->ds_next_snap_obj = | |
1468 ds->ds_phys->ds_next_snap_obj; | |
1469 } | |
1470 } | |
1471 | |
1472 zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); | |
1473 | |
1474 if (ds->ds_phys->ds_next_snap_obj != 0) { | |
2199 | 1475 blkptr_t bp; |
789 | 1476 dsl_dataset_t *ds_next; |
1477 uint64_t itor = 0; | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1478 uint64_t old_unique; |
789 | 1479 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1480 VERIFY(0 == dsl_dataset_hold_obj(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1481 ds->ds_phys->ds_next_snap_obj, FTAG, &ds_next)); |
789 | 1482 ASSERT3U(ds_next->ds_phys->ds_prev_snap_obj, ==, obj); |
1483 | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1484 old_unique = dsl_dataset_unique(ds_next); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1485 |
789 | 1486 dmu_buf_will_dirty(ds_next->ds_dbuf, tx); |
1487 ds_next->ds_phys->ds_prev_snap_obj = | |
1488 ds->ds_phys->ds_prev_snap_obj; | |
1489 ds_next->ds_phys->ds_prev_snap_txg = | |
1490 ds->ds_phys->ds_prev_snap_txg; | |
1491 ASSERT3U(ds->ds_phys->ds_prev_snap_txg, ==, | |
1492 ds_prev ? ds_prev->ds_phys->ds_creation_txg : 0); | |
1493 | |
1494 /* | |
1495 * Transfer to our deadlist (which will become next's | |
1496 * new deadlist) any entries from next's current | |
1497 * deadlist which were born before prev, and free the | |
1498 * other entries. | |
1499 * | |
1500 * XXX we're doing this long task with the config lock held | |
1501 */ | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1502 while (bplist_iterate(&ds_next->ds_deadlist, &itor, &bp) == 0) { |
789 | 1503 if (bp.blk_birth <= ds->ds_phys->ds_prev_snap_txg) { |
1544 | 1504 VERIFY(0 == bplist_enqueue(&ds->ds_deadlist, |
1505 &bp, tx)); | |
789 | 1506 if (ds_prev && !after_branch_point && |
1507 bp.blk_birth > | |
1508 ds_prev->ds_phys->ds_prev_snap_txg) { | |
1509 ds_prev->ds_phys->ds_unique_bytes += | |
2082 | 1510 bp_get_dasize(dp->dp_spa, &bp); |
789 | 1511 } |
1512 } else { | |
2082 | 1513 used += bp_get_dasize(dp->dp_spa, &bp); |
789 | 1514 compressed += BP_GET_PSIZE(&bp); |
1515 uncompressed += BP_GET_UCSIZE(&bp); | |
1516 /* XXX check return value? */ | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1517 (void) dsl_free(zio, dp, tx->tx_txg, |
789 | 1518 &bp, NULL, NULL, ARC_NOWAIT); |
1519 } | |
1520 } | |
1521 | |
1522 /* free next's deadlist */ | |
1523 bplist_close(&ds_next->ds_deadlist); | |
1524 bplist_destroy(mos, ds_next->ds_phys->ds_deadlist_obj, tx); | |
1525 | |
1526 /* set next's deadlist to our deadlist */ | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1527 bplist_close(&ds->ds_deadlist); |
789 | 1528 ds_next->ds_phys->ds_deadlist_obj = |
1529 ds->ds_phys->ds_deadlist_obj; | |
1544 | 1530 VERIFY(0 == bplist_open(&ds_next->ds_deadlist, mos, |
1531 ds_next->ds_phys->ds_deadlist_obj)); | |
789 | 1532 ds->ds_phys->ds_deadlist_obj = 0; |
1533 | |
1534 if (ds_next->ds_phys->ds_next_snap_obj != 0) { | |
1535 /* | |
1536 * Update next's unique to include blocks which | |
1537 * were previously shared by only this snapshot | |
1538 * and it. Those blocks will be born after the | |
1539 * prev snap and before this snap, and will have | |
1540 * died after the next snap and before the one | |
1541 * after that (ie. be on the snap after next's | |
1542 * deadlist). | |
1543 * | |
1544 * XXX we're doing this long task with the | |
1545 * config lock held | |
1546 */ | |
1547 dsl_dataset_t *ds_after_next; | |
1548 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1549 VERIFY(0 == dsl_dataset_hold_obj(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1550 ds_next->ds_phys->ds_next_snap_obj, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1551 FTAG, &ds_after_next)); |
789 | 1552 itor = 0; |
1553 while (bplist_iterate(&ds_after_next->ds_deadlist, | |
1554 &itor, &bp) == 0) { | |
1555 if (bp.blk_birth > | |
1556 ds->ds_phys->ds_prev_snap_txg && | |
1557 bp.blk_birth <= | |
1558 ds->ds_phys->ds_creation_txg) { | |
1559 ds_next->ds_phys->ds_unique_bytes += | |
2082 | 1560 bp_get_dasize(dp->dp_spa, &bp); |
789 | 1561 } |
1562 } | |
1563 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1564 dsl_dataset_rele(ds_after_next, FTAG); |
789 | 1565 ASSERT3P(ds_next->ds_prev, ==, NULL); |
1566 } else { | |
1567 ASSERT3P(ds_next->ds_prev, ==, ds); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1568 dsl_dataset_drop_ref(ds_next->ds_prev, ds_next); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1569 ds_next->ds_prev = NULL; |
789 | 1570 if (ds_prev) { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1571 VERIFY(0 == dsl_dataset_get_ref(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1572 ds->ds_phys->ds_prev_snap_obj, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1573 ds_next, &ds_next->ds_prev)); |
789 | 1574 } |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1575 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1576 dsl_dataset_recalc_head_uniq(ds_next); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1577 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1578 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1579 * Reduce the amount of our unconsmed refreservation |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1580 * being charged to our parent by the amount of |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1581 * new unique data we have gained. |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1582 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1583 if (old_unique < ds_next->ds_reserved) { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1584 int64_t mrsdelta; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1585 uint64_t new_unique = |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1586 ds_next->ds_phys->ds_unique_bytes; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1587 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1588 ASSERT(old_unique <= new_unique); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1589 mrsdelta = MIN(new_unique - old_unique, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1590 ds_next->ds_reserved - old_unique); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1591 dsl_dir_diduse_space(ds->ds_dir, -mrsdelta, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1592 0, 0, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1593 } |
789 | 1594 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1595 dsl_dataset_rele(ds_next, FTAG); |
789 | 1596 |
1597 /* | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1598 * NB: unique_bytes might not be accurate for the head objset. |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1599 * Before SPA_VERSION 9, we didn't update its value when we |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1600 * deleted the most recent snapshot. |
789 | 1601 */ |
1602 ASSERT3U(used, ==, ds->ds_phys->ds_unique_bytes); | |
1603 } else { | |
1604 /* | |
1605 * There's no next snapshot, so this is a head dataset. | |
1606 * Destroy the deadlist. Unless it's a clone, the | |
1607 * deadlist should be empty. (If it's a clone, it's | |
1608 * safe to ignore the deadlist contents.) | |
1609 */ | |
1610 struct killarg ka; | |
1611 | |
1612 ASSERT(after_branch_point || bplist_empty(&ds->ds_deadlist)); | |
1613 bplist_close(&ds->ds_deadlist); | |
1614 bplist_destroy(mos, ds->ds_phys->ds_deadlist_obj, tx); | |
1615 ds->ds_phys->ds_deadlist_obj = 0; | |
1616 | |
1617 /* | |
1618 * Free everything that we point to (that's born after | |
1619 * the previous snapshot, if we are a clone) | |
1620 * | |
1621 * XXX we're doing this long task with the config lock held | |
1622 */ | |
1623 ka.usedp = &used; | |
1624 ka.compressedp = &compressed; | |
1625 ka.uncompressedp = &uncompressed; | |
1626 ka.zio = zio; | |
1627 ka.tx = tx; | |
1628 err = traverse_dsl_dataset(ds, ds->ds_phys->ds_prev_snap_txg, | |
1629 ADVANCE_POST, kill_blkptr, &ka); | |
1630 ASSERT3U(err, ==, 0); | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1631 ASSERT(spa_version(dp->dp_spa) < |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1632 SPA_VERSION_UNIQUE_ACCURATE || |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1633 used == ds->ds_phys->ds_unique_bytes); |
789 | 1634 } |
1635 | |
1636 err = zio_wait(zio); | |
1637 ASSERT3U(err, ==, 0); | |
1638 | |
2199 | 1639 dsl_dir_diduse_space(ds->ds_dir, -used, -compressed, -uncompressed, tx); |
789 | 1640 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1641 if (ds->ds_dir->dd_phys->dd_head_dataset_obj == ds->ds_object) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1642 /* Erase the link in the dir */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1643 dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1644 ds->ds_dir->dd_phys->dd_head_dataset_obj = 0; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1645 ASSERT(ds->ds_phys->ds_snapnames_zapobj != 0); |
789 | 1646 err = zap_destroy(mos, ds->ds_phys->ds_snapnames_zapobj, tx); |
1647 ASSERT(err == 0); | |
1648 } else { | |
1649 /* remove from snapshot namespace */ | |
1650 dsl_dataset_t *ds_head; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1651 ASSERT(ds->ds_phys->ds_snapnames_zapobj == 0); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1652 VERIFY(0 == dsl_dataset_hold_obj(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1653 ds->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &ds_head)); |
2207
47efcb3433a7
6439370 assertion failures possible in dsl_dataset_destroy_sync()
ahrens
parents:
2199
diff
changeset
|
1654 VERIFY(0 == dsl_dataset_get_snapname(ds)); |
789 | 1655 #ifdef ZFS_DEBUG |
1656 { | |
1657 uint64_t val; | |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
1658 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1659 err = dsl_dataset_snap_lookup(ds_head, |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6047
diff
changeset
|
1660 ds->ds_snapname, &val); |
789 | 1661 ASSERT3U(err, ==, 0); |
1662 ASSERT3U(val, ==, obj); | |
1663 } | |
1664 #endif | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1665 err = dsl_dataset_snap_remove(ds_head, ds->ds_snapname, tx); |
789 | 1666 ASSERT(err == 0); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1667 dsl_dataset_rele(ds_head, FTAG); |
789 | 1668 } |
1669 | |
1670 if (ds_prev && ds->ds_prev != ds_prev) | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1671 dsl_dataset_rele(ds_prev, FTAG); |
789 | 1672 |
5094 | 1673 spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx); |
4543 | 1674 spa_history_internal_log(LOG_DS_DESTROY, dp->dp_spa, tx, |
1675 cr, "dataset = %llu", ds->ds_object); | |
1676 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1677 if (ds->ds_phys->ds_next_clones_obj != 0) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1678 uint64_t count; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1679 ASSERT(0 == zap_count(mos, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1680 ds->ds_phys->ds_next_clones_obj, &count) && count == 0); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1681 VERIFY(0 == dmu_object_free(mos, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1682 ds->ds_phys->ds_next_clones_obj, tx)); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1683 } |
7265 | 1684 if (ds->ds_phys->ds_props_obj != 0) { |
1685 VERIFY(0 == zap_destroy(mos, | |
1686 ds->ds_phys->ds_props_obj, tx)); | |
1687 } | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1688 dsl_dir_close(ds->ds_dir, ds); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1689 ds->ds_dir = NULL; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1690 dsl_dataset_drain_refs(ds, tag); |
2199 | 1691 VERIFY(0 == dmu_object_free(mos, obj, tx)); |
1692 } | |
1693 | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1694 static int |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1695 dsl_dataset_snapshot_reserve_space(dsl_dataset_t *ds, dmu_tx_t *tx) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1696 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1697 uint64_t asize; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1698 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1699 if (!dmu_tx_is_syncing(tx)) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1700 return (0); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1701 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1702 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1703 * If there's an fs-only reservation, any blocks that might become |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1704 * owned by the snapshot dataset must be accommodated by space |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1705 * outside of the reservation. |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1706 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1707 asize = MIN(dsl_dataset_unique(ds), ds->ds_reserved); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1708 if (asize > dsl_dir_space_available(ds->ds_dir, NULL, 0, FALSE)) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1709 return (ENOSPC); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1710 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1711 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1712 * Propogate any reserved space for this snapshot to other |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1713 * snapshot checks in this sync group. |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1714 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1715 if (asize > 0) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1716 dsl_dir_willuse_space(ds->ds_dir, asize, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1717 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1718 return (0); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1719 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1720 |
2199 | 1721 /* ARGSUSED */ |
1722 int | |
1723 dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx) | |
1724 { | |
5367 | 1725 dsl_dataset_t *ds = arg1; |
2199 | 1726 const char *snapname = arg2; |
1727 int err; | |
1728 uint64_t value; | |
789 | 1729 |
1730 /* | |
2199 | 1731 * We don't allow multiple snapshots of the same txg. If there |
1732 * is already one, try again. | |
1733 */ | |
1734 if (ds->ds_phys->ds_prev_snap_txg >= tx->tx_txg) | |
1735 return (EAGAIN); | |
1736 | |
1737 /* | |
1738 * Check for conflicting name snapshot name. | |
789 | 1739 */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1740 err = dsl_dataset_snap_lookup(ds, snapname, &value); |
2199 | 1741 if (err == 0) |
1742 return (EEXIST); | |
1743 if (err != ENOENT) | |
1744 return (err); | |
789 | 1745 |
3978
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
1746 /* |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
1747 * 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
|
1748 * 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
|
1749 */ |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
1750 if (dsl_dataset_namelen(ds) + 1 + strlen(snapname) >= MAXNAMELEN) |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
1751 return (ENAMETOOLONG); |
2dd668007b7a
6533813 recursive snapshotting resulted in a bad stack overflow
mmusante
parents:
3912
diff
changeset
|
1752 |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1753 err = dsl_dataset_snapshot_reserve_space(ds, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1754 if (err) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1755 return (err); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1756 |
2199 | 1757 ds->ds_trysnap_txg = tx->tx_txg; |
789 | 1758 return (0); |
1759 } | |
1760 | |
2199 | 1761 void |
4543 | 1762 dsl_dataset_snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) |
789 | 1763 { |
5367 | 1764 dsl_dataset_t *ds = arg1; |
2199 | 1765 const char *snapname = arg2; |
1766 dsl_pool_t *dp = ds->ds_dir->dd_pool; | |
789 | 1767 dmu_buf_t *dbuf; |
1768 dsl_dataset_phys_t *dsphys; | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1769 uint64_t dsobj, crtxg; |
789 | 1770 objset_t *mos = dp->dp_meta_objset; |
1771 int err; | |
1772 | |
2199 | 1773 ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock)); |
789 | 1774 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1775 /* |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1776 * The origin's ds_creation_txg has to be < TXG_INITIAL |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1777 */ |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1778 if (strcmp(snapname, ORIGIN_DIR_NAME) == 0) |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1779 crtxg = 1; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1780 else |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1781 crtxg = tx->tx_txg; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1782 |
928
36d72fe4da29
6349314 dmu_object_type names incorrect for DSL Directories and DSL Datasets
tabriz
parents:
885
diff
changeset
|
1783 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
|
1784 DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx); |
1544 | 1785 VERIFY(0 == dmu_bonus_hold(mos, dsobj, FTAG, &dbuf)); |
789 | 1786 dmu_buf_will_dirty(dbuf, tx); |
1787 dsphys = dbuf->db_data; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1788 bzero(dsphys, sizeof (dsl_dataset_phys_t)); |
2199 | 1789 dsphys->ds_dir_obj = ds->ds_dir->dd_object; |
789 | 1790 dsphys->ds_fsid_guid = unique_create(); |
1791 (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid, | |
1792 sizeof (dsphys->ds_guid)); | |
1793 dsphys->ds_prev_snap_obj = ds->ds_phys->ds_prev_snap_obj; | |
1794 dsphys->ds_prev_snap_txg = ds->ds_phys->ds_prev_snap_txg; | |
1795 dsphys->ds_next_snap_obj = ds->ds_object; | |
1796 dsphys->ds_num_children = 1; | |
1797 dsphys->ds_creation_time = gethrestime_sec(); | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1798 dsphys->ds_creation_txg = crtxg; |
789 | 1799 dsphys->ds_deadlist_obj = ds->ds_phys->ds_deadlist_obj; |
1800 dsphys->ds_used_bytes = ds->ds_phys->ds_used_bytes; | |
1801 dsphys->ds_compressed_bytes = ds->ds_phys->ds_compressed_bytes; | |
1802 dsphys->ds_uncompressed_bytes = ds->ds_phys->ds_uncompressed_bytes; | |
2082 | 1803 dsphys->ds_flags = ds->ds_phys->ds_flags; |
789 | 1804 dsphys->ds_bp = ds->ds_phys->ds_bp; |
1544 | 1805 dmu_buf_rele(dbuf, FTAG); |
789 | 1806 |
2199 | 1807 ASSERT3U(ds->ds_prev != 0, ==, ds->ds_phys->ds_prev_snap_obj != 0); |
1808 if (ds->ds_prev) { | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1809 uint64_t next_clones_obj = |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1810 ds->ds_prev->ds_phys->ds_next_clones_obj; |
2199 | 1811 ASSERT(ds->ds_prev->ds_phys->ds_next_snap_obj == |
789 | 1812 ds->ds_object || |
2199 | 1813 ds->ds_prev->ds_phys->ds_num_children > 1); |
1814 if (ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) { | |
1815 dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx); | |
789 | 1816 ASSERT3U(ds->ds_phys->ds_prev_snap_txg, ==, |
2199 | 1817 ds->ds_prev->ds_phys->ds_creation_txg); |
1818 ds->ds_prev->ds_phys->ds_next_snap_obj = dsobj; | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1819 } else if (next_clones_obj != 0) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1820 VERIFY3U(0, ==, zap_remove_int(mos, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1821 next_clones_obj, dsphys->ds_next_snap_obj, tx)); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1822 VERIFY3U(0, ==, zap_add_int(mos, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1823 next_clones_obj, dsobj, tx)); |
789 | 1824 } |
1825 } | |
1826 | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1827 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1828 * If we have a reference-reservation on this dataset, we will |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1829 * need to increase the amount of refreservation being charged |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1830 * since our unique space is going to zero. |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1831 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1832 if (ds->ds_reserved) { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1833 int64_t add = MIN(dsl_dataset_unique(ds), ds->ds_reserved); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1834 dsl_dir_diduse_space(ds->ds_dir, add, 0, 0, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1835 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1836 |
789 | 1837 bplist_close(&ds->ds_deadlist); |
1838 dmu_buf_will_dirty(ds->ds_dbuf, tx); | |
5712
81f1af42bafc
6628232 zfs snapshot -r is very slow, causes systemic slowdown
ahrens
parents:
5569
diff
changeset
|
1839 ASSERT3U(ds->ds_phys->ds_prev_snap_txg, <, tx->tx_txg); |
789 | 1840 ds->ds_phys->ds_prev_snap_obj = dsobj; |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1841 ds->ds_phys->ds_prev_snap_txg = crtxg; |
789 | 1842 ds->ds_phys->ds_unique_bytes = 0; |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1843 if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1844 ds->ds_phys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE; |
789 | 1845 ds->ds_phys->ds_deadlist_obj = |
1846 bplist_create(mos, DSL_DEADLIST_BLOCKSIZE, tx); | |
1544 | 1847 VERIFY(0 == bplist_open(&ds->ds_deadlist, mos, |
1848 ds->ds_phys->ds_deadlist_obj)); | |
789 | 1849 |
1850 dprintf("snap '%s' -> obj %llu\n", snapname, dsobj); | |
1851 err = zap_add(mos, ds->ds_phys->ds_snapnames_zapobj, | |
1852 snapname, 8, 1, &dsobj, tx); | |
1853 ASSERT(err == 0); | |
1854 | |
1855 if (ds->ds_prev) | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1856 dsl_dataset_drop_ref(ds->ds_prev, ds); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1857 VERIFY(0 == dsl_dataset_get_ref(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1858 ds->ds_phys->ds_prev_snap_obj, ds, &ds->ds_prev)); |
4543 | 1859 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1860 dsl_pool_ds_snapshotted(ds, tx); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1861 |
4543 | 1862 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
|
1863 "dataset = %llu", dsobj); |
789 | 1864 } |
1865 | |
1866 void | |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
1867 dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx) |
789 | 1868 { |
1869 ASSERT(dmu_tx_is_syncing(tx)); | |
1870 ASSERT(ds->ds_user_ptr != NULL); | |
1871 ASSERT(ds->ds_phys->ds_next_snap_obj == 0); | |
1872 | |
4787 | 1873 /* |
1874 * in case we had to change ds_fsid_guid when we opened it, | |
1875 * sync it out now. | |
1876 */ | |
1877 dmu_buf_will_dirty(ds->ds_dbuf, tx); | |
1878 ds->ds_phys->ds_fsid_guid = ds->ds_fsid_guid; | |
1879 | |
789 | 1880 dsl_dir_dirty(ds->ds_dir, tx); |
3547
e396e0a440b1
6512391 DMU should leverage ZIO dependencies to achieve greater parallelism
maybee
parents:
3444
diff
changeset
|
1881 dmu_objset_sync(ds->ds_user_ptr, zio, tx); |
789 | 1882 } |
1883 | |
1884 void | |
2885 | 1885 dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv) |
789 | 1886 { |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1887 uint64_t refd, avail, uobjs, aobjs; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1888 |
2885 | 1889 dsl_dir_stats(ds->ds_dir, nv); |
789 | 1890 |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1891 dsl_dataset_space(ds, &refd, &avail, &uobjs, &aobjs); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1892 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_AVAILABLE, avail); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1893 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFERENCED, refd); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1894 |
2885 | 1895 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_CREATION, |
1896 ds->ds_phys->ds_creation_time); | |
1897 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_CREATETXG, | |
1898 ds->ds_phys->ds_creation_txg); | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1899 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFQUOTA, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1900 ds->ds_quota); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1901 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRESERVATION, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1902 ds->ds_reserved); |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6502
diff
changeset
|
1903 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_GUID, |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6502
diff
changeset
|
1904 ds->ds_phys->ds_guid); |
789 | 1905 |
1906 if (ds->ds_phys->ds_next_snap_obj) { | |
1907 /* | |
1908 * This is a snapshot; override the dd's space used with | |
2885 | 1909 * our unique space and compression ratio. |
789 | 1910 */ |
2885 | 1911 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, |
1912 ds->ds_phys->ds_unique_bytes); | |
1913 dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, | |
1914 ds->ds_phys->ds_compressed_bytes == 0 ? 100 : | |
1915 (ds->ds_phys->ds_uncompressed_bytes * 100 / | |
1916 ds->ds_phys->ds_compressed_bytes)); | |
789 | 1917 } |
1918 } | |
1919 | |
2885 | 1920 void |
1921 dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat) | |
789 | 1922 { |
2885 | 1923 stat->dds_creation_txg = ds->ds_phys->ds_creation_txg; |
1924 stat->dds_inconsistent = ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT; | |
5367 | 1925 stat->dds_guid = ds->ds_phys->ds_guid; |
2885 | 1926 if (ds->ds_phys->ds_next_snap_obj) { |
1927 stat->dds_is_snapshot = B_TRUE; | |
1928 stat->dds_num_clones = ds->ds_phys->ds_num_children - 1; | |
1929 } | |
1930 | |
1931 /* clone origin is really a dsl_dir thing... */ | |
5446 | 1932 rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER); |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1933 if (dsl_dir_is_clone(ds->ds_dir)) { |
2885 | 1934 dsl_dataset_t *ods; |
1935 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1936 VERIFY(0 == dsl_dataset_get_ref(ds->ds_dir->dd_pool, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1937 ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &ods)); |
5367 | 1938 dsl_dataset_name(ods, stat->dds_origin); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1939 dsl_dataset_drop_ref(ods, FTAG); |
2885 | 1940 } |
5446 | 1941 rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock); |
2885 | 1942 } |
1943 | |
1944 uint64_t | |
1945 dsl_dataset_fsid_guid(dsl_dataset_t *ds) | |
1946 { | |
4787 | 1947 return (ds->ds_fsid_guid); |
2885 | 1948 } |
1949 | |
1950 void | |
1951 dsl_dataset_space(dsl_dataset_t *ds, | |
1952 uint64_t *refdbytesp, uint64_t *availbytesp, | |
1953 uint64_t *usedobjsp, uint64_t *availobjsp) | |
1954 { | |
1955 *refdbytesp = ds->ds_phys->ds_used_bytes; | |
1956 *availbytesp = dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE); | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1957 if (ds->ds_reserved > ds->ds_phys->ds_unique_bytes) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1958 *availbytesp += ds->ds_reserved - ds->ds_phys->ds_unique_bytes; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1959 if (ds->ds_quota != 0) { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1960 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1961 * Adjust available bytes according to refquota |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1962 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1963 if (*refdbytesp < ds->ds_quota) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1964 *availbytesp = MIN(*availbytesp, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1965 ds->ds_quota - *refdbytesp); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1966 else |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1967 *availbytesp = 0; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
1968 } |
2885 | 1969 *usedobjsp = ds->ds_phys->ds_bp.blk_fill; |
1970 *availobjsp = DN_MAX_OBJECT - *usedobjsp; | |
789 | 1971 } |
1972 | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1973 boolean_t |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1974 dsl_dataset_modified_since_lastsnap(dsl_dataset_t *ds) |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1975 { |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1976 dsl_pool_t *dp = ds->ds_dir->dd_pool; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1977 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1978 ASSERT(RW_LOCK_HELD(&dp->dp_config_rwlock) || |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1979 dsl_pool_sync_context(dp)); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1980 if (ds->ds_prev == NULL) |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1981 return (B_FALSE); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1982 if (ds->ds_phys->ds_bp.blk_birth > |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1983 ds->ds_prev->ds_phys->ds_creation_txg) |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1984 return (B_TRUE); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1985 return (B_FALSE); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1986 } |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
1987 |
2199 | 1988 /* ARGSUSED */ |
789 | 1989 static int |
2199 | 1990 dsl_dataset_snapshot_rename_check(void *arg1, void *arg2, dmu_tx_t *tx) |
789 | 1991 { |
2199 | 1992 dsl_dataset_t *ds = arg1; |
1993 char *newsnapname = arg2; | |
1994 dsl_dir_t *dd = ds->ds_dir; | |
1995 dsl_dataset_t *hds; | |
1996 uint64_t val; | |
789 | 1997 int err; |
1998 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1999 err = dsl_dataset_hold_obj(dd->dd_pool, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2000 dd->dd_phys->dd_head_dataset_obj, FTAG, &hds); |
789 | 2001 if (err) |
2002 return (err); | |
2003 | |
2199 | 2004 /* new name better not be in use */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2005 err = dsl_dataset_snap_lookup(hds, newsnapname, &val); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2006 dsl_dataset_rele(hds, FTAG); |
789 | 2007 |
2199 | 2008 if (err == 0) |
2009 err = EEXIST; | |
2010 else if (err == ENOENT) | |
2011 err = 0; | |
4007 | 2012 |
2013 /* dataset name + 1 for the "@" + the new snapshot name must fit */ | |
2014 if (dsl_dir_namelen(ds->ds_dir) + 1 + strlen(newsnapname) >= MAXNAMELEN) | |
2015 err = ENAMETOOLONG; | |
2016 | |
2199 | 2017 return (err); |
2018 } | |
789 | 2019 |
2199 | 2020 static void |
4543 | 2021 dsl_dataset_snapshot_rename_sync(void *arg1, void *arg2, |
2022 cred_t *cr, dmu_tx_t *tx) | |
2199 | 2023 { |
2024 dsl_dataset_t *ds = arg1; | |
4543 | 2025 const char *newsnapname = arg2; |
2199 | 2026 dsl_dir_t *dd = ds->ds_dir; |
2027 objset_t *mos = dd->dd_pool->dp_meta_objset; | |
2028 dsl_dataset_t *hds; | |
2029 int err; | |
789 | 2030 |
2199 | 2031 ASSERT(ds->ds_phys->ds_next_snap_obj != 0); |
789 | 2032 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2033 VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2034 dd->dd_phys->dd_head_dataset_obj, FTAG, &hds)); |
789 | 2035 |
2199 | 2036 VERIFY(0 == dsl_dataset_get_snapname(ds)); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2037 err = dsl_dataset_snap_remove(hds, ds->ds_snapname, tx); |
789 | 2038 ASSERT3U(err, ==, 0); |
2199 | 2039 mutex_enter(&ds->ds_lock); |
2040 (void) strcpy(ds->ds_snapname, newsnapname); | |
2041 mutex_exit(&ds->ds_lock); | |
2042 err = zap_add(mos, hds->ds_phys->ds_snapnames_zapobj, | |
2043 ds->ds_snapname, 8, 1, &ds->ds_object, tx); | |
789 | 2044 ASSERT3U(err, ==, 0); |
2045 | |
4543 | 2046 spa_history_internal_log(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx, |
2047 cr, "dataset = %llu", ds->ds_object); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2048 dsl_dataset_rele(hds, FTAG); |
789 | 2049 } |
2050 | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2051 struct renamesnaparg { |
4007 | 2052 dsl_sync_task_group_t *dstg; |
2053 char failed[MAXPATHLEN]; | |
2054 char *oldsnap; | |
2055 char *newsnap; | |
2056 }; | |
2057 | |
2058 static int | |
2059 dsl_snapshot_rename_one(char *name, void *arg) | |
2060 { | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2061 struct renamesnaparg *ra = arg; |
4007 | 2062 dsl_dataset_t *ds = NULL; |
2063 char *cp; | |
2064 int err; | |
2065 | |
2066 cp = name + strlen(name); | |
2067 *cp = '@'; | |
2068 (void) strcpy(cp + 1, ra->oldsnap); | |
4543 | 2069 |
2070 /* | |
2071 * For recursive snapshot renames the parent won't be changing | |
2072 * so we just pass name for both the to/from argument. | |
2073 */ | |
7312
3992f9a413c2
6736061 recursive rename of snapshot fails if child snapshot doesn't exist
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
7265
diff
changeset
|
2074 err = zfs_secpolicy_rename_perms(name, name, CRED()); |
3992f9a413c2
6736061 recursive rename of snapshot fails if child snapshot doesn't exist
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
7265
diff
changeset
|
2075 if (err == ENOENT) { |
3992f9a413c2
6736061 recursive rename of snapshot fails if child snapshot doesn't exist
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
7265
diff
changeset
|
2076 return (0); |
3992f9a413c2
6736061 recursive rename of snapshot fails if child snapshot doesn't exist
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
7265
diff
changeset
|
2077 } else if (err) { |
4543 | 2078 (void) strcpy(ra->failed, name); |
2079 return (err); | |
2080 } | |
2081 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2082 #ifdef _KERNEL |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2083 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2084 * For all filesystems undergoing rename, we'll need to unmount it. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2085 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2086 (void) zfs_unmount_snap(name, NULL); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2087 #endif |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2088 err = dsl_dataset_hold(name, ra->dstg, &ds); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2089 *cp = '\0'; |
4007 | 2090 if (err == ENOENT) { |
2091 return (0); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2092 } else if (err) { |
4007 | 2093 (void) strcpy(ra->failed, name); |
2094 return (err); | |
2095 } | |
2096 | |
2097 dsl_sync_task_create(ra->dstg, dsl_dataset_snapshot_rename_check, | |
2098 dsl_dataset_snapshot_rename_sync, ds, ra->newsnap, 0); | |
2099 | |
2100 return (0); | |
2101 } | |
2102 | |
2103 static int | |
2104 dsl_recursive_rename(char *oldname, const char *newname) | |
2105 { | |
2106 int err; | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2107 struct renamesnaparg *ra; |
4007 | 2108 dsl_sync_task_t *dst; |
2109 spa_t *spa; | |
2110 char *cp, *fsname = spa_strdup(oldname); | |
2111 int len = strlen(oldname); | |
2112 | |
2113 /* truncate the snapshot name to get the fsname */ | |
2114 cp = strchr(fsname, '@'); | |
2115 *cp = '\0'; | |
2116 | |
4603
c7840c367d00
6494569 zfs recv -d pool/<doesn't exist> core dumps for top-level filesystem backups
ahrens
parents:
4577
diff
changeset
|
2117 err = spa_open(fsname, &spa, FTAG); |
4007 | 2118 if (err) { |
2119 kmem_free(fsname, len + 1); | |
2120 return (err); | |
2121 } | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2122 ra = kmem_alloc(sizeof (struct renamesnaparg), KM_SLEEP); |
4007 | 2123 ra->dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); |
2124 | |
2125 ra->oldsnap = strchr(oldname, '@') + 1; | |
2126 ra->newsnap = strchr(newname, '@') + 1; | |
2127 *ra->failed = '\0'; | |
2128 | |
2129 err = dmu_objset_find(fsname, dsl_snapshot_rename_one, ra, | |
2130 DS_FIND_CHILDREN); | |
2131 kmem_free(fsname, len + 1); | |
2132 | |
2133 if (err == 0) { | |
2134 err = dsl_sync_task_group_wait(ra->dstg); | |
2135 } | |
2136 | |
2137 for (dst = list_head(&ra->dstg->dstg_tasks); dst; | |
2138 dst = list_next(&ra->dstg->dstg_tasks, dst)) { | |
2139 dsl_dataset_t *ds = dst->dst_arg1; | |
2140 if (dst->dst_err) { | |
2141 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
|
2142 (void) strcat(ra->failed, "@"); |
1a9b4fbc0d2a
6479884 want 'zfs rename -r' to recursively rename snapshots (fix lint)
mmusante
parents:
4007
diff
changeset
|
2143 (void) strcat(ra->failed, ra->newsnap); |
4007 | 2144 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2145 dsl_dataset_rele(ds, ra->dstg); |
4007 | 2146 } |
2147 | |
4543 | 2148 if (err) |
2149 (void) strcpy(oldname, ra->failed); | |
4007 | 2150 |
2151 dsl_sync_task_group_destroy(ra->dstg); | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2152 kmem_free(ra, sizeof (struct renamesnaparg)); |
4007 | 2153 spa_close(spa, FTAG); |
2154 return (err); | |
2155 } | |
2156 | |
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
|
2157 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
|
2158 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
|
2159 { |
e80d40447f27
6355623 zfs rename to a valid dataset name, but its snapshot name becomes too long, panics the system
mmusante
parents:
4543
diff
changeset
|
2160 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
|
2161 |
e80d40447f27
6355623 zfs rename to a valid dataset name, but its snapshot name becomes too long, panics the system
mmusante
parents:
4543
diff
changeset
|
2162 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
|
2163 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
|
2164 |
e80d40447f27
6355623 zfs rename to a valid dataset name, but its snapshot name becomes too long, panics the system
mmusante
parents:
4543
diff
changeset
|
2165 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
|
2166 } |
e80d40447f27
6355623 zfs rename to a valid dataset name, but its snapshot name becomes too long, panics the system
mmusante
parents:
4543
diff
changeset
|
2167 |
789 | 2168 #pragma weak dmu_objset_rename = dsl_dataset_rename |
2169 int | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2170 dsl_dataset_rename(char *oldname, const char *newname, boolean_t recursive) |
789 | 2171 { |
2172 dsl_dir_t *dd; | |
2199 | 2173 dsl_dataset_t *ds; |
789 | 2174 const char *tail; |
2175 int err; | |
2176 | |
2199 | 2177 err = dsl_dir_open(oldname, FTAG, &dd, &tail); |
1544 | 2178 if (err) |
2179 return (err); | |
789 | 2180 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
|
2181 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
|
2182 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2183 /* if we're growing, validate child name lengths */ |
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
|
2184 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
|
2185 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
|
2186 &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
|
2187 |
e80d40447f27
6355623 zfs rename to a valid dataset name, but its snapshot name becomes too long, panics the system
mmusante
parents:
4543
diff
changeset
|
2188 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
|
2189 err = dsl_dir_rename(dd, newname); |
789 | 2190 dsl_dir_close(dd, FTAG); |
2191 return (err); | |
2192 } | |
2193 if (tail[0] != '@') { | |
2194 /* the name ended in a nonexistant component */ | |
2195 dsl_dir_close(dd, FTAG); | |
2196 return (ENOENT); | |
2197 } | |
2198 | |
2199 | 2199 dsl_dir_close(dd, FTAG); |
2200 | |
2201 /* new name must be snapshot in same filesystem */ | |
2202 tail = strchr(newname, '@'); | |
2203 if (tail == NULL) | |
2204 return (EINVAL); | |
2205 tail++; | |
2206 if (strncmp(oldname, newname, tail - newname) != 0) | |
2207 return (EXDEV); | |
789 | 2208 |
4007 | 2209 if (recursive) { |
2210 err = dsl_recursive_rename(oldname, newname); | |
2211 } else { | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2212 err = dsl_dataset_hold(oldname, FTAG, &ds); |
4007 | 2213 if (err) |
2214 return (err); | |
2199 | 2215 |
4007 | 2216 err = dsl_sync_task_do(ds->ds_dir->dd_pool, |
2217 dsl_dataset_snapshot_rename_check, | |
2218 dsl_dataset_snapshot_rename_sync, ds, (char *)tail, 1); | |
2199 | 2219 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2220 dsl_dataset_rele(ds, FTAG); |
4007 | 2221 } |
2199 | 2222 |
789 | 2223 return (err); |
2224 } | |
2082 | 2225 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2226 struct promotenode { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2227 list_node_t link; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2228 dsl_dataset_t *ds; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2229 }; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2230 |
2199 | 2231 struct promotearg { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2232 list_t snap_list; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2233 dsl_dataset_t *clone_origin, *old_head; |
2199 | 2234 uint64_t used, comp, uncomp, unique; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2235 uint64_t newnext_obj; |
2199 | 2236 }; |
2237 | |
4543 | 2238 /* ARGSUSED */ |
2082 | 2239 static int |
2199 | 2240 dsl_dataset_promote_check(void *arg1, void *arg2, dmu_tx_t *tx) |
2082 | 2241 { |
2199 | 2242 dsl_dataset_t *hds = arg1; |
2243 struct promotearg *pa = arg2; | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2244 struct promotenode *snap = list_head(&pa->snap_list); |
2199 | 2245 dsl_pool_t *dp = hds->ds_dir->dd_pool; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2246 dsl_dataset_t *origin_ds = snap->ds; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2247 dsl_dataset_t *newnext_ds; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2248 char *name; |
2199 | 2249 uint64_t itor = 0; |
2082 | 2250 blkptr_t bp; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2251 int err; |
2199 | 2252 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2253 /* Check that it is a real clone */ |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2254 if (!dsl_dir_is_clone(hds->ds_dir)) |
2082 | 2255 return (EINVAL); |
2256 | |
2199 | 2257 /* Since this is so expensive, don't do the preliminary check */ |
2258 if (!dmu_tx_is_syncing(tx)) | |
2259 return (0); | |
2260 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2261 if (hds->ds_phys->ds_flags & DS_FLAG_NOPROMOTE) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2262 return (EXDEV); |
2082 | 2263 |
5367 | 2264 /* find origin's new next ds */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2265 newnext_ds = hds; |
5367 | 2266 while (newnext_ds->ds_phys->ds_prev_snap_obj != origin_ds->ds_object) { |
2082 | 2267 dsl_dataset_t *prev; |
2268 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2269 err = dsl_dataset_hold_obj(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2270 newnext_ds->ds_phys->ds_prev_snap_obj, FTAG, &prev); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2271 if (newnext_ds != hds) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2272 dsl_dataset_rele(newnext_ds, FTAG); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2273 if (err) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2274 return (err); |
2082 | 2275 newnext_ds = prev; |
2276 } | |
2199 | 2277 pa->newnext_obj = newnext_ds->ds_object; |
2082 | 2278 |
5367 | 2279 /* compute origin's new unique space */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2280 pa->unique = 0; |
2082 | 2281 while ((err = bplist_iterate(&newnext_ds->ds_deadlist, |
2282 &itor, &bp)) == 0) { | |
5367 | 2283 if (bp.blk_birth > origin_ds->ds_phys->ds_prev_snap_txg) |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2284 pa->unique += bp_get_dasize(dp->dp_spa, &bp); |
2082 | 2285 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2286 if (newnext_ds != hds) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2287 dsl_dataset_rele(newnext_ds, FTAG); |
2082 | 2288 if (err != ENOENT) |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2289 return (err); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2290 |
2082 | 2291 name = kmem_alloc(MAXPATHLEN, KM_SLEEP); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2292 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2293 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2294 * Walk the snapshots that we are moving |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2295 * |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2296 * Compute space to transfer. Each snapshot gave birth to: |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2297 * (my used) - (prev's used) + (deadlist's used) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2298 * So a sequence would look like: |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2299 * uN - u(N-1) + dN + ... + u1 - u0 + d1 + u0 - 0 + d0 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2300 * Which simplifies to: |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2301 * uN + dN + ... + d1 + d0 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2302 * Note however, if we stop before we reach the ORIGIN we get: |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2303 * uN + dN + ... + dM - uM-1 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2304 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2305 pa->used = origin_ds->ds_phys->ds_used_bytes; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2306 pa->comp = origin_ds->ds_phys->ds_compressed_bytes; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2307 pa->uncomp = origin_ds->ds_phys->ds_uncompressed_bytes; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2308 do { |
2082 | 2309 uint64_t val, dlused, dlcomp, dluncomp; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2310 dsl_dataset_t *ds = snap->ds; |
2082 | 2311 |
2312 /* Check that the snapshot name does not conflict */ | |
2313 dsl_dataset_name(ds, name); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2314 err = dsl_dataset_snap_lookup(hds, ds->ds_snapname, &val); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2315 if (err == 0) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2316 err = EEXIST; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2317 if (err != ENOENT) |
2082 | 2318 break; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2319 err = 0; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2320 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2321 /* The very first snapshot does not have a deadlist */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2322 if (ds->ds_phys->ds_prev_snap_obj != 0) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2323 if (err = bplist_space(&ds->ds_deadlist, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2324 &dlused, &dlcomp, &dluncomp)) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2325 break; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2326 pa->used += dlused; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2327 pa->comp += dlcomp; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2328 pa->uncomp += dluncomp; |
2082 | 2329 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2330 } while (snap = list_next(&pa->snap_list, snap)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2331 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2332 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2333 * If we are a clone of a clone then we never reached ORIGIN, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2334 * so we need to subtract out the clone origin's used space. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2335 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2336 if (pa->clone_origin) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2337 pa->used -= pa->clone_origin->ds_phys->ds_used_bytes; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2338 pa->comp -= pa->clone_origin->ds_phys->ds_compressed_bytes; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2339 pa->uncomp -= pa->clone_origin->ds_phys->ds_uncompressed_bytes; |
2082 | 2340 } |
2341 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2342 kmem_free(name, MAXPATHLEN); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2343 |
2082 | 2344 /* Check that there is enough space here */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2345 if (err == 0) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2346 dsl_dir_t *odd = origin_ds->ds_dir; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2347 err = dsl_dir_transfer_possible(odd, hds->ds_dir, pa->used); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2348 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2349 |
2199 | 2350 return (err); |
2351 } | |
2082 | 2352 |
2199 | 2353 static void |
4543 | 2354 dsl_dataset_promote_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) |
2199 | 2355 { |
2356 dsl_dataset_t *hds = arg1; | |
2357 struct promotearg *pa = arg2; | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2358 struct promotenode *snap = list_head(&pa->snap_list); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2359 dsl_dataset_t *origin_ds = snap->ds; |
2199 | 2360 dsl_dir_t *dd = hds->ds_dir; |
2361 dsl_pool_t *dp = hds->ds_dir->dd_pool; | |
5367 | 2362 dsl_dir_t *odd = NULL; |
2199 | 2363 char *name; |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2364 uint64_t oldnext_obj; |
2199 | 2365 |
2366 ASSERT(0 == (hds->ds_phys->ds_flags & DS_FLAG_NOPROMOTE)); | |
2367 | |
2417 | 2368 /* |
5367 | 2369 * We need to explicitly open odd, since origin_ds's dd will be |
2417 | 2370 * changing. |
2371 */ | |
5367 | 2372 VERIFY(0 == dsl_dir_open_obj(dp, origin_ds->ds_dir->dd_object, |
2373 NULL, FTAG, &odd)); | |
2082 | 2374 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2375 /* change origin's next snap */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2376 dmu_buf_will_dirty(origin_ds->ds_dbuf, tx); |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2377 oldnext_obj = origin_ds->ds_phys->ds_next_snap_obj; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2378 origin_ds->ds_phys->ds_next_snap_obj = pa->newnext_obj; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2379 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2380 /* change the origin's next clone */ |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2381 if (origin_ds->ds_phys->ds_next_clones_obj) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2382 VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2383 origin_ds->ds_phys->ds_next_clones_obj, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2384 pa->newnext_obj, tx)); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2385 VERIFY3U(0, ==, zap_add_int(dp->dp_meta_objset, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2386 origin_ds->ds_phys->ds_next_clones_obj, |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2387 oldnext_obj, tx)); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2388 } |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2389 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2390 /* change origin */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2391 dmu_buf_will_dirty(dd->dd_dbuf, tx); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2392 ASSERT3U(dd->dd_phys->dd_origin_obj, ==, origin_ds->ds_object); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2393 dd->dd_phys->dd_origin_obj = odd->dd_phys->dd_origin_obj; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2394 dmu_buf_will_dirty(odd->dd_dbuf, tx); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2395 odd->dd_phys->dd_origin_obj = origin_ds->ds_object; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2396 |
2082 | 2397 /* move snapshots to this dir */ |
2199 | 2398 name = kmem_alloc(MAXPATHLEN, KM_SLEEP); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2399 do { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2400 dsl_dataset_t *ds = snap->ds; |
2082 | 2401 |
7237
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
2402 /* unregister props as dsl_dir is changing */ |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
2403 if (ds->ds_user_ptr) { |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
2404 ds->ds_user_evict_func(ds, ds->ds_user_ptr); |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
2405 ds->ds_user_ptr = NULL; |
f47d41541b14
PSARC 2008/393 zfs primarycache and secondarycache properties
ek110237
parents:
7077
diff
changeset
|
2406 } |
2082 | 2407 /* move snap name entry */ |
2408 dsl_dataset_name(ds, name); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2409 VERIFY(0 == dsl_dataset_snap_remove(pa->old_head, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2410 ds->ds_snapname, tx)); |
2199 | 2411 VERIFY(0 == zap_add(dp->dp_meta_objset, |
2082 | 2412 hds->ds_phys->ds_snapnames_zapobj, ds->ds_snapname, |
2413 8, 1, &ds->ds_object, tx)); | |
2414 /* change containing dsl_dir */ | |
2415 dmu_buf_will_dirty(ds->ds_dbuf, tx); | |
5367 | 2416 ASSERT3U(ds->ds_phys->ds_dir_obj, ==, odd->dd_object); |
2082 | 2417 ds->ds_phys->ds_dir_obj = dd->dd_object; |
5367 | 2418 ASSERT3P(ds->ds_dir, ==, odd); |
2082 | 2419 dsl_dir_close(ds->ds_dir, ds); |
2199 | 2420 VERIFY(0 == dsl_dir_open_obj(dp, dd->dd_object, |
2082 | 2421 NULL, ds, &ds->ds_dir)); |
2422 | |
2423 ASSERT3U(dsl_prop_numcb(ds), ==, 0); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2424 } while (snap = list_next(&pa->snap_list, snap)); |
2082 | 2425 |
2426 /* change space accounting */ | |
5367 | 2427 dsl_dir_diduse_space(odd, -pa->used, -pa->comp, -pa->uncomp, tx); |
2199 | 2428 dsl_dir_diduse_space(dd, pa->used, pa->comp, pa->uncomp, tx); |
5367 | 2429 origin_ds->ds_phys->ds_unique_bytes = pa->unique; |
2082 | 2430 |
4543 | 2431 /* log history record */ |
2432 spa_history_internal_log(LOG_DS_PROMOTE, dd->dd_pool->dp_spa, tx, | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2433 cr, "dataset = %llu", hds->ds_object); |
4543 | 2434 |
5367 | 2435 dsl_dir_close(odd, FTAG); |
2199 | 2436 kmem_free(name, MAXPATHLEN); |
2082 | 2437 } |
2438 | |
2439 int | |
2440 dsl_dataset_promote(const char *name) | |
2441 { | |
2442 dsl_dataset_t *ds; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2443 dsl_dir_t *dd; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2444 dsl_pool_t *dp; |
2082 | 2445 dmu_object_info_t doi; |
2199 | 2446 struct promotearg pa; |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2447 struct promotenode *snap; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2448 uint64_t snap_obj; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2449 uint64_t last_snap = 0; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2450 int err; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2451 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2452 err = dsl_dataset_hold(name, FTAG, &ds); |
2082 | 2453 if (err) |
2454 return (err); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2455 dd = ds->ds_dir; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2456 dp = dd->dd_pool; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2457 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2458 err = dmu_object_info(dp->dp_meta_objset, |
2082 | 2459 ds->ds_phys->ds_snapnames_zapobj, &doi); |
2460 if (err) { | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2461 dsl_dataset_rele(ds, FTAG); |
2082 | 2462 return (err); |
2463 } | |
2464 | |
2465 /* | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2466 * We are going to inherit all the snapshots taken before our |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2467 * origin (i.e., our new origin will be our parent's origin). |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2468 * Take ownership of them so that we can rename them into our |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2469 * namespace. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2470 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2471 pa.clone_origin = NULL; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2472 list_create(&pa.snap_list, |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2473 sizeof (struct promotenode), offsetof(struct promotenode, link)); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2474 rw_enter(&dp->dp_config_rwlock, RW_READER); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2475 ASSERT(dd->dd_phys->dd_origin_obj != 0); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2476 snap_obj = dd->dd_phys->dd_origin_obj; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2477 while (snap_obj) { |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2478 dsl_dataset_t *snapds; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2479 |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2480 /* |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2481 * NB: this would be handled by the below check for |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2482 * clone of a clone, but then we'd always own_obj() the |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2483 * $ORIGIN, thus causing unnecessary EBUSYs. We don't |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2484 * need to set pa.clone_origin because the $ORIGIN has |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2485 * no data to account for. |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2486 */ |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2487 if (dp->dp_origin_snap && |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2488 snap_obj == dp->dp_origin_snap->ds_object) |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2489 break; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2490 |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2491 err = dsl_dataset_own_obj(dp, snap_obj, 0, FTAG, &snapds); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2492 if (err == ENOENT) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2493 /* lost race with snapshot destroy */ |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2494 struct promotenode *last = list_tail(&pa.snap_list); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2495 ASSERT(snap_obj != last->ds->ds_phys->ds_prev_snap_obj); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2496 snap_obj = last->ds->ds_phys->ds_prev_snap_obj; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2497 continue; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2498 } else if (err) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2499 rw_exit(&dp->dp_config_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2500 goto out; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2501 } |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2502 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2503 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2504 * We could be a clone of a clone. If we reach our |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2505 * parent's branch point, we're done. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2506 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2507 if (last_snap && |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2508 snapds->ds_phys->ds_next_snap_obj != last_snap) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2509 pa.clone_origin = snapds; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2510 break; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2511 } |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2512 |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2513 snap = kmem_alloc(sizeof (struct promotenode), KM_SLEEP); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2514 snap->ds = snapds; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2515 list_insert_tail(&pa.snap_list, snap); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2516 last_snap = snap_obj; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2517 snap_obj = snap->ds->ds_phys->ds_prev_snap_obj; |
7385
f69ff8507427
6727817 ZFS assertion failure (zero length arc_buf_alloc) during NFS I/O
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
7312
diff
changeset
|
2518 dsl_dataset_make_exclusive(snapds, FTAG); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2519 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2520 snap = list_head(&pa.snap_list); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2521 ASSERT(snap != NULL); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2522 err = dsl_dataset_hold_obj(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2523 snap->ds->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &pa.old_head); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2524 rw_exit(&dp->dp_config_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2525 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2526 if (err) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2527 goto out; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2528 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2529 /* |
2082 | 2530 * Add in 128x the snapnames zapobj size, since we will be moving |
2531 * a bunch of snapnames to the promoted ds, and dirtying their | |
2532 * bonus buffers. | |
2533 */ | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2534 err = dsl_sync_task_do(dp, dsl_dataset_promote_check, |
2199 | 2535 dsl_dataset_promote_sync, ds, &pa, 2 + 2 * doi.doi_physical_blks); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2536 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2537 dsl_dataset_rele(pa.old_head, FTAG); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2538 out: |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2539 while ((snap = list_tail(&pa.snap_list)) != NULL) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2540 list_remove(&pa.snap_list, snap); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2541 dsl_dataset_disown(snap->ds, FTAG); |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
2542 kmem_free(snap, sizeof (struct promotenode)); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2543 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2544 list_destroy(&pa.snap_list); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2545 if (pa.clone_origin) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2546 dsl_dataset_disown(pa.clone_origin, FTAG); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2547 dsl_dataset_rele(ds, FTAG); |
2082 | 2548 return (err); |
2549 } | |
3912 | 2550 |
5367 | 2551 struct cloneswaparg { |
2552 dsl_dataset_t *cds; /* clone dataset */ | |
2553 dsl_dataset_t *ohds; /* origin's head dataset */ | |
2554 boolean_t force; | |
5481
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2555 int64_t unused_refres_delta; /* change in unconsumed refreservation */ |
5367 | 2556 }; |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2557 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2558 /* ARGSUSED */ |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2559 static int |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2560 dsl_dataset_clone_swap_check(void *arg1, void *arg2, dmu_tx_t *tx) |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2561 { |
5367 | 2562 struct cloneswaparg *csa = arg1; |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2563 |
5367 | 2564 /* they should both be heads */ |
2565 if (dsl_dataset_is_snapshot(csa->cds) || | |
2566 dsl_dataset_is_snapshot(csa->ohds)) | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2567 return (EINVAL); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2568 |
5367 | 2569 /* the branch point should be just before them */ |
2570 if (csa->cds->ds_prev != csa->ohds->ds_prev) | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2571 return (EINVAL); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2572 |
5367 | 2573 /* cds should be the clone */ |
2574 if (csa->cds->ds_prev->ds_phys->ds_next_snap_obj != | |
2575 csa->ohds->ds_object) | |
2576 return (EINVAL); | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2577 |
5367 | 2578 /* the clone should be a child of the origin */ |
2579 if (csa->cds->ds_dir->dd_parent != csa->ohds->ds_dir) | |
2580 return (EINVAL); | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2581 |
5367 | 2582 /* ohds shouldn't be modified unless 'force' */ |
2583 if (!csa->force && dsl_dataset_modified_since_lastsnap(csa->ohds)) | |
2584 return (ETXTBSY); | |
5481
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2585 |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2586 /* adjust amount of any unconsumed refreservation */ |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2587 csa->unused_refres_delta = |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2588 (int64_t)MIN(csa->ohds->ds_reserved, |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2589 csa->ohds->ds_phys->ds_unique_bytes) - |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2590 (int64_t)MIN(csa->ohds->ds_reserved, |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2591 csa->cds->ds_phys->ds_unique_bytes); |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2592 |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2593 if (csa->unused_refres_delta > 0 && |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2594 csa->unused_refres_delta > |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2595 dsl_dir_space_available(csa->ohds->ds_dir, NULL, 0, TRUE)) |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2596 return (ENOSPC); |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2597 |
5367 | 2598 return (0); |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2599 } |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2600 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2601 /* ARGSUSED */ |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2602 static void |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2603 dsl_dataset_clone_swap_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2604 { |
5367 | 2605 struct cloneswaparg *csa = arg1; |
2606 dsl_pool_t *dp = csa->cds->ds_dir->dd_pool; | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2607 uint64_t itor = 0; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2608 blkptr_t bp; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2609 uint64_t unique = 0; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2610 int err; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2611 |
5481
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2612 ASSERT(csa->cds->ds_reserved == 0); |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2613 ASSERT(csa->cds->ds_quota == csa->ohds->ds_quota); |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2614 |
5367 | 2615 dmu_buf_will_dirty(csa->cds->ds_dbuf, tx); |
2616 dmu_buf_will_dirty(csa->ohds->ds_dbuf, tx); | |
2617 dmu_buf_will_dirty(csa->cds->ds_prev->ds_dbuf, tx); | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2618 |
5367 | 2619 if (csa->cds->ds_user_ptr != NULL) { |
2620 csa->cds->ds_user_evict_func(csa->cds, csa->cds->ds_user_ptr); | |
2621 csa->cds->ds_user_ptr = NULL; | |
2622 } | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2623 |
5367 | 2624 if (csa->ohds->ds_user_ptr != NULL) { |
2625 csa->ohds->ds_user_evict_func(csa->ohds, | |
2626 csa->ohds->ds_user_ptr); | |
2627 csa->ohds->ds_user_ptr = NULL; | |
2628 } | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2629 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2630 /* compute unique space */ |
5367 | 2631 while ((err = bplist_iterate(&csa->cds->ds_deadlist, |
2632 &itor, &bp)) == 0) { | |
2633 if (bp.blk_birth > csa->cds->ds_prev->ds_phys->ds_prev_snap_txg) | |
2634 unique += bp_get_dasize(dp->dp_spa, &bp); | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2635 } |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2636 VERIFY(err == ENOENT); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2637 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2638 /* reset origin's unique bytes */ |
5367 | 2639 csa->cds->ds_prev->ds_phys->ds_unique_bytes = unique; |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2640 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2641 /* swap blkptrs */ |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2642 { |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2643 blkptr_t tmp; |
5367 | 2644 tmp = csa->ohds->ds_phys->ds_bp; |
2645 csa->ohds->ds_phys->ds_bp = csa->cds->ds_phys->ds_bp; | |
2646 csa->cds->ds_phys->ds_bp = tmp; | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2647 } |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2648 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2649 /* set dd_*_bytes */ |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2650 { |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2651 int64_t dused, dcomp, duncomp; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2652 uint64_t cdl_used, cdl_comp, cdl_uncomp; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2653 uint64_t odl_used, odl_comp, odl_uncomp; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2654 |
5367 | 2655 VERIFY(0 == bplist_space(&csa->cds->ds_deadlist, &cdl_used, |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2656 &cdl_comp, &cdl_uncomp)); |
5367 | 2657 VERIFY(0 == bplist_space(&csa->ohds->ds_deadlist, &odl_used, |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2658 &odl_comp, &odl_uncomp)); |
5367 | 2659 dused = csa->cds->ds_phys->ds_used_bytes + cdl_used - |
2660 (csa->ohds->ds_phys->ds_used_bytes + odl_used); | |
2661 dcomp = csa->cds->ds_phys->ds_compressed_bytes + cdl_comp - | |
2662 (csa->ohds->ds_phys->ds_compressed_bytes + odl_comp); | |
2663 duncomp = csa->cds->ds_phys->ds_uncompressed_bytes + | |
2664 cdl_uncomp - | |
2665 (csa->ohds->ds_phys->ds_uncompressed_bytes + odl_uncomp); | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2666 |
5367 | 2667 dsl_dir_diduse_space(csa->ohds->ds_dir, |
2668 dused, dcomp, duncomp, tx); | |
2669 dsl_dir_diduse_space(csa->cds->ds_dir, | |
2670 -dused, -dcomp, -duncomp, tx); | |
2671 } | |
2672 | |
2673 #define SWITCH64(x, y) \ | |
2674 { \ | |
2675 uint64_t __tmp = (x); \ | |
2676 (x) = (y); \ | |
2677 (y) = __tmp; \ | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2678 } |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2679 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2680 /* swap ds_*_bytes */ |
5367 | 2681 SWITCH64(csa->ohds->ds_phys->ds_used_bytes, |
2682 csa->cds->ds_phys->ds_used_bytes); | |
2683 SWITCH64(csa->ohds->ds_phys->ds_compressed_bytes, | |
2684 csa->cds->ds_phys->ds_compressed_bytes); | |
2685 SWITCH64(csa->ohds->ds_phys->ds_uncompressed_bytes, | |
2686 csa->cds->ds_phys->ds_uncompressed_bytes); | |
5481
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2687 SWITCH64(csa->ohds->ds_phys->ds_unique_bytes, |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2688 csa->cds->ds_phys->ds_unique_bytes); |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2689 |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2690 /* apply any parent delta for change in unconsumed refreservation */ |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2691 dsl_dir_diduse_space(csa->ohds->ds_dir, csa->unused_refres_delta, |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2692 0, 0, tx); |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2693 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2694 /* swap deadlists */ |
5367 | 2695 bplist_close(&csa->cds->ds_deadlist); |
2696 bplist_close(&csa->ohds->ds_deadlist); | |
2697 SWITCH64(csa->ohds->ds_phys->ds_deadlist_obj, | |
2698 csa->cds->ds_phys->ds_deadlist_obj); | |
2699 VERIFY(0 == bplist_open(&csa->cds->ds_deadlist, dp->dp_meta_objset, | |
2700 csa->cds->ds_phys->ds_deadlist_obj)); | |
2701 VERIFY(0 == bplist_open(&csa->ohds->ds_deadlist, dp->dp_meta_objset, | |
2702 csa->ohds->ds_phys->ds_deadlist_obj)); | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2703 } |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2704 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2705 /* |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2706 * Swap 'clone' with its origin head file system. Used at the end |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2707 * of "online recv" to swizzle the file system to the new version. |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2708 */ |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2709 int |
5367 | 2710 dsl_dataset_clone_swap(dsl_dataset_t *clone, dsl_dataset_t *origin_head, |
2711 boolean_t force) | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2712 { |
5367 | 2713 struct cloneswaparg csa; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2714 int error; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2715 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2716 ASSERT(clone->ds_owner); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2717 ASSERT(origin_head->ds_owner); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2718 retry: |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2719 /* Need exclusive access for the swap */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2720 rw_enter(&clone->ds_rwlock, RW_WRITER); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2721 if (!rw_tryenter(&origin_head->ds_rwlock, RW_WRITER)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2722 rw_exit(&clone->ds_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2723 rw_enter(&origin_head->ds_rwlock, RW_WRITER); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2724 if (!rw_tryenter(&clone->ds_rwlock, RW_WRITER)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2725 rw_exit(&origin_head->ds_rwlock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2726 goto retry; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2727 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2728 } |
5367 | 2729 csa.cds = clone; |
2730 csa.ohds = origin_head; | |
2731 csa.force = force; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2732 error = dsl_sync_task_do(clone->ds_dir->dd_pool, |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2733 dsl_dataset_clone_swap_check, |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2734 dsl_dataset_clone_swap_sync, &csa, NULL, 9); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2735 return (error); |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2736 } |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5094
diff
changeset
|
2737 |
3912 | 2738 /* |
2739 * Given a pool name and a dataset object number in that pool, | |
2740 * return the name of that dataset. | |
2741 */ | |
2742 int | |
2743 dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf) | |
2744 { | |
2745 spa_t *spa; | |
2746 dsl_pool_t *dp; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2747 dsl_dataset_t *ds; |
3912 | 2748 int error; |
2749 | |
2750 if ((error = spa_open(pname, &spa, FTAG)) != 0) | |
2751 return (error); | |
2752 dp = spa_get_dsl(spa); | |
2753 rw_enter(&dp->dp_config_rwlock, RW_READER); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2754 if ((error = dsl_dataset_hold_obj(dp, obj, FTAG, &ds)) == 0) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2755 dsl_dataset_name(ds, buf); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2756 dsl_dataset_rele(ds, FTAG); |
3912 | 2757 } |
2758 rw_exit(&dp->dp_config_rwlock); | |
2759 spa_close(spa, FTAG); | |
2760 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2761 return (error); |
3912 | 2762 } |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2763 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2764 int |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2765 dsl_dataset_check_quota(dsl_dataset_t *ds, boolean_t check_quota, |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2766 uint64_t asize, uint64_t inflight, uint64_t *used, uint64_t *ref_rsrv) |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2767 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2768 int error = 0; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2769 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2770 ASSERT3S(asize, >, 0); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2771 |
5831
48655d6b290b
6630761 In sub-filesystem, available space is less than refreservation space
ck153898
parents:
5712
diff
changeset
|
2772 /* |
48655d6b290b
6630761 In sub-filesystem, available space is less than refreservation space
ck153898
parents:
5712
diff
changeset
|
2773 * *ref_rsrv is the portion of asize that will come from any |
48655d6b290b
6630761 In sub-filesystem, available space is less than refreservation space
ck153898
parents:
5712
diff
changeset
|
2774 * unconsumed refreservation space. |
48655d6b290b
6630761 In sub-filesystem, available space is less than refreservation space
ck153898
parents:
5712
diff
changeset
|
2775 */ |
48655d6b290b
6630761 In sub-filesystem, available space is less than refreservation space
ck153898
parents:
5712
diff
changeset
|
2776 *ref_rsrv = 0; |
48655d6b290b
6630761 In sub-filesystem, available space is less than refreservation space
ck153898
parents:
5712
diff
changeset
|
2777 |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2778 mutex_enter(&ds->ds_lock); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2779 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2780 * Make a space adjustment for reserved bytes. |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2781 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2782 if (ds->ds_reserved > ds->ds_phys->ds_unique_bytes) { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2783 ASSERT3U(*used, >=, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2784 ds->ds_reserved - ds->ds_phys->ds_unique_bytes); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2785 *used -= (ds->ds_reserved - ds->ds_phys->ds_unique_bytes); |
5831
48655d6b290b
6630761 In sub-filesystem, available space is less than refreservation space
ck153898
parents:
5712
diff
changeset
|
2786 *ref_rsrv = |
48655d6b290b
6630761 In sub-filesystem, available space is less than refreservation space
ck153898
parents:
5712
diff
changeset
|
2787 asize - MIN(asize, parent_delta(ds, asize + inflight)); |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2788 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2789 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2790 if (!check_quota || ds->ds_quota == 0) { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2791 mutex_exit(&ds->ds_lock); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2792 return (0); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2793 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2794 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2795 * If they are requesting more space, and our current estimate |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2796 * is over quota, they get to try again unless the actual |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2797 * on-disk is over quota and there are no pending changes (which |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2798 * may free up space for us). |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2799 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2800 if (ds->ds_phys->ds_used_bytes + inflight >= ds->ds_quota) { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2801 if (inflight > 0 || ds->ds_phys->ds_used_bytes < ds->ds_quota) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2802 error = ERESTART; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2803 else |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2804 error = EDQUOT; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2805 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2806 mutex_exit(&ds->ds_lock); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2807 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2808 return (error); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2809 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2810 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2811 /* ARGSUSED */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2812 static int |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2813 dsl_dataset_set_quota_check(void *arg1, void *arg2, dmu_tx_t *tx) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2814 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2815 dsl_dataset_t *ds = arg1; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2816 uint64_t *quotap = arg2; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2817 uint64_t new_quota = *quotap; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2818 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2819 if (spa_version(ds->ds_dir->dd_pool->dp_spa) < SPA_VERSION_REFQUOTA) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2820 return (ENOTSUP); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2821 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2822 if (new_quota == 0) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2823 return (0); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2824 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2825 if (new_quota < ds->ds_phys->ds_used_bytes || |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2826 new_quota < ds->ds_reserved) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2827 return (ENOSPC); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2828 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2829 return (0); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2830 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2831 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2832 /* ARGSUSED */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2833 void |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2834 dsl_dataset_set_quota_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2835 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2836 dsl_dataset_t *ds = arg1; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2837 uint64_t *quotap = arg2; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2838 uint64_t new_quota = *quotap; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2839 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2840 dmu_buf_will_dirty(ds->ds_dbuf, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2841 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2842 ds->ds_quota = new_quota; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2843 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2844 dsl_prop_set_uint64_sync(ds->ds_dir, "refquota", new_quota, cr, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2845 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2846 spa_history_internal_log(LOG_DS_REFQUOTA, ds->ds_dir->dd_pool->dp_spa, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2847 tx, cr, "%lld dataset = %llu ", |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2848 (longlong_t)new_quota, ds->ds_object); |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2849 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2850 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2851 int |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2852 dsl_dataset_set_quota(const char *dsname, uint64_t quota) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2853 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2854 dsl_dataset_t *ds; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2855 int err; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2856 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2857 err = dsl_dataset_hold(dsname, FTAG, &ds); |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2858 if (err) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2859 return (err); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2860 |
5481
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2861 if (quota != ds->ds_quota) { |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2862 /* |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2863 * If someone removes a file, then tries to set the quota, we |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2864 * want to make sure the file freeing takes effect. |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2865 */ |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2866 txg_wait_open(ds->ds_dir->dd_pool, 0); |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2867 |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2868 err = dsl_sync_task_do(ds->ds_dir->dd_pool, |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2869 dsl_dataset_set_quota_check, dsl_dataset_set_quota_sync, |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2870 ds, "a, 0); |
1364fb7de75d
6619182 new non-sparse zvols should get refreservations
ck153898
parents:
5475
diff
changeset
|
2871 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2872 dsl_dataset_rele(ds, FTAG); |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2873 return (err); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2874 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2875 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2876 static int |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2877 dsl_dataset_set_reservation_check(void *arg1, void *arg2, dmu_tx_t *tx) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2878 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2879 dsl_dataset_t *ds = arg1; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2880 uint64_t *reservationp = arg2; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2881 uint64_t new_reservation = *reservationp; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2882 int64_t delta; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2883 uint64_t unique; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2884 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2885 if (new_reservation > INT64_MAX) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2886 return (EOVERFLOW); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2887 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2888 if (spa_version(ds->ds_dir->dd_pool->dp_spa) < |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2889 SPA_VERSION_REFRESERVATION) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2890 return (ENOTSUP); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2891 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2892 if (dsl_dataset_is_snapshot(ds)) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2893 return (EINVAL); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2894 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2895 /* |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2896 * If we are doing the preliminary check in open context, the |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2897 * space estimates may be inaccurate. |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2898 */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2899 if (!dmu_tx_is_syncing(tx)) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2900 return (0); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2901 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2902 mutex_enter(&ds->ds_lock); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2903 unique = dsl_dataset_unique(ds); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2904 delta = MAX(unique, new_reservation) - MAX(unique, ds->ds_reserved); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2905 mutex_exit(&ds->ds_lock); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2906 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2907 if (delta > 0 && |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2908 delta > dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE)) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2909 return (ENOSPC); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2910 if (delta > 0 && ds->ds_quota > 0 && |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2911 new_reservation > ds->ds_quota) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2912 return (ENOSPC); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2913 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2914 return (0); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2915 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2916 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2917 /* ARGSUSED */ |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2918 static void |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2919 dsl_dataset_set_reservation_sync(void *arg1, void *arg2, cred_t *cr, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2920 dmu_tx_t *tx) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2921 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2922 dsl_dataset_t *ds = arg1; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2923 uint64_t *reservationp = arg2; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2924 uint64_t new_reservation = *reservationp; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2925 uint64_t unique; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2926 int64_t delta; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2927 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2928 dmu_buf_will_dirty(ds->ds_dbuf, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2929 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2930 mutex_enter(&ds->ds_lock); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2931 unique = dsl_dataset_unique(ds); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2932 delta = MAX(0, (int64_t)(new_reservation - unique)) - |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2933 MAX(0, (int64_t)(ds->ds_reserved - unique)); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2934 ds->ds_reserved = new_reservation; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2935 mutex_exit(&ds->ds_lock); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2936 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2937 dsl_prop_set_uint64_sync(ds->ds_dir, "refreservation", |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2938 new_reservation, cr, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2939 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2940 dsl_dir_diduse_space(ds->ds_dir, delta, 0, 0, tx); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2941 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2942 spa_history_internal_log(LOG_DS_REFRESERV, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2943 ds->ds_dir->dd_pool->dp_spa, tx, cr, "%lld dataset = %llu", |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2944 (longlong_t)new_reservation, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2945 ds->ds_dir->dd_phys->dd_head_dataset_obj); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2946 } |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2947 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2948 int |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2949 dsl_dataset_set_reservation(const char *dsname, uint64_t reservation) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2950 { |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2951 dsl_dataset_t *ds; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2952 int err; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2953 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2954 err = dsl_dataset_hold(dsname, FTAG, &ds); |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2955 if (err) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2956 return (err); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2957 |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2958 err = dsl_sync_task_do(ds->ds_dir->dd_pool, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2959 dsl_dataset_set_reservation_check, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2960 dsl_dataset_set_reservation_sync, ds, &reservation, 0); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2961 dsl_dataset_rele(ds, FTAG); |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2962 return (err); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5367
diff
changeset
|
2963 } |