xref: /titanic_50/usr/src/uts/common/fs/zfs/dsl_dir.c (revision 41efec2219526a9b3ecce26f97aba761ef1e1d0d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/dmu.h>
29 #include <sys/dmu_tx.h>
30 #include <sys/dsl_dataset.h>
31 #include <sys/dsl_dir.h>
32 #include <sys/dsl_prop.h>
33 #include <sys/dsl_synctask.h>
34 #include <sys/dsl_deleg.h>
35 #include <sys/spa.h>
36 #include <sys/zap.h>
37 #include <sys/zio.h>
38 #include <sys/arc.h>
39 #include <sys/sunddi.h>
40 #include "zfs_namecheck.h"
41 
42 static uint64_t dsl_dir_estimated_space(dsl_dir_t *dd);
43 static void dsl_dir_set_reservation_sync(void *arg1, void *arg2,
44     cred_t *cr, dmu_tx_t *tx);
45 
46 
47 /* ARGSUSED */
48 static void
49 dsl_dir_evict(dmu_buf_t *db, void *arg)
50 {
51 	dsl_dir_t *dd = arg;
52 	dsl_pool_t *dp = dd->dd_pool;
53 	int t;
54 
55 	for (t = 0; t < TXG_SIZE; t++) {
56 		ASSERT(!txg_list_member(&dp->dp_dirty_dirs, dd, t));
57 		ASSERT(dd->dd_tempreserved[t] == 0);
58 		ASSERT(dd->dd_space_towrite[t] == 0);
59 	}
60 
61 	ASSERT3U(dd->dd_used_bytes, ==, dd->dd_phys->dd_used_bytes);
62 
63 	if (dd->dd_parent)
64 		dsl_dir_close(dd->dd_parent, dd);
65 
66 	spa_close(dd->dd_pool->dp_spa, dd);
67 
68 	/*
69 	 * The props callback list should be empty since they hold the
70 	 * dir open.
71 	 */
72 	list_destroy(&dd->dd_prop_cbs);
73 	mutex_destroy(&dd->dd_lock);
74 	kmem_free(dd, sizeof (dsl_dir_t));
75 }
76 
77 int
78 dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj,
79     const char *tail, void *tag, dsl_dir_t **ddp)
80 {
81 	dmu_buf_t *dbuf;
82 	dsl_dir_t *dd;
83 	int err;
84 
85 	ASSERT(RW_LOCK_HELD(&dp->dp_config_rwlock) ||
86 	    dsl_pool_sync_context(dp));
87 
88 	err = dmu_bonus_hold(dp->dp_meta_objset, ddobj, tag, &dbuf);
89 	if (err)
90 		return (err);
91 	dd = dmu_buf_get_user(dbuf);
92 #ifdef ZFS_DEBUG
93 	{
94 		dmu_object_info_t doi;
95 		dmu_object_info_from_db(dbuf, &doi);
96 		ASSERT3U(doi.doi_type, ==, DMU_OT_DSL_DIR);
97 	}
98 #endif
99 	/* XXX assert bonus buffer size is correct */
100 	if (dd == NULL) {
101 		dsl_dir_t *winner;
102 		int err;
103 
104 		dd = kmem_zalloc(sizeof (dsl_dir_t), KM_SLEEP);
105 		dd->dd_object = ddobj;
106 		dd->dd_dbuf = dbuf;
107 		dd->dd_pool = dp;
108 		dd->dd_phys = dbuf->db_data;
109 		dd->dd_used_bytes = dd->dd_phys->dd_used_bytes;
110 		mutex_init(&dd->dd_lock, NULL, MUTEX_DEFAULT, NULL);
111 
112 		list_create(&dd->dd_prop_cbs, sizeof (dsl_prop_cb_record_t),
113 		    offsetof(dsl_prop_cb_record_t, cbr_node));
114 
115 		if (dd->dd_phys->dd_parent_obj) {
116 			err = dsl_dir_open_obj(dp, dd->dd_phys->dd_parent_obj,
117 			    NULL, dd, &dd->dd_parent);
118 			if (err) {
119 				mutex_destroy(&dd->dd_lock);
120 				kmem_free(dd, sizeof (dsl_dir_t));
121 				dmu_buf_rele(dbuf, tag);
122 				return (err);
123 			}
124 			if (tail) {
125 #ifdef ZFS_DEBUG
126 				uint64_t foundobj;
127 
128 				err = zap_lookup(dp->dp_meta_objset,
129 				    dd->dd_parent->dd_phys->
130 				    dd_child_dir_zapobj,
131 				    tail, sizeof (foundobj), 1, &foundobj);
132 				ASSERT(err || foundobj == ddobj);
133 #endif
134 				(void) strcpy(dd->dd_myname, tail);
135 			} else {
136 				err = zap_value_search(dp->dp_meta_objset,
137 				    dd->dd_parent->dd_phys->
138 				    dd_child_dir_zapobj,
139 				    ddobj, dd->dd_myname);
140 			}
141 			if (err) {
142 				dsl_dir_close(dd->dd_parent, dd);
143 				mutex_destroy(&dd->dd_lock);
144 				kmem_free(dd, sizeof (dsl_dir_t));
145 				dmu_buf_rele(dbuf, tag);
146 				return (err);
147 			}
148 		} else {
149 			(void) strcpy(dd->dd_myname, spa_name(dp->dp_spa));
150 		}
151 
152 		winner = dmu_buf_set_user_ie(dbuf, dd, &dd->dd_phys,
153 		    dsl_dir_evict);
154 		if (winner) {
155 			if (dd->dd_parent)
156 				dsl_dir_close(dd->dd_parent, dd);
157 			mutex_destroy(&dd->dd_lock);
158 			kmem_free(dd, sizeof (dsl_dir_t));
159 			dd = winner;
160 		} else {
161 			spa_open_ref(dp->dp_spa, dd);
162 		}
163 	}
164 
165 	/*
166 	 * The dsl_dir_t has both open-to-close and instantiate-to-evict
167 	 * holds on the spa.  We need the open-to-close holds because
168 	 * otherwise the spa_refcnt wouldn't change when we open a
169 	 * dir which the spa also has open, so we could incorrectly
170 	 * think it was OK to unload/export/destroy the pool.  We need
171 	 * the instantiate-to-evict hold because the dsl_dir_t has a
172 	 * pointer to the dd_pool, which has a pointer to the spa_t.
173 	 */
174 	spa_open_ref(dp->dp_spa, tag);
175 	ASSERT3P(dd->dd_pool, ==, dp);
176 	ASSERT3U(dd->dd_object, ==, ddobj);
177 	ASSERT3P(dd->dd_dbuf, ==, dbuf);
178 	*ddp = dd;
179 	return (0);
180 }
181 
182 void
183 dsl_dir_close(dsl_dir_t *dd, void *tag)
184 {
185 	dprintf_dd(dd, "%s\n", "");
186 	spa_close(dd->dd_pool->dp_spa, tag);
187 	dmu_buf_rele(dd->dd_dbuf, tag);
188 }
189 
190 /* buf must be long enough (MAXNAMELEN + strlen(MOS_DIR_NAME) + 1 should do) */
191 void
192 dsl_dir_name(dsl_dir_t *dd, char *buf)
193 {
194 	if (dd->dd_parent) {
195 		dsl_dir_name(dd->dd_parent, buf);
196 		(void) strcat(buf, "/");
197 	} else {
198 		buf[0] = '\0';
199 	}
200 	if (!MUTEX_HELD(&dd->dd_lock)) {
201 		/*
202 		 * recursive mutex so that we can use
203 		 * dprintf_dd() with dd_lock held
204 		 */
205 		mutex_enter(&dd->dd_lock);
206 		(void) strcat(buf, dd->dd_myname);
207 		mutex_exit(&dd->dd_lock);
208 	} else {
209 		(void) strcat(buf, dd->dd_myname);
210 	}
211 }
212 
213 /* Calculate name legnth, avoiding all the strcat calls of dsl_dir_name */
214 int
215 dsl_dir_namelen(dsl_dir_t *dd)
216 {
217 	int result = 0;
218 
219 	if (dd->dd_parent) {
220 		/* parent's name + 1 for the "/" */
221 		result = dsl_dir_namelen(dd->dd_parent) + 1;
222 	}
223 
224 	if (!MUTEX_HELD(&dd->dd_lock)) {
225 		/* see dsl_dir_name */
226 		mutex_enter(&dd->dd_lock);
227 		result += strlen(dd->dd_myname);
228 		mutex_exit(&dd->dd_lock);
229 	} else {
230 		result += strlen(dd->dd_myname);
231 	}
232 
233 	return (result);
234 }
235 
236 int
237 dsl_dir_is_private(dsl_dir_t *dd)
238 {
239 	int rv = FALSE;
240 
241 	if (dd->dd_parent && dsl_dir_is_private(dd->dd_parent))
242 		rv = TRUE;
243 	if (dataset_name_hidden(dd->dd_myname))
244 		rv = TRUE;
245 	return (rv);
246 }
247 
248 
249 static int
250 getcomponent(const char *path, char *component, const char **nextp)
251 {
252 	char *p;
253 	if (path == NULL)
254 		return (ENOENT);
255 	/* This would be a good place to reserve some namespace... */
256 	p = strpbrk(path, "/@");
257 	if (p && (p[1] == '/' || p[1] == '@')) {
258 		/* two separators in a row */
259 		return (EINVAL);
260 	}
261 	if (p == NULL || p == path) {
262 		/*
263 		 * if the first thing is an @ or /, it had better be an
264 		 * @ and it had better not have any more ats or slashes,
265 		 * and it had better have something after the @.
266 		 */
267 		if (p != NULL &&
268 		    (p[0] != '@' || strpbrk(path+1, "/@") || p[1] == '\0'))
269 			return (EINVAL);
270 		if (strlen(path) >= MAXNAMELEN)
271 			return (ENAMETOOLONG);
272 		(void) strcpy(component, path);
273 		p = NULL;
274 	} else if (p[0] == '/') {
275 		if (p-path >= MAXNAMELEN)
276 			return (ENAMETOOLONG);
277 		(void) strncpy(component, path, p - path);
278 		component[p-path] = '\0';
279 		p++;
280 	} else if (p[0] == '@') {
281 		/*
282 		 * if the next separator is an @, there better not be
283 		 * any more slashes.
284 		 */
285 		if (strchr(path, '/'))
286 			return (EINVAL);
287 		if (p-path >= MAXNAMELEN)
288 			return (ENAMETOOLONG);
289 		(void) strncpy(component, path, p - path);
290 		component[p-path] = '\0';
291 	} else {
292 		ASSERT(!"invalid p");
293 	}
294 	*nextp = p;
295 	return (0);
296 }
297 
298 /*
299  * same as dsl_open_dir, ignore the first component of name and use the
300  * spa instead
301  */
302 int
303 dsl_dir_open_spa(spa_t *spa, const char *name, void *tag,
304     dsl_dir_t **ddp, const char **tailp)
305 {
306 	char buf[MAXNAMELEN];
307 	const char *next, *nextnext = NULL;
308 	int err;
309 	dsl_dir_t *dd;
310 	dsl_pool_t *dp;
311 	uint64_t ddobj;
312 	int openedspa = FALSE;
313 
314 	dprintf("%s\n", name);
315 
316 	err = getcomponent(name, buf, &next);
317 	if (err)
318 		return (err);
319 	if (spa == NULL) {
320 		err = spa_open(buf, &spa, FTAG);
321 		if (err) {
322 			dprintf("spa_open(%s) failed\n", buf);
323 			return (err);
324 		}
325 		openedspa = TRUE;
326 
327 		/* XXX this assertion belongs in spa_open */
328 		ASSERT(!dsl_pool_sync_context(spa_get_dsl(spa)));
329 	}
330 
331 	dp = spa_get_dsl(spa);
332 
333 	rw_enter(&dp->dp_config_rwlock, RW_READER);
334 	err = dsl_dir_open_obj(dp, dp->dp_root_dir_obj, NULL, tag, &dd);
335 	if (err) {
336 		rw_exit(&dp->dp_config_rwlock);
337 		if (openedspa)
338 			spa_close(spa, FTAG);
339 		return (err);
340 	}
341 
342 	while (next != NULL) {
343 		dsl_dir_t *child_ds;
344 		err = getcomponent(next, buf, &nextnext);
345 		if (err)
346 			break;
347 		ASSERT(next[0] != '\0');
348 		if (next[0] == '@')
349 			break;
350 		dprintf("looking up %s in obj%lld\n",
351 		    buf, dd->dd_phys->dd_child_dir_zapobj);
352 
353 		err = zap_lookup(dp->dp_meta_objset,
354 		    dd->dd_phys->dd_child_dir_zapobj,
355 		    buf, sizeof (ddobj), 1, &ddobj);
356 		if (err) {
357 			if (err == ENOENT)
358 				err = 0;
359 			break;
360 		}
361 
362 		err = dsl_dir_open_obj(dp, ddobj, buf, tag, &child_ds);
363 		if (err)
364 			break;
365 		dsl_dir_close(dd, tag);
366 		dd = child_ds;
367 		next = nextnext;
368 	}
369 	rw_exit(&dp->dp_config_rwlock);
370 
371 	if (err) {
372 		dsl_dir_close(dd, tag);
373 		if (openedspa)
374 			spa_close(spa, FTAG);
375 		return (err);
376 	}
377 
378 	/*
379 	 * It's an error if there's more than one component left, or
380 	 * tailp==NULL and there's any component left.
381 	 */
382 	if (next != NULL &&
383 	    (tailp == NULL || (nextnext && nextnext[0] != '\0'))) {
384 		/* bad path name */
385 		dsl_dir_close(dd, tag);
386 		dprintf("next=%p (%s) tail=%p\n", next, next?next:"", tailp);
387 		err = ENOENT;
388 	}
389 	if (tailp)
390 		*tailp = next;
391 	if (openedspa)
392 		spa_close(spa, FTAG);
393 	*ddp = dd;
394 	return (err);
395 }
396 
397 /*
398  * Return the dsl_dir_t, and possibly the last component which couldn't
399  * be found in *tail.  Return NULL if the path is bogus, or if
400  * tail==NULL and we couldn't parse the whole name.  (*tail)[0] == '@'
401  * means that the last component is a snapshot.
402  */
403 int
404 dsl_dir_open(const char *name, void *tag, dsl_dir_t **ddp, const char **tailp)
405 {
406 	return (dsl_dir_open_spa(NULL, name, tag, ddp, tailp));
407 }
408 
409 uint64_t
410 dsl_dir_create_sync(dsl_dir_t *pds, const char *name, dmu_tx_t *tx)
411 {
412 	objset_t *mos = pds->dd_pool->dp_meta_objset;
413 	uint64_t ddobj;
414 	dsl_dir_phys_t *dsphys;
415 	dmu_buf_t *dbuf;
416 
417 	ddobj = dmu_object_alloc(mos, DMU_OT_DSL_DIR, 0,
418 	    DMU_OT_DSL_DIR, sizeof (dsl_dir_phys_t), tx);
419 	VERIFY(0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj,
420 	    name, sizeof (uint64_t), 1, &ddobj, tx));
421 	VERIFY(0 == dmu_bonus_hold(mos, ddobj, FTAG, &dbuf));
422 	dmu_buf_will_dirty(dbuf, tx);
423 	dsphys = dbuf->db_data;
424 
425 	dsphys->dd_creation_time = gethrestime_sec();
426 	dsphys->dd_parent_obj = pds->dd_object;
427 	dsphys->dd_props_zapobj = zap_create(mos,
428 	    DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx);
429 	dsphys->dd_child_dir_zapobj = zap_create(mos,
430 	    DMU_OT_DSL_DIR_CHILD_MAP, DMU_OT_NONE, 0, tx);
431 	dmu_buf_rele(dbuf, FTAG);
432 
433 	return (ddobj);
434 }
435 
436 /* ARGSUSED */
437 int
438 dsl_dir_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx)
439 {
440 	dsl_dir_t *dd = arg1;
441 	dsl_pool_t *dp = dd->dd_pool;
442 	objset_t *mos = dp->dp_meta_objset;
443 	int err;
444 	uint64_t count;
445 
446 	/*
447 	 * There should be exactly two holds, both from
448 	 * dsl_dataset_destroy: one on the dd directory, and one on its
449 	 * head ds.  Otherwise, someone is trying to lookup something
450 	 * inside this dir while we want to destroy it.  The
451 	 * config_rwlock ensures that nobody else opens it after we
452 	 * check.
453 	 */
454 	if (dmu_buf_refcount(dd->dd_dbuf) > 2)
455 		return (EBUSY);
456 
457 	err = zap_count(mos, dd->dd_phys->dd_child_dir_zapobj, &count);
458 	if (err)
459 		return (err);
460 	if (count != 0)
461 		return (EEXIST);
462 
463 	return (0);
464 }
465 
466 void
467 dsl_dir_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx)
468 {
469 	dsl_dir_t *dd = arg1;
470 	objset_t *mos = dd->dd_pool->dp_meta_objset;
471 	uint64_t val, obj;
472 
473 	ASSERT(RW_WRITE_HELD(&dd->dd_pool->dp_config_rwlock));
474 	ASSERT(dd->dd_phys->dd_head_dataset_obj == 0);
475 
476 	/* Remove our reservation. */
477 	val = 0;
478 	dsl_dir_set_reservation_sync(dd, &val, cr, tx);
479 	ASSERT3U(dd->dd_used_bytes, ==, 0);
480 	ASSERT3U(dd->dd_phys->dd_reserved, ==, 0);
481 
482 	VERIFY(0 == zap_destroy(mos, dd->dd_phys->dd_child_dir_zapobj, tx));
483 	VERIFY(0 == zap_destroy(mos, dd->dd_phys->dd_props_zapobj, tx));
484 	VERIFY(0 == dsl_deleg_destroy(mos, dd->dd_phys->dd_deleg_zapobj, tx));
485 	VERIFY(0 == zap_remove(mos,
486 	    dd->dd_parent->dd_phys->dd_child_dir_zapobj, dd->dd_myname, tx));
487 
488 	obj = dd->dd_object;
489 	dsl_dir_close(dd, tag);
490 	VERIFY(0 == dmu_object_free(mos, obj, tx));
491 }
492 
493 void
494 dsl_dir_create_root(objset_t *mos, uint64_t *ddobjp, dmu_tx_t *tx)
495 {
496 	dsl_dir_phys_t *dsp;
497 	dmu_buf_t *dbuf;
498 	int error;
499 
500 	*ddobjp = dmu_object_alloc(mos, DMU_OT_DSL_DIR, 0,
501 	    DMU_OT_DSL_DIR, sizeof (dsl_dir_phys_t), tx);
502 
503 	error = zap_add(mos, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ROOT_DATASET,
504 	    sizeof (uint64_t), 1, ddobjp, tx);
505 	ASSERT3U(error, ==, 0);
506 
507 	VERIFY(0 == dmu_bonus_hold(mos, *ddobjp, FTAG, &dbuf));
508 	dmu_buf_will_dirty(dbuf, tx);
509 	dsp = dbuf->db_data;
510 
511 	dsp->dd_creation_time = gethrestime_sec();
512 	dsp->dd_props_zapobj = zap_create(mos,
513 	    DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx);
514 	dsp->dd_child_dir_zapobj = zap_create(mos,
515 	    DMU_OT_DSL_DIR_CHILD_MAP, DMU_OT_NONE, 0, tx);
516 
517 	dmu_buf_rele(dbuf, FTAG);
518 }
519 
520 void
521 dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv)
522 {
523 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_AVAILABLE,
524 	    dsl_dir_space_available(dd, NULL, 0, TRUE));
525 
526 	mutex_enter(&dd->dd_lock);
527 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, dd->dd_used_bytes);
528 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_QUOTA,
529 	    dd->dd_phys->dd_quota);
530 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_RESERVATION,
531 	    dd->dd_phys->dd_reserved);
532 	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO,
533 	    dd->dd_phys->dd_compressed_bytes == 0 ? 100 :
534 	    (dd->dd_phys->dd_uncompressed_bytes * 100 /
535 	    dd->dd_phys->dd_compressed_bytes));
536 	mutex_exit(&dd->dd_lock);
537 
538 	if (dd->dd_phys->dd_clone_parent_obj) {
539 		dsl_dataset_t *ds;
540 		char buf[MAXNAMELEN];
541 
542 		rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER);
543 		VERIFY(0 == dsl_dataset_open_obj(dd->dd_pool,
544 		    dd->dd_phys->dd_clone_parent_obj,
545 		    NULL, DS_MODE_NONE, FTAG, &ds));
546 		dsl_dataset_name(ds, buf);
547 		dsl_dataset_close(ds, DS_MODE_NONE, FTAG);
548 		rw_exit(&dd->dd_pool->dp_config_rwlock);
549 
550 		dsl_prop_nvlist_add_string(nv, ZFS_PROP_ORIGIN, buf);
551 	}
552 }
553 
554 void
555 dsl_dir_dirty(dsl_dir_t *dd, dmu_tx_t *tx)
556 {
557 	dsl_pool_t *dp = dd->dd_pool;
558 
559 	ASSERT(dd->dd_phys);
560 
561 	if (txg_list_add(&dp->dp_dirty_dirs, dd, tx->tx_txg) == 0) {
562 		/* up the hold count until we can be written out */
563 		dmu_buf_add_ref(dd->dd_dbuf, dd);
564 	}
565 }
566 
567 static int64_t
568 parent_delta(dsl_dir_t *dd, uint64_t used, int64_t delta)
569 {
570 	uint64_t old_accounted = MAX(used, dd->dd_phys->dd_reserved);
571 	uint64_t new_accounted = MAX(used + delta, dd->dd_phys->dd_reserved);
572 	return (new_accounted - old_accounted);
573 }
574 
575 void
576 dsl_dir_sync(dsl_dir_t *dd, dmu_tx_t *tx)
577 {
578 	ASSERT(dmu_tx_is_syncing(tx));
579 
580 	dmu_buf_will_dirty(dd->dd_dbuf, tx);
581 
582 	mutex_enter(&dd->dd_lock);
583 	ASSERT3U(dd->dd_tempreserved[tx->tx_txg&TXG_MASK], ==, 0);
584 	dprintf_dd(dd, "txg=%llu towrite=%lluK\n", tx->tx_txg,
585 	    dd->dd_space_towrite[tx->tx_txg&TXG_MASK] / 1024);
586 	dd->dd_space_towrite[tx->tx_txg&TXG_MASK] = 0;
587 	dd->dd_phys->dd_used_bytes = dd->dd_used_bytes;
588 	mutex_exit(&dd->dd_lock);
589 
590 	/* release the hold from dsl_dir_dirty */
591 	dmu_buf_rele(dd->dd_dbuf, dd);
592 }
593 
594 static uint64_t
595 dsl_dir_estimated_space(dsl_dir_t *dd)
596 {
597 	int64_t space;
598 	int i;
599 
600 	ASSERT(MUTEX_HELD(&dd->dd_lock));
601 
602 	space = dd->dd_phys->dd_used_bytes;
603 	ASSERT(space >= 0);
604 	for (i = 0; i < TXG_SIZE; i++) {
605 		space += dd->dd_space_towrite[i&TXG_MASK];
606 		ASSERT3U(dd->dd_space_towrite[i&TXG_MASK], >=, 0);
607 	}
608 	return (space);
609 }
610 
611 /*
612  * How much space would dd have available if ancestor had delta applied
613  * to it?  If ondiskonly is set, we're only interested in what's
614  * on-disk, not estimated pending changes.
615  */
616 uint64_t
617 dsl_dir_space_available(dsl_dir_t *dd,
618     dsl_dir_t *ancestor, int64_t delta, int ondiskonly)
619 {
620 	uint64_t parentspace, myspace, quota, used;
621 
622 	/*
623 	 * If there are no restrictions otherwise, assume we have
624 	 * unlimited space available.
625 	 */
626 	quota = UINT64_MAX;
627 	parentspace = UINT64_MAX;
628 
629 	if (dd->dd_parent != NULL) {
630 		parentspace = dsl_dir_space_available(dd->dd_parent,
631 		    ancestor, delta, ondiskonly);
632 	}
633 
634 	mutex_enter(&dd->dd_lock);
635 	if (dd->dd_phys->dd_quota != 0)
636 		quota = dd->dd_phys->dd_quota;
637 	if (ondiskonly) {
638 		used = dd->dd_used_bytes;
639 	} else {
640 		used = dsl_dir_estimated_space(dd);
641 	}
642 	if (dd == ancestor)
643 		used += delta;
644 
645 	if (dd->dd_parent == NULL) {
646 		uint64_t poolsize = dsl_pool_adjustedsize(dd->dd_pool, FALSE);
647 		quota = MIN(quota, poolsize);
648 	}
649 
650 	if (dd->dd_phys->dd_reserved > used && parentspace != UINT64_MAX) {
651 		/*
652 		 * We have some space reserved, in addition to what our
653 		 * parent gave us.
654 		 */
655 		parentspace += dd->dd_phys->dd_reserved - used;
656 	}
657 
658 	if (used > quota) {
659 		/* over quota */
660 		myspace = 0;
661 
662 		/*
663 		 * While it's OK to be a little over quota, if
664 		 * we think we are using more space than there
665 		 * is in the pool (which is already 1.6% more than
666 		 * dsl_pool_adjustedsize()), something is very
667 		 * wrong.
668 		 */
669 		ASSERT3U(used, <=, spa_get_space(dd->dd_pool->dp_spa));
670 	} else {
671 		/*
672 		 * the lesser of the space provided by our parent and
673 		 * the space left in our quota
674 		 */
675 		myspace = MIN(parentspace, quota - used);
676 	}
677 
678 	mutex_exit(&dd->dd_lock);
679 
680 	return (myspace);
681 }
682 
683 struct tempreserve {
684 	list_node_t tr_node;
685 	dsl_dir_t *tr_ds;
686 	uint64_t tr_size;
687 };
688 
689 /*
690  * Reserve space in this dsl_dir, to be used in this tx's txg.
691  * After the space has been dirtied (and thus
692  * dsl_dir_willuse_space() has been called), the reservation should
693  * be canceled, using dsl_dir_tempreserve_clear().
694  */
695 static int
696 dsl_dir_tempreserve_impl(dsl_dir_t *dd,
697     uint64_t asize, boolean_t netfree, list_t *tr_list, dmu_tx_t *tx)
698 {
699 	uint64_t txg = tx->tx_txg;
700 	uint64_t est_used, quota, parent_rsrv;
701 	int edquot = EDQUOT;
702 	int txgidx = txg & TXG_MASK;
703 	int i;
704 	struct tempreserve *tr;
705 
706 	ASSERT3U(txg, !=, 0);
707 	ASSERT3S(asize, >=, 0);
708 
709 	mutex_enter(&dd->dd_lock);
710 	/*
711 	 * Check against the dsl_dir's quota.  We don't add in the delta
712 	 * when checking for over-quota because they get one free hit.
713 	 */
714 	est_used = dsl_dir_estimated_space(dd);
715 	for (i = 0; i < TXG_SIZE; i++)
716 		est_used += dd->dd_tempreserved[i];
717 
718 	quota = UINT64_MAX;
719 
720 	if (dd->dd_phys->dd_quota)
721 		quota = dd->dd_phys->dd_quota;
722 
723 	/*
724 	 * If this transaction will result in a net free of space, we want
725 	 * to let it through, but we have to be careful: the space that it
726 	 * frees won't become available until *after* this txg syncs.
727 	 * Therefore, to ensure that it's possible to remove files from
728 	 * a full pool without inducing transient overcommits, we throttle
729 	 * netfree transactions against a quota that is slightly larger,
730 	 * but still within the pool's allocation slop.  In cases where
731 	 * we're very close to full, this will allow a steady trickle of
732 	 * removes to get through.
733 	 */
734 	if (dd->dd_parent == NULL) {
735 		uint64_t poolsize = dsl_pool_adjustedsize(dd->dd_pool, netfree);
736 		if (poolsize < quota) {
737 			quota = poolsize;
738 			edquot = ENOSPC;
739 		}
740 	} else if (netfree) {
741 		quota = UINT64_MAX;
742 	}
743 
744 	/*
745 	 * If they are requesting more space, and our current estimate
746 	 * is over quota.  They get to try again unless the actual
747 	 * on-disk is over quota and there are no pending changes (which
748 	 * may free up space for us).
749 	 */
750 	if (asize > 0 && est_used > quota) {
751 		if (dd->dd_space_towrite[txg & TXG_MASK] != 0 ||
752 		    dd->dd_space_towrite[(txg-1) & TXG_MASK] != 0 ||
753 		    dd->dd_space_towrite[(txg-2) & TXG_MASK] != 0 ||
754 		    dd->dd_used_bytes < quota)
755 			edquot = ERESTART;
756 		dprintf_dd(dd, "failing: used=%lluK est_used = %lluK "
757 		    "quota=%lluK tr=%lluK err=%d\n",
758 		    dd->dd_used_bytes>>10, est_used>>10,
759 		    quota>>10, asize>>10, edquot);
760 		mutex_exit(&dd->dd_lock);
761 		return (edquot);
762 	}
763 
764 	/* We need to up our estimated delta before dropping dd_lock */
765 	dd->dd_tempreserved[txgidx] += asize;
766 
767 	parent_rsrv = parent_delta(dd, est_used, asize);
768 	mutex_exit(&dd->dd_lock);
769 
770 	tr = kmem_alloc(sizeof (struct tempreserve), KM_SLEEP);
771 	tr->tr_ds = dd;
772 	tr->tr_size = asize;
773 	list_insert_tail(tr_list, tr);
774 
775 	/* see if it's OK with our parent */
776 	if (dd->dd_parent && parent_rsrv) {
777 		return (dsl_dir_tempreserve_impl(dd->dd_parent,
778 		    parent_rsrv, netfree, tr_list, tx));
779 	} else {
780 		return (0);
781 	}
782 }
783 
784 /*
785  * Reserve space in this dsl_dir, to be used in this tx's txg.
786  * After the space has been dirtied (and thus
787  * dsl_dir_willuse_space() has been called), the reservation should
788  * be canceled, using dsl_dir_tempreserve_clear().
789  */
790 int
791 dsl_dir_tempreserve_space(dsl_dir_t *dd, uint64_t lsize,
792     uint64_t asize, uint64_t fsize, void **tr_cookiep, dmu_tx_t *tx)
793 {
794 	int err = 0;
795 	list_t *tr_list;
796 
797 	tr_list = kmem_alloc(sizeof (list_t), KM_SLEEP);
798 	list_create(tr_list, sizeof (struct tempreserve),
799 	    offsetof(struct tempreserve, tr_node));
800 	ASSERT3S(asize, >=, 0);
801 	ASSERT3S(fsize, >=, 0);
802 
803 	err = dsl_dir_tempreserve_impl(dd, asize, fsize >= asize,
804 	    tr_list, tx);
805 
806 	if (err == 0) {
807 		struct tempreserve *tr;
808 
809 		err = arc_tempreserve_space(lsize);
810 		if (err == 0) {
811 			tr = kmem_alloc(sizeof (struct tempreserve), KM_SLEEP);
812 			tr->tr_ds = NULL;
813 			tr->tr_size = lsize;
814 			list_insert_tail(tr_list, tr);
815 		}
816 	}
817 
818 	if (err)
819 		dsl_dir_tempreserve_clear(tr_list, tx);
820 	else
821 		*tr_cookiep = tr_list;
822 	return (err);
823 }
824 
825 /*
826  * Clear a temporary reservation that we previously made with
827  * dsl_dir_tempreserve_space().
828  */
829 void
830 dsl_dir_tempreserve_clear(void *tr_cookie, dmu_tx_t *tx)
831 {
832 	int txgidx = tx->tx_txg & TXG_MASK;
833 	list_t *tr_list = tr_cookie;
834 	struct tempreserve *tr;
835 
836 	ASSERT3U(tx->tx_txg, !=, 0);
837 
838 	while (tr = list_head(tr_list)) {
839 		if (tr->tr_ds == NULL) {
840 			arc_tempreserve_clear(tr->tr_size);
841 		} else {
842 			mutex_enter(&tr->tr_ds->dd_lock);
843 			ASSERT3U(tr->tr_ds->dd_tempreserved[txgidx], >=,
844 			    tr->tr_size);
845 			tr->tr_ds->dd_tempreserved[txgidx] -= tr->tr_size;
846 			mutex_exit(&tr->tr_ds->dd_lock);
847 		}
848 		list_remove(tr_list, tr);
849 		kmem_free(tr, sizeof (struct tempreserve));
850 	}
851 
852 	kmem_free(tr_list, sizeof (list_t));
853 }
854 
855 /*
856  * Call in open context when we think we're going to write/free space,
857  * eg. when dirtying data.  Be conservative (ie. OK to write less than
858  * this or free more than this, but don't write more or free less).
859  */
860 void
861 dsl_dir_willuse_space(dsl_dir_t *dd, int64_t space, dmu_tx_t *tx)
862 {
863 	int64_t parent_space;
864 	uint64_t est_used;
865 
866 	mutex_enter(&dd->dd_lock);
867 	if (space > 0)
868 		dd->dd_space_towrite[tx->tx_txg & TXG_MASK] += space;
869 
870 	est_used = dsl_dir_estimated_space(dd);
871 	parent_space = parent_delta(dd, est_used, space);
872 	mutex_exit(&dd->dd_lock);
873 
874 	/* Make sure that we clean up dd_space_to* */
875 	dsl_dir_dirty(dd, tx);
876 
877 	/* XXX this is potentially expensive and unnecessary... */
878 	if (parent_space && dd->dd_parent)
879 		dsl_dir_willuse_space(dd->dd_parent, parent_space, tx);
880 }
881 
882 /* call from syncing context when we actually write/free space for this dd */
883 void
884 dsl_dir_diduse_space(dsl_dir_t *dd,
885     int64_t used, int64_t compressed, int64_t uncompressed, dmu_tx_t *tx)
886 {
887 	int64_t accounted_delta;
888 
889 	ASSERT(dmu_tx_is_syncing(tx));
890 
891 	dsl_dir_dirty(dd, tx);
892 
893 	mutex_enter(&dd->dd_lock);
894 	accounted_delta = parent_delta(dd, dd->dd_used_bytes, used);
895 	ASSERT(used >= 0 || dd->dd_used_bytes >= -used);
896 	ASSERT(compressed >= 0 ||
897 	    dd->dd_phys->dd_compressed_bytes >= -compressed);
898 	ASSERT(uncompressed >= 0 ||
899 	    dd->dd_phys->dd_uncompressed_bytes >= -uncompressed);
900 	dd->dd_used_bytes += used;
901 	dd->dd_phys->dd_uncompressed_bytes += uncompressed;
902 	dd->dd_phys->dd_compressed_bytes += compressed;
903 	mutex_exit(&dd->dd_lock);
904 
905 	if (dd->dd_parent != NULL) {
906 		dsl_dir_diduse_space(dd->dd_parent,
907 		    accounted_delta, compressed, uncompressed, tx);
908 	}
909 }
910 
911 static int
912 dsl_dir_set_quota_check(void *arg1, void *arg2, dmu_tx_t *tx)
913 {
914 	dsl_dir_t *dd = arg1;
915 	uint64_t *quotap = arg2;
916 	uint64_t new_quota = *quotap;
917 	int err = 0;
918 	uint64_t towrite;
919 
920 	if (new_quota == 0)
921 		return (0);
922 
923 	mutex_enter(&dd->dd_lock);
924 	/*
925 	 * If we are doing the preliminary check in open context, and
926 	 * there are pending changes, then don't fail it, since the
927 	 * pending changes could under-estimat the amount of space to be
928 	 * freed up.
929 	 */
930 	towrite = dd->dd_space_towrite[0] + dd->dd_space_towrite[1] +
931 	    dd->dd_space_towrite[2] + dd->dd_space_towrite[3];
932 	if ((dmu_tx_is_syncing(tx) || towrite == 0) &&
933 	    (new_quota < dd->dd_phys->dd_reserved ||
934 	    new_quota < dsl_dir_estimated_space(dd))) {
935 		err = ENOSPC;
936 	}
937 	mutex_exit(&dd->dd_lock);
938 	return (err);
939 }
940 
941 /* ARGSUSED */
942 static void
943 dsl_dir_set_quota_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
944 {
945 	dsl_dir_t *dd = arg1;
946 	uint64_t *quotap = arg2;
947 	uint64_t new_quota = *quotap;
948 
949 	dmu_buf_will_dirty(dd->dd_dbuf, tx);
950 
951 	mutex_enter(&dd->dd_lock);
952 	dd->dd_phys->dd_quota = new_quota;
953 	mutex_exit(&dd->dd_lock);
954 
955 	spa_history_internal_log(LOG_DS_QUOTA, dd->dd_pool->dp_spa,
956 	    tx, cr, "%lld dataset = %llu ",
957 	    (longlong_t)new_quota, dd->dd_phys->dd_head_dataset_obj);
958 }
959 
960 int
961 dsl_dir_set_quota(const char *ddname, uint64_t quota)
962 {
963 	dsl_dir_t *dd;
964 	int err;
965 
966 	err = dsl_dir_open(ddname, FTAG, &dd, NULL);
967 	if (err)
968 		return (err);
969 	/*
970 	 * If someone removes a file, then tries to set the quota, we
971 	 * want to make sure the file freeing takes effect.
972 	 */
973 	txg_wait_open(dd->dd_pool, 0);
974 
975 	err = dsl_sync_task_do(dd->dd_pool, dsl_dir_set_quota_check,
976 	    dsl_dir_set_quota_sync, dd, &quota, 0);
977 	dsl_dir_close(dd, FTAG);
978 	return (err);
979 }
980 
981 static int
982 dsl_dir_set_reservation_check(void *arg1, void *arg2, dmu_tx_t *tx)
983 {
984 	dsl_dir_t *dd = arg1;
985 	uint64_t *reservationp = arg2;
986 	uint64_t new_reservation = *reservationp;
987 	uint64_t used, avail;
988 	int64_t delta;
989 
990 	if (new_reservation > INT64_MAX)
991 		return (EOVERFLOW);
992 
993 	/*
994 	 * If we are doing the preliminary check in open context, the
995 	 * space estimates may be inaccurate.
996 	 */
997 	if (!dmu_tx_is_syncing(tx))
998 		return (0);
999 
1000 	mutex_enter(&dd->dd_lock);
1001 	used = dd->dd_used_bytes;
1002 	delta = MAX(used, new_reservation) -
1003 	    MAX(used, dd->dd_phys->dd_reserved);
1004 	mutex_exit(&dd->dd_lock);
1005 
1006 	if (dd->dd_parent) {
1007 		avail = dsl_dir_space_available(dd->dd_parent,
1008 		    NULL, 0, FALSE);
1009 	} else {
1010 		avail = dsl_pool_adjustedsize(dd->dd_pool, B_FALSE) - used;
1011 	}
1012 
1013 	if (delta > 0 && delta > avail)
1014 		return (ENOSPC);
1015 	if (delta > 0 && dd->dd_phys->dd_quota > 0 &&
1016 	    new_reservation > dd->dd_phys->dd_quota)
1017 		return (ENOSPC);
1018 	return (0);
1019 }
1020 
1021 /* ARGSUSED */
1022 static void
1023 dsl_dir_set_reservation_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
1024 {
1025 	dsl_dir_t *dd = arg1;
1026 	uint64_t *reservationp = arg2;
1027 	uint64_t new_reservation = *reservationp;
1028 	uint64_t used;
1029 	int64_t delta;
1030 
1031 	mutex_enter(&dd->dd_lock);
1032 	used = dd->dd_used_bytes;
1033 	delta = MAX(used, new_reservation) -
1034 	    MAX(used, dd->dd_phys->dd_reserved);
1035 	mutex_exit(&dd->dd_lock);
1036 
1037 	dmu_buf_will_dirty(dd->dd_dbuf, tx);
1038 	dd->dd_phys->dd_reserved = new_reservation;
1039 
1040 	if (dd->dd_parent != NULL) {
1041 		/* Roll up this additional usage into our ancestors */
1042 		dsl_dir_diduse_space(dd->dd_parent, delta, 0, 0, tx);
1043 	}
1044 
1045 	spa_history_internal_log(LOG_DS_RESERVATION, dd->dd_pool->dp_spa,
1046 	    tx, cr, "%lld dataset = %llu",
1047 	    (longlong_t)new_reservation, dd->dd_phys->dd_head_dataset_obj);
1048 }
1049 
1050 int
1051 dsl_dir_set_reservation(const char *ddname, uint64_t reservation)
1052 {
1053 	dsl_dir_t *dd;
1054 	int err;
1055 
1056 	err = dsl_dir_open(ddname, FTAG, &dd, NULL);
1057 	if (err)
1058 		return (err);
1059 	err = dsl_sync_task_do(dd->dd_pool, dsl_dir_set_reservation_check,
1060 	    dsl_dir_set_reservation_sync, dd, &reservation, 0);
1061 	dsl_dir_close(dd, FTAG);
1062 	return (err);
1063 }
1064 
1065 static dsl_dir_t *
1066 closest_common_ancestor(dsl_dir_t *ds1, dsl_dir_t *ds2)
1067 {
1068 	for (; ds1; ds1 = ds1->dd_parent) {
1069 		dsl_dir_t *dd;
1070 		for (dd = ds2; dd; dd = dd->dd_parent) {
1071 			if (ds1 == dd)
1072 				return (dd);
1073 		}
1074 	}
1075 	return (NULL);
1076 }
1077 
1078 /*
1079  * If delta is applied to dd, how much of that delta would be applied to
1080  * ancestor?  Syncing context only.
1081  */
1082 static int64_t
1083 would_change(dsl_dir_t *dd, int64_t delta, dsl_dir_t *ancestor)
1084 {
1085 	if (dd == ancestor)
1086 		return (delta);
1087 
1088 	mutex_enter(&dd->dd_lock);
1089 	delta = parent_delta(dd, dd->dd_used_bytes, delta);
1090 	mutex_exit(&dd->dd_lock);
1091 	return (would_change(dd->dd_parent, delta, ancestor));
1092 }
1093 
1094 struct renamearg {
1095 	dsl_dir_t *newparent;
1096 	const char *mynewname;
1097 };
1098 
1099 /*ARGSUSED*/
1100 static int
1101 dsl_dir_rename_check(void *arg1, void *arg2, dmu_tx_t *tx)
1102 {
1103 	dsl_dir_t *dd = arg1;
1104 	struct renamearg *ra = arg2;
1105 	dsl_pool_t *dp = dd->dd_pool;
1106 	objset_t *mos = dp->dp_meta_objset;
1107 	int err;
1108 	uint64_t val;
1109 
1110 	/* There should be 2 references: the open and the dirty */
1111 	if (dmu_buf_refcount(dd->dd_dbuf) > 2)
1112 		return (EBUSY);
1113 
1114 	/* check for existing name */
1115 	err = zap_lookup(mos, ra->newparent->dd_phys->dd_child_dir_zapobj,
1116 	    ra->mynewname, 8, 1, &val);
1117 	if (err == 0)
1118 		return (EEXIST);
1119 	if (err != ENOENT)
1120 		return (err);
1121 
1122 	if (ra->newparent != dd->dd_parent) {
1123 		/* is there enough space? */
1124 		uint64_t myspace =
1125 		    MAX(dd->dd_used_bytes, dd->dd_phys->dd_reserved);
1126 
1127 		/* no rename into our descendant */
1128 		if (closest_common_ancestor(dd, ra->newparent) == dd)
1129 			return (EINVAL);
1130 
1131 		if (err = dsl_dir_transfer_possible(dd->dd_parent,
1132 		    ra->newparent, myspace))
1133 			return (err);
1134 	}
1135 
1136 	return (0);
1137 }
1138 
1139 static void
1140 dsl_dir_rename_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
1141 {
1142 	dsl_dir_t *dd = arg1;
1143 	struct renamearg *ra = arg2;
1144 	dsl_pool_t *dp = dd->dd_pool;
1145 	objset_t *mos = dp->dp_meta_objset;
1146 	int err;
1147 
1148 	ASSERT(dmu_buf_refcount(dd->dd_dbuf) <= 2);
1149 
1150 	if (ra->newparent != dd->dd_parent) {
1151 		uint64_t myspace =
1152 		    MAX(dd->dd_used_bytes, dd->dd_phys->dd_reserved);
1153 
1154 		dsl_dir_diduse_space(dd->dd_parent, -myspace,
1155 		    -dd->dd_phys->dd_compressed_bytes,
1156 		    -dd->dd_phys->dd_uncompressed_bytes, tx);
1157 		dsl_dir_diduse_space(ra->newparent, myspace,
1158 		    dd->dd_phys->dd_compressed_bytes,
1159 		    dd->dd_phys->dd_uncompressed_bytes, tx);
1160 	}
1161 
1162 	dmu_buf_will_dirty(dd->dd_dbuf, tx);
1163 
1164 	/* remove from old parent zapobj */
1165 	err = zap_remove(mos, dd->dd_parent->dd_phys->dd_child_dir_zapobj,
1166 	    dd->dd_myname, tx);
1167 	ASSERT3U(err, ==, 0);
1168 
1169 	(void) strcpy(dd->dd_myname, ra->mynewname);
1170 	dsl_dir_close(dd->dd_parent, dd);
1171 	dd->dd_phys->dd_parent_obj = ra->newparent->dd_object;
1172 	VERIFY(0 == dsl_dir_open_obj(dd->dd_pool,
1173 	    ra->newparent->dd_object, NULL, dd, &dd->dd_parent));
1174 
1175 	/* add to new parent zapobj */
1176 	err = zap_add(mos, ra->newparent->dd_phys->dd_child_dir_zapobj,
1177 	    dd->dd_myname, 8, 1, &dd->dd_object, tx);
1178 	ASSERT3U(err, ==, 0);
1179 
1180 	spa_history_internal_log(LOG_DS_RENAME, dd->dd_pool->dp_spa,
1181 	    tx, cr, "dataset = %llu", dd->dd_phys->dd_head_dataset_obj);
1182 }
1183 
1184 int
1185 dsl_dir_rename(dsl_dir_t *dd, const char *newname)
1186 {
1187 	struct renamearg ra;
1188 	int err;
1189 
1190 	/* new parent should exist */
1191 	err = dsl_dir_open(newname, FTAG, &ra.newparent, &ra.mynewname);
1192 	if (err)
1193 		return (err);
1194 
1195 	/* can't rename to different pool */
1196 	if (dd->dd_pool != ra.newparent->dd_pool) {
1197 		err = ENXIO;
1198 		goto out;
1199 	}
1200 
1201 	/* new name should not already exist */
1202 	if (ra.mynewname == NULL) {
1203 		err = EEXIST;
1204 		goto out;
1205 	}
1206 
1207 	err = dsl_sync_task_do(dd->dd_pool,
1208 	    dsl_dir_rename_check, dsl_dir_rename_sync, dd, &ra, 3);
1209 
1210 out:
1211 	dsl_dir_close(ra.newparent, FTAG);
1212 	return (err);
1213 }
1214 
1215 int
1216 dsl_dir_transfer_possible(dsl_dir_t *sdd, dsl_dir_t *tdd, uint64_t space)
1217 {
1218 	dsl_dir_t *ancestor;
1219 	int64_t adelta;
1220 	uint64_t avail;
1221 
1222 	ancestor = closest_common_ancestor(sdd, tdd);
1223 	adelta = would_change(sdd, -space, ancestor);
1224 	avail = dsl_dir_space_available(tdd, ancestor, adelta, FALSE);
1225 	if (avail < space)
1226 		return (ENOSPC);
1227 
1228 	return (0);
1229 }
1230