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 /*
23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright 2019 Joyent, Inc.
25  * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
26  * Copyright (c) 2012 DEY Storage Systems, Inc.  All rights reserved.
27  * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
28  * Copyright (c) 2013 Martin Matuska. All rights reserved.
29  * Copyright (c) 2013 Steven Hartland. All rights reserved.
30  * Copyright 2017 Nexenta Systems, Inc.
31  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
32  * Copyright 2017-2018 RackTop Systems.
33  * Copyright (c) 2019 Datto Inc.
34  * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
35  * Copyright (c) 2021 Matt Fiddaman
36  */
37 
38 #include <ctype.h>
39 #include <errno.h>
40 #include <libintl.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <strings.h>
44 #include <unistd.h>
45 #include <stddef.h>
46 #include <zone.h>
47 #include <fcntl.h>
48 #include <sys/mntent.h>
49 #include <sys/mount.h>
50 #include <pwd.h>
51 #include <grp.h>
52 #include <ucred.h>
53 #ifdef HAVE_IDMAP
54 #include <idmap.h>
55 #include <aclutils.h>
56 #include <directory.h>
57 #endif /* HAVE_IDMAP */
58 
59 #include <sys/dnode.h>
60 #include <sys/spa.h>
61 #include <sys/zap.h>
62 #include <sys/dsl_crypt.h>
63 #include <libzfs.h>
64 #include <libzutil.h>
65 
66 #include "zfs_namecheck.h"
67 #include "zfs_prop.h"
68 #include "libzfs_impl.h"
69 #include "zfs_deleg.h"
70 
71 static int userquota_propname_decode(const char *propname, boolean_t zoned,
72     zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
73 
74 /*
75  * Given a single type (not a mask of types), return the type in a human
76  * readable form.
77  */
78 const char *
79 zfs_type_to_name(zfs_type_t type)
80 {
81 	switch (type) {
82 	case ZFS_TYPE_FILESYSTEM:
83 		return (dgettext(TEXT_DOMAIN, "filesystem"));
84 	case ZFS_TYPE_SNAPSHOT:
85 		return (dgettext(TEXT_DOMAIN, "snapshot"));
86 	case ZFS_TYPE_VOLUME:
87 		return (dgettext(TEXT_DOMAIN, "volume"));
88 	case ZFS_TYPE_POOL:
89 		return (dgettext(TEXT_DOMAIN, "pool"));
90 	case ZFS_TYPE_BOOKMARK:
91 		return (dgettext(TEXT_DOMAIN, "bookmark"));
92 	default:
93 		assert(!"unhandled zfs_type_t");
94 	}
95 
96 	return (NULL);
97 }
98 
99 /*
100  * Validate a ZFS path.  This is used even before trying to open the dataset, to
101  * provide a more meaningful error message.  We call zfs_error_aux() to
102  * explain exactly why the name was not valid.
103  */
104 int
105 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
106     boolean_t modifying)
107 {
108 	namecheck_err_t why;
109 	char what;
110 
111 	if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
112 		if (hdl != NULL)
113 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
114 			    "snapshot delimiter '@' is not expected here"));
115 		return (0);
116 	}
117 
118 	if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) {
119 		if (hdl != NULL)
120 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
121 			    "missing '@' delimiter in snapshot name"));
122 		return (0);
123 	}
124 
125 	if (!(type & ZFS_TYPE_BOOKMARK) && strchr(path, '#') != NULL) {
126 		if (hdl != NULL)
127 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
128 			    "bookmark delimiter '#' is not expected here"));
129 		return (0);
130 	}
131 
132 	if (type == ZFS_TYPE_BOOKMARK && strchr(path, '#') == NULL) {
133 		if (hdl != NULL)
134 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
135 			    "missing '#' delimiter in bookmark name"));
136 		return (0);
137 	}
138 
139 	if (modifying && strchr(path, '%') != NULL) {
140 		if (hdl != NULL)
141 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
142 			    "invalid character %c in name"), '%');
143 		return (0);
144 	}
145 
146 	if (entity_namecheck(path, &why, &what) != 0) {
147 		if (hdl != NULL) {
148 			switch (why) {
149 			case NAME_ERR_TOOLONG:
150 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
151 				    "name is too long"));
152 				break;
153 
154 			case NAME_ERR_LEADING_SLASH:
155 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
156 				    "leading slash in name"));
157 				break;
158 
159 			case NAME_ERR_EMPTY_COMPONENT:
160 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
161 				    "empty component or misplaced '@'"
162 				    " or '#' delimiter in name"));
163 				break;
164 
165 			case NAME_ERR_TRAILING_SLASH:
166 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
167 				    "trailing slash in name"));
168 				break;
169 
170 			case NAME_ERR_INVALCHAR:
171 				zfs_error_aux(hdl,
172 				    dgettext(TEXT_DOMAIN, "invalid character "
173 				    "'%c' in name"), what);
174 				break;
175 
176 			case NAME_ERR_MULTIPLE_DELIMITERS:
177 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
178 				    "multiple '@' and/or '#' delimiters in "
179 				    "name"));
180 				break;
181 
182 			case NAME_ERR_NOLETTER:
183 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
184 				    "pool doesn't begin with a letter"));
185 				break;
186 
187 			case NAME_ERR_RESERVED:
188 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
189 				    "name is reserved"));
190 				break;
191 
192 			case NAME_ERR_DISKLIKE:
193 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
194 				    "reserved disk name"));
195 				break;
196 
197 			case NAME_ERR_SELF_REF:
198 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
199 				    "self reference, '.' is found in name"));
200 				break;
201 
202 			case NAME_ERR_PARENT_REF:
203 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
204 				    "parent reference, '..' is found in name"));
205 				break;
206 
207 			default:
208 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
209 				    "(%d) not defined"), why);
210 				break;
211 			}
212 		}
213 
214 		return (0);
215 	}
216 
217 	return (-1);
218 }
219 
220 int
221 zfs_name_valid(const char *name, zfs_type_t type)
222 {
223 	if (type == ZFS_TYPE_POOL)
224 		return (zpool_name_valid(NULL, B_FALSE, name));
225 	return (zfs_validate_name(NULL, name, type, B_FALSE));
226 }
227 
228 /*
229  * This function takes the raw DSL properties, and filters out the user-defined
230  * properties into a separate nvlist.
231  */
232 static nvlist_t *
233 process_user_props(zfs_handle_t *zhp, nvlist_t *props)
234 {
235 	libzfs_handle_t *hdl = zhp->zfs_hdl;
236 	nvpair_t *elem;
237 	nvlist_t *propval;
238 	nvlist_t *nvl;
239 
240 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
241 		(void) no_memory(hdl);
242 		return (NULL);
243 	}
244 
245 	elem = NULL;
246 	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
247 		if (!zfs_prop_user(nvpair_name(elem)))
248 			continue;
249 
250 		verify(nvpair_value_nvlist(elem, &propval) == 0);
251 		if (nvlist_add_nvlist(nvl, nvpair_name(elem), propval) != 0) {
252 			nvlist_free(nvl);
253 			(void) no_memory(hdl);
254 			return (NULL);
255 		}
256 	}
257 
258 	return (nvl);
259 }
260 
261 static zpool_handle_t *
262 zpool_add_handle(zfs_handle_t *zhp, const char *pool_name)
263 {
264 	libzfs_handle_t *hdl = zhp->zfs_hdl;
265 	zpool_handle_t *zph;
266 
267 	if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) {
268 		if (hdl->libzfs_pool_handles != NULL)
269 			zph->zpool_next = hdl->libzfs_pool_handles;
270 		hdl->libzfs_pool_handles = zph;
271 	}
272 	return (zph);
273 }
274 
275 static zpool_handle_t *
276 zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len)
277 {
278 	libzfs_handle_t *hdl = zhp->zfs_hdl;
279 	zpool_handle_t *zph = hdl->libzfs_pool_handles;
280 
281 	while ((zph != NULL) &&
282 	    (strncmp(pool_name, zpool_get_name(zph), len) != 0))
283 		zph = zph->zpool_next;
284 	return (zph);
285 }
286 
287 /*
288  * Returns a handle to the pool that contains the provided dataset.
289  * If a handle to that pool already exists then that handle is returned.
290  * Otherwise, a new handle is created and added to the list of handles.
291  */
292 static zpool_handle_t *
293 zpool_handle(zfs_handle_t *zhp)
294 {
295 	char *pool_name;
296 	int len;
297 	zpool_handle_t *zph;
298 
299 	len = strcspn(zhp->zfs_name, "/@#") + 1;
300 	pool_name = zfs_alloc(zhp->zfs_hdl, len);
301 	(void) strlcpy(pool_name, zhp->zfs_name, len);
302 
303 	zph = zpool_find_handle(zhp, pool_name, len);
304 	if (zph == NULL)
305 		zph = zpool_add_handle(zhp, pool_name);
306 
307 	free(pool_name);
308 	return (zph);
309 }
310 
311 void
312 zpool_free_handles(libzfs_handle_t *hdl)
313 {
314 	zpool_handle_t *next, *zph = hdl->libzfs_pool_handles;
315 
316 	while (zph != NULL) {
317 		next = zph->zpool_next;
318 		zpool_close(zph);
319 		zph = next;
320 	}
321 	hdl->libzfs_pool_handles = NULL;
322 }
323 
324 /*
325  * Utility function to gather stats (objset and zpl) for the given object.
326  */
327 static int
328 get_stats_ioctl(zfs_handle_t *zhp, zfs_cmd_t *zc)
329 {
330 	libzfs_handle_t *hdl = zhp->zfs_hdl;
331 
332 	(void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
333 
334 	while (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, zc) != 0) {
335 		if (errno == ENOMEM) {
336 			if (zcmd_expand_dst_nvlist(hdl, zc) != 0) {
337 				return (-1);
338 			}
339 		} else {
340 			return (-1);
341 		}
342 	}
343 	return (0);
344 }
345 
346 /*
347  * Utility function to get the received properties of the given object.
348  */
349 static int
350 get_recvd_props_ioctl(zfs_handle_t *zhp)
351 {
352 	libzfs_handle_t *hdl = zhp->zfs_hdl;
353 	nvlist_t *recvdprops;
354 	zfs_cmd_t zc = {"\0"};
355 	int err;
356 
357 	if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
358 		return (-1);
359 
360 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
361 
362 	while (zfs_ioctl(hdl, ZFS_IOC_OBJSET_RECVD_PROPS, &zc) != 0) {
363 		if (errno == ENOMEM) {
364 			if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
365 				return (-1);
366 			}
367 		} else {
368 			zcmd_free_nvlists(&zc);
369 			return (-1);
370 		}
371 	}
372 
373 	err = zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &recvdprops);
374 	zcmd_free_nvlists(&zc);
375 	if (err != 0)
376 		return (-1);
377 
378 	nvlist_free(zhp->zfs_recvd_props);
379 	zhp->zfs_recvd_props = recvdprops;
380 
381 	return (0);
382 }
383 
384 static int
385 put_stats_zhdl(zfs_handle_t *zhp, zfs_cmd_t *zc)
386 {
387 	nvlist_t *allprops, *userprops;
388 
389 	zhp->zfs_dmustats = zc->zc_objset_stats; /* structure assignment */
390 
391 	if (zcmd_read_dst_nvlist(zhp->zfs_hdl, zc, &allprops) != 0) {
392 		return (-1);
393 	}
394 
395 	/*
396 	 * XXX Why do we store the user props separately, in addition to
397 	 * storing them in zfs_props?
398 	 */
399 	if ((userprops = process_user_props(zhp, allprops)) == NULL) {
400 		nvlist_free(allprops);
401 		return (-1);
402 	}
403 
404 	nvlist_free(zhp->zfs_props);
405 	nvlist_free(zhp->zfs_user_props);
406 
407 	zhp->zfs_props = allprops;
408 	zhp->zfs_user_props = userprops;
409 
410 	return (0);
411 }
412 
413 static int
414 get_stats(zfs_handle_t *zhp)
415 {
416 	int rc = 0;
417 	zfs_cmd_t zc = {"\0"};
418 
419 	if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
420 		return (-1);
421 	if (get_stats_ioctl(zhp, &zc) != 0)
422 		rc = -1;
423 	else if (put_stats_zhdl(zhp, &zc) != 0)
424 		rc = -1;
425 	zcmd_free_nvlists(&zc);
426 	return (rc);
427 }
428 
429 /*
430  * Refresh the properties currently stored in the handle.
431  */
432 void
433 zfs_refresh_properties(zfs_handle_t *zhp)
434 {
435 	(void) get_stats(zhp);
436 }
437 
438 /*
439  * Makes a handle from the given dataset name.  Used by zfs_open() and
440  * zfs_iter_* to create child handles on the fly.
441  */
442 static int
443 make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
444 {
445 	if (put_stats_zhdl(zhp, zc) != 0)
446 		return (-1);
447 
448 	/*
449 	 * We've managed to open the dataset and gather statistics.  Determine
450 	 * the high-level type.
451 	 */
452 	if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) {
453 		zhp->zfs_head_type = ZFS_TYPE_VOLUME;
454 	} else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) {
455 		zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM;
456 	} else if (zhp->zfs_dmustats.dds_type == DMU_OST_OTHER) {
457 		errno = EINVAL;
458 		return (-1);
459 	} else if (zhp->zfs_dmustats.dds_inconsistent) {
460 		errno = EBUSY;
461 		return (-1);
462 	} else {
463 		abort();
464 	}
465 
466 	if (zhp->zfs_dmustats.dds_is_snapshot)
467 		zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
468 	else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
469 		zhp->zfs_type = ZFS_TYPE_VOLUME;
470 	else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
471 		zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
472 	else
473 		abort();	/* we should never see any other types */
474 
475 	if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL)
476 		return (-1);
477 
478 	return (0);
479 }
480 
481 zfs_handle_t *
482 make_dataset_handle(libzfs_handle_t *hdl, const char *path)
483 {
484 	zfs_cmd_t zc = {"\0"};
485 
486 	zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
487 
488 	if (zhp == NULL)
489 		return (NULL);
490 
491 	zhp->zfs_hdl = hdl;
492 	(void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
493 	if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) {
494 		free(zhp);
495 		return (NULL);
496 	}
497 	if (get_stats_ioctl(zhp, &zc) == -1) {
498 		zcmd_free_nvlists(&zc);
499 		free(zhp);
500 		return (NULL);
501 	}
502 	if (make_dataset_handle_common(zhp, &zc) == -1) {
503 		free(zhp);
504 		zhp = NULL;
505 	}
506 	zcmd_free_nvlists(&zc);
507 	return (zhp);
508 }
509 
510 zfs_handle_t *
511 make_dataset_handle_zc(libzfs_handle_t *hdl, zfs_cmd_t *zc)
512 {
513 	zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
514 
515 	if (zhp == NULL)
516 		return (NULL);
517 
518 	zhp->zfs_hdl = hdl;
519 	(void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name));
520 	if (make_dataset_handle_common(zhp, zc) == -1) {
521 		free(zhp);
522 		return (NULL);
523 	}
524 	return (zhp);
525 }
526 
527 zfs_handle_t *
528 make_dataset_simple_handle_zc(zfs_handle_t *pzhp, zfs_cmd_t *zc)
529 {
530 	zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
531 
532 	if (zhp == NULL)
533 		return (NULL);
534 
535 	zhp->zfs_hdl = pzhp->zfs_hdl;
536 	(void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name));
537 	zhp->zfs_head_type = pzhp->zfs_type;
538 	zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
539 	zhp->zpool_hdl = zpool_handle(zhp);
540 
541 	return (zhp);
542 }
543 
544 zfs_handle_t *
545 zfs_handle_dup(zfs_handle_t *zhp_orig)
546 {
547 	zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
548 
549 	if (zhp == NULL)
550 		return (NULL);
551 
552 	zhp->zfs_hdl = zhp_orig->zfs_hdl;
553 	zhp->zpool_hdl = zhp_orig->zpool_hdl;
554 	(void) strlcpy(zhp->zfs_name, zhp_orig->zfs_name,
555 	    sizeof (zhp->zfs_name));
556 	zhp->zfs_type = zhp_orig->zfs_type;
557 	zhp->zfs_head_type = zhp_orig->zfs_head_type;
558 	zhp->zfs_dmustats = zhp_orig->zfs_dmustats;
559 	if (zhp_orig->zfs_props != NULL) {
560 		if (nvlist_dup(zhp_orig->zfs_props, &zhp->zfs_props, 0) != 0) {
561 			(void) no_memory(zhp->zfs_hdl);
562 			zfs_close(zhp);
563 			return (NULL);
564 		}
565 	}
566 	if (zhp_orig->zfs_user_props != NULL) {
567 		if (nvlist_dup(zhp_orig->zfs_user_props,
568 		    &zhp->zfs_user_props, 0) != 0) {
569 			(void) no_memory(zhp->zfs_hdl);
570 			zfs_close(zhp);
571 			return (NULL);
572 		}
573 	}
574 	if (zhp_orig->zfs_recvd_props != NULL) {
575 		if (nvlist_dup(zhp_orig->zfs_recvd_props,
576 		    &zhp->zfs_recvd_props, 0)) {
577 			(void) no_memory(zhp->zfs_hdl);
578 			zfs_close(zhp);
579 			return (NULL);
580 		}
581 	}
582 	zhp->zfs_mntcheck = zhp_orig->zfs_mntcheck;
583 	if (zhp_orig->zfs_mntopts != NULL) {
584 		zhp->zfs_mntopts = zfs_strdup(zhp_orig->zfs_hdl,
585 		    zhp_orig->zfs_mntopts);
586 	}
587 	zhp->zfs_props_table = zhp_orig->zfs_props_table;
588 	return (zhp);
589 }
590 
591 boolean_t
592 zfs_bookmark_exists(const char *path)
593 {
594 	nvlist_t *bmarks;
595 	nvlist_t *props;
596 	char fsname[ZFS_MAX_DATASET_NAME_LEN];
597 	char *bmark_name;
598 	char *pound;
599 	int err;
600 	boolean_t rv;
601 
602 	(void) strlcpy(fsname, path, sizeof (fsname));
603 	pound = strchr(fsname, '#');
604 	if (pound == NULL)
605 		return (B_FALSE);
606 
607 	*pound = '\0';
608 	bmark_name = pound + 1;
609 	props = fnvlist_alloc();
610 	err = lzc_get_bookmarks(fsname, props, &bmarks);
611 	nvlist_free(props);
612 	if (err != 0) {
613 		nvlist_free(bmarks);
614 		return (B_FALSE);
615 	}
616 
617 	rv = nvlist_exists(bmarks, bmark_name);
618 	nvlist_free(bmarks);
619 	return (rv);
620 }
621 
622 zfs_handle_t *
623 make_bookmark_handle(zfs_handle_t *parent, const char *path,
624     nvlist_t *bmark_props)
625 {
626 	zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
627 
628 	if (zhp == NULL)
629 		return (NULL);
630 
631 	/* Fill in the name. */
632 	zhp->zfs_hdl = parent->zfs_hdl;
633 	(void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
634 
635 	/* Set the property lists. */
636 	if (nvlist_dup(bmark_props, &zhp->zfs_props, 0) != 0) {
637 		free(zhp);
638 		return (NULL);
639 	}
640 
641 	/* Set the types. */
642 	zhp->zfs_head_type = parent->zfs_head_type;
643 	zhp->zfs_type = ZFS_TYPE_BOOKMARK;
644 
645 	if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL) {
646 		nvlist_free(zhp->zfs_props);
647 		free(zhp);
648 		return (NULL);
649 	}
650 
651 	return (zhp);
652 }
653 
654 struct zfs_open_bookmarks_cb_data {
655 	const char *path;
656 	zfs_handle_t *zhp;
657 };
658 
659 static int
660 zfs_open_bookmarks_cb(zfs_handle_t *zhp, void *data)
661 {
662 	struct zfs_open_bookmarks_cb_data *dp = data;
663 
664 	/*
665 	 * Is it the one we are looking for?
666 	 */
667 	if (strcmp(dp->path, zfs_get_name(zhp)) == 0) {
668 		/*
669 		 * We found it.  Save it and let the caller know we are done.
670 		 */
671 		dp->zhp = zhp;
672 		return (EEXIST);
673 	}
674 
675 	/*
676 	 * Not found.  Close the handle and ask for another one.
677 	 */
678 	zfs_close(zhp);
679 	return (0);
680 }
681 
682 /*
683  * Opens the given snapshot, bookmark, filesystem, or volume.   The 'types'
684  * argument is a mask of acceptable types.  The function will print an
685  * appropriate error message and return NULL if it can't be opened.
686  */
687 zfs_handle_t *
688 zfs_open(libzfs_handle_t *hdl, const char *path, int types)
689 {
690 	zfs_handle_t *zhp;
691 	char errbuf[1024];
692 	char *bookp;
693 
694 	(void) snprintf(errbuf, sizeof (errbuf),
695 	    dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
696 
697 	/*
698 	 * Validate the name before we even try to open it.
699 	 */
700 	if (!zfs_validate_name(hdl, path, types, B_FALSE)) {
701 		(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
702 		return (NULL);
703 	}
704 
705 	/*
706 	 * Bookmarks needs to be handled separately.
707 	 */
708 	bookp = strchr(path, '#');
709 	if (bookp == NULL) {
710 		/*
711 		 * Try to get stats for the dataset, which will tell us if it
712 		 * exists.
713 		 */
714 		errno = 0;
715 		if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
716 			(void) zfs_standard_error(hdl, errno, errbuf);
717 			return (NULL);
718 		}
719 	} else {
720 		char dsname[ZFS_MAX_DATASET_NAME_LEN];
721 		zfs_handle_t *pzhp;
722 		struct zfs_open_bookmarks_cb_data cb_data = {path, NULL};
723 
724 		/*
725 		 * We need to cut out '#' and everything after '#'
726 		 * to get the parent dataset name only.
727 		 */
728 		assert(bookp - path < sizeof (dsname));
729 		(void) strncpy(dsname, path, bookp - path);
730 		dsname[bookp - path] = '\0';
731 
732 		/*
733 		 * Create handle for the parent dataset.
734 		 */
735 		errno = 0;
736 		if ((pzhp = make_dataset_handle(hdl, dsname)) == NULL) {
737 			(void) zfs_standard_error(hdl, errno, errbuf);
738 			return (NULL);
739 		}
740 
741 		/*
742 		 * Iterate bookmarks to find the right one.
743 		 */
744 		errno = 0;
745 		if ((zfs_iter_bookmarks(pzhp, zfs_open_bookmarks_cb,
746 		    &cb_data) == 0) && (cb_data.zhp == NULL)) {
747 			(void) zfs_error(hdl, EZFS_NOENT, errbuf);
748 			zfs_close(pzhp);
749 			return (NULL);
750 		}
751 		if (cb_data.zhp == NULL) {
752 			(void) zfs_standard_error(hdl, errno, errbuf);
753 			zfs_close(pzhp);
754 			return (NULL);
755 		}
756 		zhp = cb_data.zhp;
757 
758 		/*
759 		 * Cleanup.
760 		 */
761 		zfs_close(pzhp);
762 	}
763 
764 	if (!(types & zhp->zfs_type)) {
765 		(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
766 		zfs_close(zhp);
767 		return (NULL);
768 	}
769 
770 	return (zhp);
771 }
772 
773 /*
774  * Release a ZFS handle.  Nothing to do but free the associated memory.
775  */
776 void
777 zfs_close(zfs_handle_t *zhp)
778 {
779 	if (zhp->zfs_mntopts)
780 		free(zhp->zfs_mntopts);
781 	nvlist_free(zhp->zfs_props);
782 	nvlist_free(zhp->zfs_user_props);
783 	nvlist_free(zhp->zfs_recvd_props);
784 	free(zhp);
785 }
786 
787 typedef struct mnttab_node {
788 	struct mnttab mtn_mt;
789 	avl_node_t mtn_node;
790 } mnttab_node_t;
791 
792 static int
793 libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
794 {
795 	const mnttab_node_t *mtn1 = (const mnttab_node_t *)arg1;
796 	const mnttab_node_t *mtn2 = (const mnttab_node_t *)arg2;
797 	int rv;
798 
799 	rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
800 
801 	return (TREE_ISIGN(rv));
802 }
803 
804 void
805 libzfs_mnttab_init(libzfs_handle_t *hdl)
806 {
807 	pthread_mutex_init(&hdl->libzfs_mnttab_cache_lock, NULL);
808 	assert(avl_numnodes(&hdl->libzfs_mnttab_cache) == 0);
809 	avl_create(&hdl->libzfs_mnttab_cache, libzfs_mnttab_cache_compare,
810 	    sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
811 }
812 
813 static int
814 libzfs_mnttab_update(libzfs_handle_t *hdl)
815 {
816 	FILE *mnttab;
817 	struct mnttab entry;
818 
819 	if ((mnttab = fopen(MNTTAB, "re")) == NULL)
820 		return (ENOENT);
821 
822 	while (getmntent(mnttab, &entry) == 0) {
823 		mnttab_node_t *mtn;
824 		avl_index_t where;
825 
826 		if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
827 			continue;
828 
829 		mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
830 		mtn->mtn_mt.mnt_special = zfs_strdup(hdl, entry.mnt_special);
831 		mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp);
832 		mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype);
833 		mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
834 
835 		/* Exclude duplicate mounts */
836 		if (avl_find(&hdl->libzfs_mnttab_cache, mtn, &where) != NULL) {
837 			free(mtn->mtn_mt.mnt_special);
838 			free(mtn->mtn_mt.mnt_mountp);
839 			free(mtn->mtn_mt.mnt_fstype);
840 			free(mtn->mtn_mt.mnt_mntopts);
841 			free(mtn);
842 			continue;
843 		}
844 
845 		avl_add(&hdl->libzfs_mnttab_cache, mtn);
846 	}
847 
848 	(void) fclose(mnttab);
849 	return (0);
850 }
851 
852 void
853 libzfs_mnttab_fini(libzfs_handle_t *hdl)
854 {
855 	void *cookie = NULL;
856 	mnttab_node_t *mtn;
857 
858 	while ((mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie))
859 	    != NULL) {
860 		free(mtn->mtn_mt.mnt_special);
861 		free(mtn->mtn_mt.mnt_mountp);
862 		free(mtn->mtn_mt.mnt_fstype);
863 		free(mtn->mtn_mt.mnt_mntopts);
864 		free(mtn);
865 	}
866 	avl_destroy(&hdl->libzfs_mnttab_cache);
867 	(void) pthread_mutex_destroy(&hdl->libzfs_mnttab_cache_lock);
868 }
869 
870 void
871 libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
872 {
873 	hdl->libzfs_mnttab_enable = enable;
874 }
875 
876 int
877 libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
878     struct mnttab *entry)
879 {
880 	FILE *mnttab;
881 	mnttab_node_t find;
882 	mnttab_node_t *mtn;
883 	int ret = ENOENT;
884 
885 	if (!hdl->libzfs_mnttab_enable) {
886 		struct mnttab srch = { 0 };
887 
888 		if (avl_numnodes(&hdl->libzfs_mnttab_cache))
889 			libzfs_mnttab_fini(hdl);
890 
891 		if ((mnttab = fopen(MNTTAB, "re")) == NULL)
892 			return (ENOENT);
893 
894 		srch.mnt_special = (char *)fsname;
895 		srch.mnt_fstype = MNTTYPE_ZFS;
896 		ret = getmntany(mnttab, entry, &srch) ? ENOENT : 0;
897 		(void) fclose(mnttab);
898 		return (ret);
899 	}
900 
901 	pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
902 	if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0) {
903 		int error;
904 
905 		if ((error = libzfs_mnttab_update(hdl)) != 0) {
906 			pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
907 			return (error);
908 		}
909 	}
910 
911 	find.mtn_mt.mnt_special = (char *)fsname;
912 	mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL);
913 	if (mtn) {
914 		*entry = mtn->mtn_mt;
915 		ret = 0;
916 	}
917 	pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
918 	return (ret);
919 }
920 
921 void
922 libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
923     const char *mountp, const char *mntopts)
924 {
925 	mnttab_node_t *mtn;
926 
927 	pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
928 	if (avl_numnodes(&hdl->libzfs_mnttab_cache) != 0) {
929 		mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
930 		mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special);
931 		mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp);
932 		mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, MNTTYPE_ZFS);
933 		mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts);
934 		/*
935 		 * Another thread may have already added this entry
936 		 * via libzfs_mnttab_update. If so we should skip it.
937 		 */
938 		if (avl_find(&hdl->libzfs_mnttab_cache, mtn, NULL) != NULL) {
939 			free(mtn->mtn_mt.mnt_special);
940 			free(mtn->mtn_mt.mnt_mountp);
941 			free(mtn->mtn_mt.mnt_fstype);
942 			free(mtn->mtn_mt.mnt_mntopts);
943 			free(mtn);
944 		} else {
945 			avl_add(&hdl->libzfs_mnttab_cache, mtn);
946 		}
947 	}
948 	pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
949 }
950 
951 void
952 libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
953 {
954 	mnttab_node_t find;
955 	mnttab_node_t *ret;
956 
957 	pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
958 	find.mtn_mt.mnt_special = (char *)fsname;
959 	if ((ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL))
960 	    != NULL) {
961 		avl_remove(&hdl->libzfs_mnttab_cache, ret);
962 		free(ret->mtn_mt.mnt_special);
963 		free(ret->mtn_mt.mnt_mountp);
964 		free(ret->mtn_mt.mnt_fstype);
965 		free(ret->mtn_mt.mnt_mntopts);
966 		free(ret);
967 	}
968 	pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
969 }
970 
971 int
972 zfs_spa_version(zfs_handle_t *zhp, int *spa_version)
973 {
974 	zpool_handle_t *zpool_handle = zhp->zpool_hdl;
975 
976 	if (zpool_handle == NULL)
977 		return (-1);
978 
979 	*spa_version = zpool_get_prop_int(zpool_handle,
980 	    ZPOOL_PROP_VERSION, NULL);
981 	return (0);
982 }
983 
984 /*
985  * The choice of reservation property depends on the SPA version.
986  */
987 static int
988 zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
989 {
990 	int spa_version;
991 
992 	if (zfs_spa_version(zhp, &spa_version) < 0)
993 		return (-1);
994 
995 	if (spa_version >= SPA_VERSION_REFRESERVATION)
996 		*resv_prop = ZFS_PROP_REFRESERVATION;
997 	else
998 		*resv_prop = ZFS_PROP_RESERVATION;
999 
1000 	return (0);
1001 }
1002 
1003 /*
1004  * Given an nvlist of properties to set, validates that they are correct, and
1005  * parses any numeric properties (index, boolean, etc) if they are specified as
1006  * strings.
1007  */
1008 nvlist_t *
1009 zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
1010     uint64_t zoned, zfs_handle_t *zhp, zpool_handle_t *zpool_hdl,
1011     boolean_t key_params_ok, const char *errbuf)
1012 {
1013 	nvpair_t *elem;
1014 	uint64_t intval;
1015 	char *strval;
1016 	zfs_prop_t prop;
1017 	nvlist_t *ret;
1018 	int chosen_normal = -1;
1019 	int chosen_utf = -1;
1020 
1021 	if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
1022 		(void) no_memory(hdl);
1023 		return (NULL);
1024 	}
1025 
1026 	/*
1027 	 * Make sure this property is valid and applies to this type.
1028 	 */
1029 
1030 	elem = NULL;
1031 	while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
1032 		const char *propname = nvpair_name(elem);
1033 
1034 		prop = zfs_name_to_prop(propname);
1035 		if (prop == ZPROP_INVAL && zfs_prop_user(propname)) {
1036 			/*
1037 			 * This is a user property: make sure it's a
1038 			 * string, and that it's less than ZAP_MAXNAMELEN.
1039 			 */
1040 			if (nvpair_type(elem) != DATA_TYPE_STRING) {
1041 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1042 				    "'%s' must be a string"), propname);
1043 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1044 				goto error;
1045 			}
1046 
1047 			if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
1048 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1049 				    "property name '%s' is too long"),
1050 				    propname);
1051 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1052 				goto error;
1053 			}
1054 
1055 			(void) nvpair_value_string(elem, &strval);
1056 			if (nvlist_add_string(ret, propname, strval) != 0) {
1057 				(void) no_memory(hdl);
1058 				goto error;
1059 			}
1060 			continue;
1061 		}
1062 
1063 		/*
1064 		 * Currently, only user properties can be modified on
1065 		 * snapshots.
1066 		 */
1067 		if (type == ZFS_TYPE_SNAPSHOT) {
1068 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1069 			    "this property can not be modified for snapshots"));
1070 			(void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
1071 			goto error;
1072 		}
1073 
1074 		if (prop == ZPROP_INVAL && zfs_prop_userquota(propname)) {
1075 			zfs_userquota_prop_t uqtype;
1076 			char *newpropname = NULL;
1077 			char domain[128];
1078 			uint64_t rid;
1079 			uint64_t valary[3];
1080 			int rc;
1081 
1082 			if (userquota_propname_decode(propname, zoned,
1083 			    &uqtype, domain, sizeof (domain), &rid) != 0) {
1084 				zfs_error_aux(hdl,
1085 				    dgettext(TEXT_DOMAIN,
1086 				    "'%s' has an invalid user/group name"),
1087 				    propname);
1088 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1089 				goto error;
1090 			}
1091 
1092 			if (uqtype != ZFS_PROP_USERQUOTA &&
1093 			    uqtype != ZFS_PROP_GROUPQUOTA &&
1094 			    uqtype != ZFS_PROP_USEROBJQUOTA &&
1095 			    uqtype != ZFS_PROP_GROUPOBJQUOTA &&
1096 			    uqtype != ZFS_PROP_PROJECTQUOTA &&
1097 			    uqtype != ZFS_PROP_PROJECTOBJQUOTA) {
1098 				zfs_error_aux(hdl,
1099 				    dgettext(TEXT_DOMAIN, "'%s' is readonly"),
1100 				    propname);
1101 				(void) zfs_error(hdl, EZFS_PROPREADONLY,
1102 				    errbuf);
1103 				goto error;
1104 			}
1105 
1106 			if (nvpair_type(elem) == DATA_TYPE_STRING) {
1107 				(void) nvpair_value_string(elem, &strval);
1108 				if (strcmp(strval, "none") == 0) {
1109 					intval = 0;
1110 				} else if (zfs_nicestrtonum(hdl,
1111 				    strval, &intval) != 0) {
1112 					(void) zfs_error(hdl,
1113 					    EZFS_BADPROP, errbuf);
1114 					goto error;
1115 				}
1116 			} else if (nvpair_type(elem) ==
1117 			    DATA_TYPE_UINT64) {
1118 				(void) nvpair_value_uint64(elem, &intval);
1119 				if (intval == 0) {
1120 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1121 					    "use 'none' to disable "
1122 					    "{user|group|project}quota"));
1123 					goto error;
1124 				}
1125 			} else {
1126 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1127 				    "'%s' must be a number"), propname);
1128 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1129 				goto error;
1130 			}
1131 
1132 			/*
1133 			 * Encode the prop name as
1134 			 * userquota@<hex-rid>-domain, to make it easy
1135 			 * for the kernel to decode.
1136 			 */
1137 			rc = asprintf(&newpropname, "%s%llx-%s",
1138 			    zfs_userquota_prop_prefixes[uqtype],
1139 			    (longlong_t)rid, domain);
1140 			if (rc == -1 || newpropname == NULL) {
1141 				(void) no_memory(hdl);
1142 				goto error;
1143 			}
1144 
1145 			valary[0] = uqtype;
1146 			valary[1] = rid;
1147 			valary[2] = intval;
1148 			if (nvlist_add_uint64_array(ret, newpropname,
1149 			    valary, 3) != 0) {
1150 				free(newpropname);
1151 				(void) no_memory(hdl);
1152 				goto error;
1153 			}
1154 			free(newpropname);
1155 			continue;
1156 		} else if (prop == ZPROP_INVAL && zfs_prop_written(propname)) {
1157 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1158 			    "'%s' is readonly"),
1159 			    propname);
1160 			(void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
1161 			goto error;
1162 		}
1163 
1164 		if (prop == ZPROP_INVAL) {
1165 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1166 			    "invalid property '%s'"), propname);
1167 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1168 			goto error;
1169 		}
1170 
1171 		if (!zfs_prop_valid_for_type(prop, type, B_FALSE)) {
1172 			zfs_error_aux(hdl,
1173 			    dgettext(TEXT_DOMAIN, "'%s' does not "
1174 			    "apply to datasets of this type"), propname);
1175 			(void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
1176 			goto error;
1177 		}
1178 
1179 		if (zfs_prop_readonly(prop) &&
1180 		    !(zfs_prop_setonce(prop) && zhp == NULL) &&
1181 		    !(zfs_prop_encryption_key_param(prop) && key_params_ok)) {
1182 			zfs_error_aux(hdl,
1183 			    dgettext(TEXT_DOMAIN, "'%s' is readonly"),
1184 			    propname);
1185 			(void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
1186 			goto error;
1187 		}
1188 
1189 		if (zprop_parse_value(hdl, elem, prop, type, ret,
1190 		    &strval, &intval, errbuf) != 0)
1191 			goto error;
1192 
1193 		/*
1194 		 * Perform some additional checks for specific properties.
1195 		 */
1196 		switch (prop) {
1197 		case ZFS_PROP_VERSION:
1198 		{
1199 			int version;
1200 
1201 			if (zhp == NULL)
1202 				break;
1203 			version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
1204 			if (intval < version) {
1205 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1206 				    "Can not downgrade; already at version %u"),
1207 				    version);
1208 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1209 				goto error;
1210 			}
1211 			break;
1212 		}
1213 
1214 		case ZFS_PROP_VOLBLOCKSIZE:
1215 		case ZFS_PROP_RECORDSIZE:
1216 		{
1217 			int maxbs = SPA_MAXBLOCKSIZE;
1218 			char buf[64];
1219 
1220 			if (zpool_hdl != NULL) {
1221 				maxbs = zpool_get_prop_int(zpool_hdl,
1222 				    ZPOOL_PROP_MAXBLOCKSIZE, NULL);
1223 			}
1224 			/*
1225 			 * The value must be a power of two between
1226 			 * SPA_MINBLOCKSIZE and maxbs.
1227 			 */
1228 			if (intval < SPA_MINBLOCKSIZE ||
1229 			    intval > maxbs || !ISP2(intval)) {
1230 				zfs_nicebytes(maxbs, buf, sizeof (buf));
1231 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1232 				    "'%s' must be power of 2 from 512B "
1233 				    "to %s"), propname, buf);
1234 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1235 				goto error;
1236 			}
1237 			break;
1238 		}
1239 
1240 		case ZFS_PROP_SPECIAL_SMALL_BLOCKS:
1241 		{
1242 			int maxbs = SPA_OLD_MAXBLOCKSIZE;
1243 			char buf[64];
1244 
1245 			if (zpool_hdl != NULL) {
1246 				char state[64] = "";
1247 
1248 				maxbs = zpool_get_prop_int(zpool_hdl,
1249 				    ZPOOL_PROP_MAXBLOCKSIZE, NULL);
1250 
1251 				/*
1252 				 * Issue a warning but do not fail so that
1253 				 * tests for settable properties succeed.
1254 				 */
1255 				if (zpool_prop_get_feature(zpool_hdl,
1256 				    "feature@allocation_classes", state,
1257 				    sizeof (state)) != 0 ||
1258 				    strcmp(state, ZFS_FEATURE_ACTIVE) != 0) {
1259 					(void) fprintf(stderr, gettext(
1260 					    "%s: property requires a special "
1261 					    "device in the pool\n"), propname);
1262 				}
1263 			}
1264 			if (intval != 0 &&
1265 			    (intval < SPA_MINBLOCKSIZE ||
1266 			    intval > maxbs || !ISP2(intval))) {
1267 				zfs_nicebytes(maxbs, buf, sizeof (buf));
1268 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1269 				    "invalid '%s=%llu' property: must be zero "
1270 				    "or a power of 2 from 512B to %s"),
1271 				    propname, (unsigned long long)intval, buf);
1272 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1273 				goto error;
1274 			}
1275 			break;
1276 		}
1277 
1278 		case ZFS_PROP_MLSLABEL:
1279 		{
1280 #ifdef HAVE_MLSLABEL
1281 			/*
1282 			 * Verify the mlslabel string and convert to
1283 			 * internal hex label string.
1284 			 */
1285 
1286 			m_label_t *new_sl;
1287 			char *hex = NULL;	/* internal label string */
1288 
1289 			/* Default value is already OK. */
1290 			if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
1291 				break;
1292 
1293 			/* Verify the label can be converted to binary form */
1294 			if (((new_sl = m_label_alloc(MAC_LABEL)) == NULL) ||
1295 			    (str_to_label(strval, &new_sl, MAC_LABEL,
1296 			    L_NO_CORRECTION, NULL) == -1)) {
1297 				goto badlabel;
1298 			}
1299 
1300 			/* Now translate to hex internal label string */
1301 			if (label_to_str(new_sl, &hex, M_INTERNAL,
1302 			    DEF_NAMES) != 0) {
1303 				if (hex)
1304 					free(hex);
1305 				goto badlabel;
1306 			}
1307 			m_label_free(new_sl);
1308 
1309 			/* If string is already in internal form, we're done. */
1310 			if (strcmp(strval, hex) == 0) {
1311 				free(hex);
1312 				break;
1313 			}
1314 
1315 			/* Replace the label string with the internal form. */
1316 			(void) nvlist_remove(ret, zfs_prop_to_name(prop),
1317 			    DATA_TYPE_STRING);
1318 			verify(nvlist_add_string(ret, zfs_prop_to_name(prop),
1319 			    hex) == 0);
1320 			free(hex);
1321 
1322 			break;
1323 
1324 badlabel:
1325 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1326 			    "invalid mlslabel '%s'"), strval);
1327 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1328 			m_label_free(new_sl);	/* OK if null */
1329 			goto error;
1330 #else
1331 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1332 			    "mlslabels are unsupported"));
1333 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1334 			goto error;
1335 #endif /* HAVE_MLSLABEL */
1336 		}
1337 
1338 		case ZFS_PROP_MOUNTPOINT:
1339 		{
1340 			namecheck_err_t why;
1341 
1342 			if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 ||
1343 			    strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0)
1344 				break;
1345 
1346 			if (mountpoint_namecheck(strval, &why)) {
1347 				switch (why) {
1348 				case NAME_ERR_LEADING_SLASH:
1349 					zfs_error_aux(hdl,
1350 					    dgettext(TEXT_DOMAIN,
1351 					    "'%s' must be an absolute path, "
1352 					    "'none', or 'legacy'"), propname);
1353 					break;
1354 				case NAME_ERR_TOOLONG:
1355 					zfs_error_aux(hdl,
1356 					    dgettext(TEXT_DOMAIN,
1357 					    "component of '%s' is too long"),
1358 					    propname);
1359 					break;
1360 
1361 				default:
1362 					zfs_error_aux(hdl,
1363 					    dgettext(TEXT_DOMAIN,
1364 					    "(%d) not defined"),
1365 					    why);
1366 					break;
1367 				}
1368 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1369 				goto error;
1370 			}
1371 			zfs_fallthrough;
1372 		}
1373 
1374 		case ZFS_PROP_SHARESMB:
1375 		case ZFS_PROP_SHARENFS:
1376 			/*
1377 			 * For the mountpoint and sharenfs or sharesmb
1378 			 * properties, check if it can be set in a
1379 			 * global/non-global zone based on
1380 			 * the zoned property value:
1381 			 *
1382 			 *		global zone	    non-global zone
1383 			 * --------------------------------------------------
1384 			 * zoned=on	mountpoint (no)	    mountpoint (yes)
1385 			 *		sharenfs (no)	    sharenfs (no)
1386 			 *		sharesmb (no)	    sharesmb (no)
1387 			 *
1388 			 * zoned=off	mountpoint (yes)	N/A
1389 			 *		sharenfs (yes)
1390 			 *		sharesmb (yes)
1391 			 */
1392 			if (zoned) {
1393 				if (getzoneid() == GLOBAL_ZONEID) {
1394 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1395 					    "'%s' cannot be set on "
1396 					    "dataset in a non-global zone"),
1397 					    propname);
1398 					(void) zfs_error(hdl, EZFS_ZONED,
1399 					    errbuf);
1400 					goto error;
1401 				} else if (prop == ZFS_PROP_SHARENFS ||
1402 				    prop == ZFS_PROP_SHARESMB) {
1403 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1404 					    "'%s' cannot be set in "
1405 					    "a non-global zone"), propname);
1406 					(void) zfs_error(hdl, EZFS_ZONED,
1407 					    errbuf);
1408 					goto error;
1409 				}
1410 			} else if (getzoneid() != GLOBAL_ZONEID) {
1411 				/*
1412 				 * If zoned property is 'off', this must be in
1413 				 * a global zone. If not, something is wrong.
1414 				 */
1415 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1416 				    "'%s' cannot be set while dataset "
1417 				    "'zoned' property is set"), propname);
1418 				(void) zfs_error(hdl, EZFS_ZONED, errbuf);
1419 				goto error;
1420 			}
1421 
1422 			/*
1423 			 * At this point, it is legitimate to set the
1424 			 * property. Now we want to make sure that the
1425 			 * property value is valid if it is sharenfs.
1426 			 */
1427 			if ((prop == ZFS_PROP_SHARENFS ||
1428 			    prop == ZFS_PROP_SHARESMB) &&
1429 			    strcmp(strval, "on") != 0 &&
1430 			    strcmp(strval, "off") != 0) {
1431 				zfs_share_proto_t proto;
1432 
1433 				if (prop == ZFS_PROP_SHARESMB)
1434 					proto = PROTO_SMB;
1435 				else
1436 					proto = PROTO_NFS;
1437 
1438 				if (zfs_parse_options(strval, proto) != SA_OK) {
1439 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1440 					    "'%s' cannot be set to invalid "
1441 					    "options"), propname);
1442 					(void) zfs_error(hdl, EZFS_BADPROP,
1443 					    errbuf);
1444 					goto error;
1445 				}
1446 			}
1447 
1448 			break;
1449 
1450 		case ZFS_PROP_KEYLOCATION:
1451 			if (!zfs_prop_valid_keylocation(strval, B_FALSE)) {
1452 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1453 				    "invalid keylocation"));
1454 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1455 				goto error;
1456 			}
1457 
1458 			if (zhp != NULL) {
1459 				uint64_t crypt =
1460 				    zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
1461 
1462 				if (crypt == ZIO_CRYPT_OFF &&
1463 				    strcmp(strval, "none") != 0) {
1464 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1465 					    "keylocation must be 'none' "
1466 					    "for unencrypted datasets"));
1467 					(void) zfs_error(hdl, EZFS_BADPROP,
1468 					    errbuf);
1469 					goto error;
1470 				} else if (crypt != ZIO_CRYPT_OFF &&
1471 				    strcmp(strval, "none") == 0) {
1472 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1473 					    "keylocation must not be 'none' "
1474 					    "for encrypted datasets"));
1475 					(void) zfs_error(hdl, EZFS_BADPROP,
1476 					    errbuf);
1477 					goto error;
1478 				}
1479 			}
1480 			break;
1481 
1482 		case ZFS_PROP_PBKDF2_ITERS:
1483 			if (intval < MIN_PBKDF2_ITERATIONS) {
1484 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1485 				    "minimum pbkdf2 iterations is %u"),
1486 				    MIN_PBKDF2_ITERATIONS);
1487 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1488 				goto error;
1489 			}
1490 			break;
1491 
1492 		case ZFS_PROP_UTF8ONLY:
1493 			chosen_utf = (int)intval;
1494 			break;
1495 
1496 		case ZFS_PROP_NORMALIZE:
1497 			chosen_normal = (int)intval;
1498 			break;
1499 
1500 		default:
1501 			break;
1502 		}
1503 
1504 		/*
1505 		 * For changes to existing volumes, we have some additional
1506 		 * checks to enforce.
1507 		 */
1508 		if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
1509 			uint64_t blocksize = zfs_prop_get_int(zhp,
1510 			    ZFS_PROP_VOLBLOCKSIZE);
1511 			char buf[64];
1512 
1513 			switch (prop) {
1514 			case ZFS_PROP_VOLSIZE:
1515 				if (intval % blocksize != 0) {
1516 					zfs_nicebytes(blocksize, buf,
1517 					    sizeof (buf));
1518 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1519 					    "'%s' must be a multiple of "
1520 					    "volume block size (%s)"),
1521 					    propname, buf);
1522 					(void) zfs_error(hdl, EZFS_BADPROP,
1523 					    errbuf);
1524 					goto error;
1525 				}
1526 
1527 				if (intval == 0) {
1528 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1529 					    "'%s' cannot be zero"),
1530 					    propname);
1531 					(void) zfs_error(hdl, EZFS_BADPROP,
1532 					    errbuf);
1533 					goto error;
1534 				}
1535 				break;
1536 
1537 			default:
1538 				break;
1539 			}
1540 		}
1541 
1542 		/* check encryption properties */
1543 		if (zhp != NULL) {
1544 			int64_t crypt = zfs_prop_get_int(zhp,
1545 			    ZFS_PROP_ENCRYPTION);
1546 
1547 			switch (prop) {
1548 			case ZFS_PROP_COPIES:
1549 				if (crypt != ZIO_CRYPT_OFF && intval > 2) {
1550 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1551 					    "encrypted datasets cannot have "
1552 					    "3 copies"));
1553 					(void) zfs_error(hdl, EZFS_BADPROP,
1554 					    errbuf);
1555 					goto error;
1556 				}
1557 				break;
1558 			default:
1559 				break;
1560 			}
1561 		}
1562 	}
1563 
1564 	/*
1565 	 * If normalization was chosen, but no UTF8 choice was made,
1566 	 * enforce rejection of non-UTF8 names.
1567 	 *
1568 	 * If normalization was chosen, but rejecting non-UTF8 names
1569 	 * was explicitly not chosen, it is an error.
1570 	 *
1571 	 * If utf8only was turned off, but the parent has normalization,
1572 	 * turn off normalization.
1573 	 */
1574 	if (chosen_normal > 0 && chosen_utf < 0) {
1575 		if (nvlist_add_uint64(ret,
1576 		    zfs_prop_to_name(ZFS_PROP_UTF8ONLY), 1) != 0) {
1577 			(void) no_memory(hdl);
1578 			goto error;
1579 		}
1580 	} else if (chosen_normal > 0 && chosen_utf == 0) {
1581 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1582 		    "'%s' must be set 'on' if normalization chosen"),
1583 		    zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
1584 		(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1585 		goto error;
1586 	} else if (chosen_normal < 0 && chosen_utf == 0) {
1587 		if (nvlist_add_uint64(ret,
1588 		    zfs_prop_to_name(ZFS_PROP_NORMALIZE), 0) != 0) {
1589 			(void) no_memory(hdl);
1590 			goto error;
1591 		}
1592 	}
1593 	return (ret);
1594 
1595 error:
1596 	nvlist_free(ret);
1597 	return (NULL);
1598 }
1599 
1600 static int
1601 zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl)
1602 {
1603 	uint64_t old_volsize;
1604 	uint64_t new_volsize;
1605 	uint64_t old_reservation;
1606 	uint64_t new_reservation;
1607 	zfs_prop_t resv_prop;
1608 	nvlist_t *props;
1609 	zpool_handle_t *zph = zpool_handle(zhp);
1610 
1611 	/*
1612 	 * If this is an existing volume, and someone is setting the volsize,
1613 	 * make sure that it matches the reservation, or add it if necessary.
1614 	 */
1615 	old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
1616 	if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
1617 		return (-1);
1618 	old_reservation = zfs_prop_get_int(zhp, resv_prop);
1619 
1620 	props = fnvlist_alloc();
1621 	fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
1622 	    zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
1623 
1624 	if ((zvol_volsize_to_reservation(zph, old_volsize, props) !=
1625 	    old_reservation) || nvlist_exists(nvl,
1626 	    zfs_prop_to_name(resv_prop))) {
1627 		fnvlist_free(props);
1628 		return (0);
1629 	}
1630 	if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
1631 	    &new_volsize) != 0) {
1632 		fnvlist_free(props);
1633 		return (-1);
1634 	}
1635 	new_reservation = zvol_volsize_to_reservation(zph, new_volsize, props);
1636 	fnvlist_free(props);
1637 
1638 	if (nvlist_add_uint64(nvl, zfs_prop_to_name(resv_prop),
1639 	    new_reservation) != 0) {
1640 		(void) no_memory(zhp->zfs_hdl);
1641 		return (-1);
1642 	}
1643 	return (1);
1644 }
1645 
1646 /*
1647  * Helper for 'zfs {set|clone} refreservation=auto'.  Must be called after
1648  * zfs_valid_proplist(), as it is what sets the UINT64_MAX sentinel value.
1649  * Return codes must match zfs_add_synthetic_resv().
1650  */
1651 static int
1652 zfs_fix_auto_resv(zfs_handle_t *zhp, nvlist_t *nvl)
1653 {
1654 	uint64_t volsize;
1655 	uint64_t resvsize;
1656 	zfs_prop_t prop;
1657 	nvlist_t *props;
1658 
1659 	if (!ZFS_IS_VOLUME(zhp)) {
1660 		return (0);
1661 	}
1662 
1663 	if (zfs_which_resv_prop(zhp, &prop) != 0) {
1664 		return (-1);
1665 	}
1666 
1667 	if (prop != ZFS_PROP_REFRESERVATION) {
1668 		return (0);
1669 	}
1670 
1671 	if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(prop), &resvsize) != 0) {
1672 		/* No value being set, so it can't be "auto" */
1673 		return (0);
1674 	}
1675 	if (resvsize != UINT64_MAX) {
1676 		/* Being set to a value other than "auto" */
1677 		return (0);
1678 	}
1679 
1680 	props = fnvlist_alloc();
1681 
1682 	fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
1683 	    zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
1684 
1685 	if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
1686 	    &volsize) != 0) {
1687 		volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
1688 	}
1689 
1690 	resvsize = zvol_volsize_to_reservation(zpool_handle(zhp), volsize,
1691 	    props);
1692 	fnvlist_free(props);
1693 
1694 	(void) nvlist_remove_all(nvl, zfs_prop_to_name(prop));
1695 	if (nvlist_add_uint64(nvl, zfs_prop_to_name(prop), resvsize) != 0) {
1696 		(void) no_memory(zhp->zfs_hdl);
1697 		return (-1);
1698 	}
1699 	return (1);
1700 }
1701 
1702 static boolean_t
1703 zfs_is_namespace_prop(zfs_prop_t prop)
1704 {
1705 	switch (prop) {
1706 
1707 	case ZFS_PROP_ATIME:
1708 	case ZFS_PROP_RELATIME:
1709 	case ZFS_PROP_DEVICES:
1710 	case ZFS_PROP_EXEC:
1711 	case ZFS_PROP_SETUID:
1712 	case ZFS_PROP_READONLY:
1713 	case ZFS_PROP_XATTR:
1714 	case ZFS_PROP_NBMAND:
1715 		return (B_TRUE);
1716 
1717 	default:
1718 		return (B_FALSE);
1719 	}
1720 }
1721 
1722 /*
1723  * Given a property name and value, set the property for the given dataset.
1724  */
1725 int
1726 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
1727 {
1728 	int ret = -1;
1729 	char errbuf[1024];
1730 	libzfs_handle_t *hdl = zhp->zfs_hdl;
1731 	nvlist_t *nvl = NULL;
1732 
1733 	(void) snprintf(errbuf, sizeof (errbuf),
1734 	    dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
1735 	    zhp->zfs_name);
1736 
1737 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
1738 	    nvlist_add_string(nvl, propname, propval) != 0) {
1739 		(void) no_memory(hdl);
1740 		goto error;
1741 	}
1742 
1743 	ret = zfs_prop_set_list(zhp, nvl);
1744 
1745 error:
1746 	nvlist_free(nvl);
1747 	return (ret);
1748 }
1749 
1750 
1751 
1752 /*
1753  * Given an nvlist of property names and values, set the properties for the
1754  * given dataset.
1755  */
1756 int
1757 zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
1758 {
1759 	zfs_cmd_t zc = {"\0"};
1760 	int ret = -1;
1761 	prop_changelist_t **cls = NULL;
1762 	int cl_idx;
1763 	char errbuf[1024];
1764 	libzfs_handle_t *hdl = zhp->zfs_hdl;
1765 	nvlist_t *nvl;
1766 	int nvl_len = 0;
1767 	int added_resv = 0;
1768 	zfs_prop_t prop = 0;
1769 	nvpair_t *elem;
1770 
1771 	(void) snprintf(errbuf, sizeof (errbuf),
1772 	    dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
1773 	    zhp->zfs_name);
1774 
1775 	if ((nvl = zfs_valid_proplist(hdl, zhp->zfs_type, props,
1776 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, zhp->zpool_hdl,
1777 	    B_FALSE, errbuf)) == NULL)
1778 		goto error;
1779 
1780 	/*
1781 	 * We have to check for any extra properties which need to be added
1782 	 * before computing the length of the nvlist.
1783 	 */
1784 	for (elem = nvlist_next_nvpair(nvl, NULL);
1785 	    elem != NULL;
1786 	    elem = nvlist_next_nvpair(nvl, elem)) {
1787 		if (zfs_name_to_prop(nvpair_name(elem)) == ZFS_PROP_VOLSIZE &&
1788 		    (added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1) {
1789 			goto error;
1790 		}
1791 	}
1792 
1793 	if (added_resv != 1 &&
1794 	    (added_resv = zfs_fix_auto_resv(zhp, nvl)) == -1) {
1795 		goto error;
1796 	}
1797 
1798 	/*
1799 	 * Check how many properties we're setting and allocate an array to
1800 	 * store changelist pointers for postfix().
1801 	 */
1802 	for (elem = nvlist_next_nvpair(nvl, NULL);
1803 	    elem != NULL;
1804 	    elem = nvlist_next_nvpair(nvl, elem))
1805 		nvl_len++;
1806 	if ((cls = calloc(nvl_len, sizeof (prop_changelist_t *))) == NULL)
1807 		goto error;
1808 
1809 	cl_idx = 0;
1810 	for (elem = nvlist_next_nvpair(nvl, NULL);
1811 	    elem != NULL;
1812 	    elem = nvlist_next_nvpair(nvl, elem)) {
1813 
1814 		prop = zfs_name_to_prop(nvpair_name(elem));
1815 
1816 		assert(cl_idx < nvl_len);
1817 		/*
1818 		 * We don't want to unmount & remount the dataset when changing
1819 		 * its canmount property to 'on' or 'noauto'.  We only use
1820 		 * the changelist logic to unmount when setting canmount=off.
1821 		 */
1822 		if (prop != ZFS_PROP_CANMOUNT ||
1823 		    (fnvpair_value_uint64(elem) == ZFS_CANMOUNT_OFF &&
1824 		    zfs_is_mounted(zhp, NULL))) {
1825 			cls[cl_idx] = changelist_gather(zhp, prop, 0, 0);
1826 			if (cls[cl_idx] == NULL)
1827 				goto error;
1828 		}
1829 
1830 		if (prop == ZFS_PROP_MOUNTPOINT &&
1831 		    changelist_haszonedchild(cls[cl_idx])) {
1832 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1833 			    "child dataset with inherited mountpoint is used "
1834 			    "in a non-global zone"));
1835 			ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1836 			goto error;
1837 		}
1838 
1839 		if (cls[cl_idx] != NULL &&
1840 		    (ret = changelist_prefix(cls[cl_idx])) != 0)
1841 			goto error;
1842 
1843 		cl_idx++;
1844 	}
1845 	assert(cl_idx == nvl_len);
1846 
1847 	/*
1848 	 * Execute the corresponding ioctl() to set this list of properties.
1849 	 */
1850 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1851 
1852 	if ((ret = zcmd_write_src_nvlist(hdl, &zc, nvl)) != 0 ||
1853 	    (ret = zcmd_alloc_dst_nvlist(hdl, &zc, 0)) != 0)
1854 		goto error;
1855 
1856 	ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1857 
1858 	if (ret != 0) {
1859 		if (zc.zc_nvlist_dst_filled == B_FALSE) {
1860 			(void) zfs_standard_error(hdl, errno, errbuf);
1861 			goto error;
1862 		}
1863 
1864 		/* Get the list of unset properties back and report them. */
1865 		nvlist_t *errorprops = NULL;
1866 		if (zcmd_read_dst_nvlist(hdl, &zc, &errorprops) != 0)
1867 			goto error;
1868 		for (nvpair_t *elem = nvlist_next_nvpair(errorprops, NULL);
1869 		    elem != NULL;
1870 		    elem = nvlist_next_nvpair(errorprops, elem)) {
1871 			prop = zfs_name_to_prop(nvpair_name(elem));
1872 			zfs_setprop_error(hdl, prop, errno, errbuf);
1873 		}
1874 		nvlist_free(errorprops);
1875 
1876 		if (added_resv && errno == ENOSPC) {
1877 			/* clean up the volsize property we tried to set */
1878 			uint64_t old_volsize = zfs_prop_get_int(zhp,
1879 			    ZFS_PROP_VOLSIZE);
1880 			nvlist_free(nvl);
1881 			nvl = NULL;
1882 			zcmd_free_nvlists(&zc);
1883 
1884 			if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
1885 				goto error;
1886 			if (nvlist_add_uint64(nvl,
1887 			    zfs_prop_to_name(ZFS_PROP_VOLSIZE),
1888 			    old_volsize) != 0)
1889 				goto error;
1890 			if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
1891 				goto error;
1892 			(void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1893 		}
1894 	} else {
1895 		for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
1896 			if (cls[cl_idx] != NULL) {
1897 				int clp_err = changelist_postfix(cls[cl_idx]);
1898 				if (clp_err != 0)
1899 					ret = clp_err;
1900 			}
1901 		}
1902 
1903 		if (ret == 0) {
1904 			/*
1905 			 * Refresh the statistics so the new property
1906 			 * value is reflected.
1907 			 */
1908 			(void) get_stats(zhp);
1909 
1910 			/*
1911 			 * Remount the filesystem to propagate the change
1912 			 * if one of the options handled by the generic
1913 			 * Linux namespace layer has been modified.
1914 			 */
1915 			if (zfs_is_namespace_prop(prop) &&
1916 			    zfs_is_mounted(zhp, NULL))
1917 				ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0);
1918 		}
1919 	}
1920 
1921 error:
1922 	nvlist_free(nvl);
1923 	zcmd_free_nvlists(&zc);
1924 	if (cls != NULL) {
1925 		for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
1926 			if (cls[cl_idx] != NULL)
1927 				changelist_free(cls[cl_idx]);
1928 		}
1929 		free(cls);
1930 	}
1931 	return (ret);
1932 }
1933 
1934 /*
1935  * Given a property, inherit the value from the parent dataset, or if received
1936  * is TRUE, revert to the received value, if any.
1937  */
1938 int
1939 zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
1940 {
1941 	zfs_cmd_t zc = {"\0"};
1942 	int ret;
1943 	prop_changelist_t *cl;
1944 	libzfs_handle_t *hdl = zhp->zfs_hdl;
1945 	char errbuf[1024];
1946 	zfs_prop_t prop;
1947 
1948 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1949 	    "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
1950 
1951 	zc.zc_cookie = received;
1952 	if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
1953 		/*
1954 		 * For user properties, the amount of work we have to do is very
1955 		 * small, so just do it here.
1956 		 */
1957 		if (!zfs_prop_user(propname)) {
1958 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1959 			    "invalid property"));
1960 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1961 		}
1962 
1963 		(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1964 		(void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1965 
1966 		if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0)
1967 			return (zfs_standard_error(hdl, errno, errbuf));
1968 
1969 		(void) get_stats(zhp);
1970 		return (0);
1971 	}
1972 
1973 	/*
1974 	 * Verify that this property is inheritable.
1975 	 */
1976 	if (zfs_prop_readonly(prop))
1977 		return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
1978 
1979 	if (!zfs_prop_inheritable(prop) && !received)
1980 		return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
1981 
1982 	/*
1983 	 * Check to see if the value applies to this type
1984 	 */
1985 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE))
1986 		return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
1987 
1988 	/*
1989 	 * Normalize the name, to get rid of shorthand abbreviations.
1990 	 */
1991 	propname = zfs_prop_to_name(prop);
1992 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1993 	(void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1994 
1995 	if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
1996 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
1997 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1998 		    "dataset is used in a non-global zone"));
1999 		return (zfs_error(hdl, EZFS_ZONED, errbuf));
2000 	}
2001 
2002 	/*
2003 	 * Determine datasets which will be affected by this change, if any.
2004 	 */
2005 	if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
2006 		return (-1);
2007 
2008 	if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
2009 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2010 		    "child dataset with inherited mountpoint is used "
2011 		    "in a non-global zone"));
2012 		ret = zfs_error(hdl, EZFS_ZONED, errbuf);
2013 		goto error;
2014 	}
2015 
2016 	if ((ret = changelist_prefix(cl)) != 0)
2017 		goto error;
2018 
2019 	if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) {
2020 		return (zfs_standard_error(hdl, errno, errbuf));
2021 	} else {
2022 
2023 		if ((ret = changelist_postfix(cl)) != 0)
2024 			goto error;
2025 
2026 		/*
2027 		 * Refresh the statistics so the new property is reflected.
2028 		 */
2029 		(void) get_stats(zhp);
2030 
2031 		/*
2032 		 * Remount the filesystem to propagate the change
2033 		 * if one of the options handled by the generic
2034 		 * Linux namespace layer has been modified.
2035 		 */
2036 		if (zfs_is_namespace_prop(prop) &&
2037 		    zfs_is_mounted(zhp, NULL))
2038 			ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0);
2039 	}
2040 
2041 error:
2042 	changelist_free(cl);
2043 	return (ret);
2044 }
2045 
2046 /*
2047  * True DSL properties are stored in an nvlist.  The following two functions
2048  * extract them appropriately.
2049  */
2050 uint64_t
2051 getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
2052 {
2053 	nvlist_t *nv;
2054 	uint64_t value;
2055 
2056 	*source = NULL;
2057 	if (nvlist_lookup_nvlist(zhp->zfs_props,
2058 	    zfs_prop_to_name(prop), &nv) == 0) {
2059 		verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
2060 		(void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
2061 	} else {
2062 		verify(!zhp->zfs_props_table ||
2063 		    zhp->zfs_props_table[prop] == B_TRUE);
2064 		value = zfs_prop_default_numeric(prop);
2065 		*source = "";
2066 	}
2067 
2068 	return (value);
2069 }
2070 
2071 static const char *
2072 getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
2073 {
2074 	nvlist_t *nv;
2075 	const char *value;
2076 
2077 	*source = NULL;
2078 	if (nvlist_lookup_nvlist(zhp->zfs_props,
2079 	    zfs_prop_to_name(prop), &nv) == 0) {
2080 		value = fnvlist_lookup_string(nv, ZPROP_VALUE);
2081 		(void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
2082 	} else {
2083 		verify(!zhp->zfs_props_table ||
2084 		    zhp->zfs_props_table[prop] == B_TRUE);
2085 		value = zfs_prop_default_string(prop);
2086 		*source = "";
2087 	}
2088 
2089 	return (value);
2090 }
2091 
2092 static boolean_t
2093 zfs_is_recvd_props_mode(zfs_handle_t *zhp)
2094 {
2095 	return (zhp->zfs_props == zhp->zfs_recvd_props);
2096 }
2097 
2098 static void
2099 zfs_set_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
2100 {
2101 	*cookie = (uint64_t)(uintptr_t)zhp->zfs_props;
2102 	zhp->zfs_props = zhp->zfs_recvd_props;
2103 }
2104 
2105 static void
2106 zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
2107 {
2108 	zhp->zfs_props = (nvlist_t *)(uintptr_t)*cookie;
2109 	*cookie = 0;
2110 }
2111 
2112 /*
2113  * Internal function for getting a numeric property.  Both zfs_prop_get() and
2114  * zfs_prop_get_int() are built using this interface.
2115  *
2116  * Certain properties can be overridden using 'mount -o'.  In this case, scan
2117  * the contents of the /proc/self/mounts entry, searching for the
2118  * appropriate options. If they differ from the on-disk values, report the
2119  * current values and mark the source "temporary".
2120  */
2121 static int
2122 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
2123     char **source, uint64_t *val)
2124 {
2125 	zfs_cmd_t zc = {"\0"};
2126 	nvlist_t *zplprops = NULL;
2127 	struct mnttab mnt;
2128 	char *mntopt_on = NULL;
2129 	char *mntopt_off = NULL;
2130 	boolean_t received = zfs_is_recvd_props_mode(zhp);
2131 
2132 	*source = NULL;
2133 
2134 	/*
2135 	 * If the property is being fetched for a snapshot, check whether
2136 	 * the property is valid for the snapshot's head dataset type.
2137 	 */
2138 	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT &&
2139 	    !zfs_prop_valid_for_type(prop, zhp->zfs_head_type, B_TRUE)) {
2140 		*val = zfs_prop_default_numeric(prop);
2141 		return (-1);
2142 	}
2143 
2144 	switch (prop) {
2145 	case ZFS_PROP_ATIME:
2146 		mntopt_on = MNTOPT_ATIME;
2147 		mntopt_off = MNTOPT_NOATIME;
2148 		break;
2149 
2150 	case ZFS_PROP_RELATIME:
2151 		mntopt_on = MNTOPT_RELATIME;
2152 		mntopt_off = MNTOPT_NORELATIME;
2153 		break;
2154 
2155 	case ZFS_PROP_DEVICES:
2156 		mntopt_on = MNTOPT_DEVICES;
2157 		mntopt_off = MNTOPT_NODEVICES;
2158 		break;
2159 
2160 	case ZFS_PROP_EXEC:
2161 		mntopt_on = MNTOPT_EXEC;
2162 		mntopt_off = MNTOPT_NOEXEC;
2163 		break;
2164 
2165 	case ZFS_PROP_READONLY:
2166 		mntopt_on = MNTOPT_RO;
2167 		mntopt_off = MNTOPT_RW;
2168 		break;
2169 
2170 	case ZFS_PROP_SETUID:
2171 		mntopt_on = MNTOPT_SETUID;
2172 		mntopt_off = MNTOPT_NOSETUID;
2173 		break;
2174 
2175 	case ZFS_PROP_XATTR:
2176 		mntopt_on = MNTOPT_XATTR;
2177 		mntopt_off = MNTOPT_NOXATTR;
2178 		break;
2179 
2180 	case ZFS_PROP_NBMAND:
2181 		mntopt_on = MNTOPT_NBMAND;
2182 		mntopt_off = MNTOPT_NONBMAND;
2183 		break;
2184 
2185 	default:
2186 		break;
2187 	}
2188 
2189 	/*
2190 	 * Because looking up the mount options is potentially expensive
2191 	 * (iterating over all of /proc/self/mounts), we defer its
2192 	 * calculation until we're looking up a property which requires
2193 	 * its presence.
2194 	 */
2195 	if (!zhp->zfs_mntcheck &&
2196 	    (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
2197 		libzfs_handle_t *hdl = zhp->zfs_hdl;
2198 		struct mnttab entry;
2199 
2200 		if (libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0) {
2201 			zhp->zfs_mntopts = zfs_strdup(hdl,
2202 			    entry.mnt_mntopts);
2203 			if (zhp->zfs_mntopts == NULL)
2204 				return (-1);
2205 		}
2206 
2207 		zhp->zfs_mntcheck = B_TRUE;
2208 	}
2209 
2210 	if (zhp->zfs_mntopts == NULL)
2211 		mnt.mnt_mntopts = "";
2212 	else
2213 		mnt.mnt_mntopts = zhp->zfs_mntopts;
2214 
2215 	switch (prop) {
2216 	case ZFS_PROP_ATIME:
2217 	case ZFS_PROP_RELATIME:
2218 	case ZFS_PROP_DEVICES:
2219 	case ZFS_PROP_EXEC:
2220 	case ZFS_PROP_READONLY:
2221 	case ZFS_PROP_SETUID:
2222 #ifndef __FreeBSD__
2223 	case ZFS_PROP_XATTR:
2224 #endif
2225 	case ZFS_PROP_NBMAND:
2226 		*val = getprop_uint64(zhp, prop, source);
2227 
2228 		if (received)
2229 			break;
2230 
2231 		if (hasmntopt(&mnt, mntopt_on) && !*val) {
2232 			*val = B_TRUE;
2233 			if (src)
2234 				*src = ZPROP_SRC_TEMPORARY;
2235 		} else if (hasmntopt(&mnt, mntopt_off) && *val) {
2236 			*val = B_FALSE;
2237 			if (src)
2238 				*src = ZPROP_SRC_TEMPORARY;
2239 		}
2240 		break;
2241 
2242 	case ZFS_PROP_CANMOUNT:
2243 	case ZFS_PROP_VOLSIZE:
2244 	case ZFS_PROP_QUOTA:
2245 	case ZFS_PROP_REFQUOTA:
2246 	case ZFS_PROP_RESERVATION:
2247 	case ZFS_PROP_REFRESERVATION:
2248 	case ZFS_PROP_FILESYSTEM_LIMIT:
2249 	case ZFS_PROP_SNAPSHOT_LIMIT:
2250 	case ZFS_PROP_FILESYSTEM_COUNT:
2251 	case ZFS_PROP_SNAPSHOT_COUNT:
2252 		*val = getprop_uint64(zhp, prop, source);
2253 
2254 		if (*source == NULL) {
2255 			/* not default, must be local */
2256 			*source = zhp->zfs_name;
2257 		}
2258 		break;
2259 
2260 	case ZFS_PROP_MOUNTED:
2261 		*val = (zhp->zfs_mntopts != NULL);
2262 		break;
2263 
2264 	case ZFS_PROP_NUMCLONES:
2265 		*val = zhp->zfs_dmustats.dds_num_clones;
2266 		break;
2267 
2268 	case ZFS_PROP_VERSION:
2269 	case ZFS_PROP_NORMALIZE:
2270 	case ZFS_PROP_UTF8ONLY:
2271 	case ZFS_PROP_CASE:
2272 		if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
2273 			return (-1);
2274 		(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2275 		if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) {
2276 			zcmd_free_nvlists(&zc);
2277 			if (prop == ZFS_PROP_VERSION &&
2278 			    zhp->zfs_type == ZFS_TYPE_VOLUME)
2279 				*val = zfs_prop_default_numeric(prop);
2280 			return (-1);
2281 		}
2282 		if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 ||
2283 		    nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop),
2284 		    val) != 0) {
2285 			zcmd_free_nvlists(&zc);
2286 			return (-1);
2287 		}
2288 		nvlist_free(zplprops);
2289 		zcmd_free_nvlists(&zc);
2290 		break;
2291 
2292 	case ZFS_PROP_INCONSISTENT:
2293 		*val = zhp->zfs_dmustats.dds_inconsistent;
2294 		break;
2295 
2296 	case ZFS_PROP_REDACTED:
2297 		*val = zhp->zfs_dmustats.dds_redacted;
2298 		break;
2299 
2300 	default:
2301 		switch (zfs_prop_get_type(prop)) {
2302 		case PROP_TYPE_NUMBER:
2303 		case PROP_TYPE_INDEX:
2304 			*val = getprop_uint64(zhp, prop, source);
2305 			/*
2306 			 * If we tried to use a default value for a
2307 			 * readonly property, it means that it was not
2308 			 * present.  Note this only applies to "truly"
2309 			 * readonly properties, not set-once properties
2310 			 * like volblocksize.
2311 			 */
2312 			if (zfs_prop_readonly(prop) &&
2313 			    !zfs_prop_setonce(prop) &&
2314 			    *source != NULL && (*source)[0] == '\0') {
2315 				*source = NULL;
2316 				return (-1);
2317 			}
2318 			break;
2319 
2320 		case PROP_TYPE_STRING:
2321 		default:
2322 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2323 			    "cannot get non-numeric property"));
2324 			return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
2325 			    dgettext(TEXT_DOMAIN, "internal error")));
2326 		}
2327 	}
2328 
2329 	return (0);
2330 }
2331 
2332 /*
2333  * Calculate the source type, given the raw source string.
2334  */
2335 static void
2336 get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source,
2337     char *statbuf, size_t statlen)
2338 {
2339 	if (statbuf == NULL ||
2340 	    srctype == NULL || *srctype == ZPROP_SRC_TEMPORARY) {
2341 		return;
2342 	}
2343 
2344 	if (source == NULL) {
2345 		*srctype = ZPROP_SRC_NONE;
2346 	} else if (source[0] == '\0') {
2347 		*srctype = ZPROP_SRC_DEFAULT;
2348 	} else if (strstr(source, ZPROP_SOURCE_VAL_RECVD) != NULL) {
2349 		*srctype = ZPROP_SRC_RECEIVED;
2350 	} else {
2351 		if (strcmp(source, zhp->zfs_name) == 0) {
2352 			*srctype = ZPROP_SRC_LOCAL;
2353 		} else {
2354 			(void) strlcpy(statbuf, source, statlen);
2355 			*srctype = ZPROP_SRC_INHERITED;
2356 		}
2357 	}
2358 
2359 }
2360 
2361 int
2362 zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
2363     size_t proplen, boolean_t literal)
2364 {
2365 	zfs_prop_t prop;
2366 	int err = 0;
2367 
2368 	if (zhp->zfs_recvd_props == NULL)
2369 		if (get_recvd_props_ioctl(zhp) != 0)
2370 			return (-1);
2371 
2372 	prop = zfs_name_to_prop(propname);
2373 
2374 	if (prop != ZPROP_INVAL) {
2375 		uint64_t cookie;
2376 		if (!nvlist_exists(zhp->zfs_recvd_props, propname))
2377 			return (-1);
2378 		zfs_set_recvd_props_mode(zhp, &cookie);
2379 		err = zfs_prop_get(zhp, prop, propbuf, proplen,
2380 		    NULL, NULL, 0, literal);
2381 		zfs_unset_recvd_props_mode(zhp, &cookie);
2382 	} else {
2383 		nvlist_t *propval;
2384 		char *recvdval;
2385 		if (nvlist_lookup_nvlist(zhp->zfs_recvd_props,
2386 		    propname, &propval) != 0)
2387 			return (-1);
2388 		verify(nvlist_lookup_string(propval, ZPROP_VALUE,
2389 		    &recvdval) == 0);
2390 		(void) strlcpy(propbuf, recvdval, proplen);
2391 	}
2392 
2393 	return (err == 0 ? 0 : -1);
2394 }
2395 
2396 static int
2397 get_clones_string(zfs_handle_t *zhp, char *propbuf, size_t proplen)
2398 {
2399 	nvlist_t *value;
2400 	nvpair_t *pair;
2401 
2402 	value = zfs_get_clones_nvl(zhp);
2403 	if (value == NULL || nvlist_empty(value))
2404 		return (-1);
2405 
2406 	propbuf[0] = '\0';
2407 	for (pair = nvlist_next_nvpair(value, NULL); pair != NULL;
2408 	    pair = nvlist_next_nvpair(value, pair)) {
2409 		if (propbuf[0] != '\0')
2410 			(void) strlcat(propbuf, ",", proplen);
2411 		(void) strlcat(propbuf, nvpair_name(pair), proplen);
2412 	}
2413 
2414 	return (0);
2415 }
2416 
2417 struct get_clones_arg {
2418 	uint64_t numclones;
2419 	nvlist_t *value;
2420 	const char *origin;
2421 	char buf[ZFS_MAX_DATASET_NAME_LEN];
2422 };
2423 
2424 static int
2425 get_clones_cb(zfs_handle_t *zhp, void *arg)
2426 {
2427 	struct get_clones_arg *gca = arg;
2428 
2429 	if (gca->numclones == 0) {
2430 		zfs_close(zhp);
2431 		return (0);
2432 	}
2433 
2434 	if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, gca->buf, sizeof (gca->buf),
2435 	    NULL, NULL, 0, B_TRUE) != 0)
2436 		goto out;
2437 	if (strcmp(gca->buf, gca->origin) == 0) {
2438 		fnvlist_add_boolean(gca->value, zfs_get_name(zhp));
2439 		gca->numclones--;
2440 	}
2441 
2442 out:
2443 	(void) zfs_iter_children(zhp, get_clones_cb, gca);
2444 	zfs_close(zhp);
2445 	return (0);
2446 }
2447 
2448 nvlist_t *
2449 zfs_get_clones_nvl(zfs_handle_t *zhp)
2450 {
2451 	nvlist_t *nv, *value;
2452 
2453 	if (nvlist_lookup_nvlist(zhp->zfs_props,
2454 	    zfs_prop_to_name(ZFS_PROP_CLONES), &nv) != 0) {
2455 		struct get_clones_arg gca;
2456 
2457 		/*
2458 		 * if this is a snapshot, then the kernel wasn't able
2459 		 * to get the clones.  Do it by slowly iterating.
2460 		 */
2461 		if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT)
2462 			return (NULL);
2463 		if (nvlist_alloc(&nv, NV_UNIQUE_NAME, 0) != 0)
2464 			return (NULL);
2465 		if (nvlist_alloc(&value, NV_UNIQUE_NAME, 0) != 0) {
2466 			nvlist_free(nv);
2467 			return (NULL);
2468 		}
2469 
2470 		gca.numclones = zfs_prop_get_int(zhp, ZFS_PROP_NUMCLONES);
2471 		gca.value = value;
2472 		gca.origin = zhp->zfs_name;
2473 
2474 		if (gca.numclones != 0) {
2475 			zfs_handle_t *root;
2476 			char pool[ZFS_MAX_DATASET_NAME_LEN];
2477 			char *cp = pool;
2478 
2479 			/* get the pool name */
2480 			(void) strlcpy(pool, zhp->zfs_name, sizeof (pool));
2481 			(void) strsep(&cp, "/@");
2482 			root = zfs_open(zhp->zfs_hdl, pool,
2483 			    ZFS_TYPE_FILESYSTEM);
2484 			if (root == NULL) {
2485 				nvlist_free(nv);
2486 				nvlist_free(value);
2487 				return (NULL);
2488 			}
2489 
2490 			(void) get_clones_cb(root, &gca);
2491 		}
2492 
2493 		if (gca.numclones != 0 ||
2494 		    nvlist_add_nvlist(nv, ZPROP_VALUE, value) != 0 ||
2495 		    nvlist_add_nvlist(zhp->zfs_props,
2496 		    zfs_prop_to_name(ZFS_PROP_CLONES), nv) != 0) {
2497 			nvlist_free(nv);
2498 			nvlist_free(value);
2499 			return (NULL);
2500 		}
2501 		nvlist_free(nv);
2502 		nvlist_free(value);
2503 		verify(0 == nvlist_lookup_nvlist(zhp->zfs_props,
2504 		    zfs_prop_to_name(ZFS_PROP_CLONES), &nv));
2505 	}
2506 
2507 	verify(nvlist_lookup_nvlist(nv, ZPROP_VALUE, &value) == 0);
2508 
2509 	return (value);
2510 }
2511 
2512 static int
2513 get_rsnaps_string(zfs_handle_t *zhp, char *propbuf, size_t proplen)
2514 {
2515 	nvlist_t *value;
2516 	uint64_t *snaps;
2517 	uint_t nsnaps;
2518 
2519 	if (nvlist_lookup_nvlist(zhp->zfs_props,
2520 	    zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS), &value) != 0)
2521 		return (-1);
2522 	if (nvlist_lookup_uint64_array(value, ZPROP_VALUE, &snaps,
2523 	    &nsnaps) != 0)
2524 		return (-1);
2525 	if (nsnaps == 0) {
2526 		/* There's no redaction snapshots; pass a special value back */
2527 		(void) snprintf(propbuf, proplen, "none");
2528 		return (0);
2529 	}
2530 	propbuf[0] = '\0';
2531 	for (int i = 0; i < nsnaps; i++) {
2532 		char buf[128];
2533 		if (propbuf[0] != '\0')
2534 			(void) strlcat(propbuf, ",", proplen);
2535 		(void) snprintf(buf, sizeof (buf), "%llu",
2536 		    (u_longlong_t)snaps[i]);
2537 		(void) strlcat(propbuf, buf, proplen);
2538 	}
2539 
2540 	return (0);
2541 }
2542 
2543 /*
2544  * Accepts a property and value and checks that the value
2545  * matches the one found by the channel program. If they are
2546  * not equal, print both of them.
2547  */
2548 static void
2549 zcp_check(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t intval,
2550     const char *strval)
2551 {
2552 	if (!zhp->zfs_hdl->libzfs_prop_debug)
2553 		return;
2554 	int error;
2555 	char *poolname = zhp->zpool_hdl->zpool_name;
2556 	const char *prop_name = zfs_prop_to_name(prop);
2557 	const char *program =
2558 	    "args = ...\n"
2559 	    "ds = args['dataset']\n"
2560 	    "prop = args['property']\n"
2561 	    "value, setpoint = zfs.get_prop(ds, prop)\n"
2562 	    "return {value=value, setpoint=setpoint}\n";
2563 	nvlist_t *outnvl;
2564 	nvlist_t *retnvl;
2565 	nvlist_t *argnvl = fnvlist_alloc();
2566 
2567 	fnvlist_add_string(argnvl, "dataset", zhp->zfs_name);
2568 	fnvlist_add_string(argnvl, "property", zfs_prop_to_name(prop));
2569 
2570 	error = lzc_channel_program_nosync(poolname, program,
2571 	    10 * 1000 * 1000, 10 * 1024 * 1024, argnvl, &outnvl);
2572 
2573 	if (error == 0) {
2574 		retnvl = fnvlist_lookup_nvlist(outnvl, "return");
2575 		if (zfs_prop_get_type(prop) == PROP_TYPE_NUMBER) {
2576 			int64_t ans;
2577 			error = nvlist_lookup_int64(retnvl, "value", &ans);
2578 			if (error != 0) {
2579 				(void) fprintf(stderr, "%s: zcp check error: "
2580 				    "%u\n", prop_name, error);
2581 				return;
2582 			}
2583 			if (ans != intval) {
2584 				(void) fprintf(stderr, "%s: zfs found %llu, "
2585 				    "but zcp found %llu\n", prop_name,
2586 				    (u_longlong_t)intval, (u_longlong_t)ans);
2587 			}
2588 		} else {
2589 			char *str_ans;
2590 			error = nvlist_lookup_string(retnvl, "value", &str_ans);
2591 			if (error != 0) {
2592 				(void) fprintf(stderr, "%s: zcp check error: "
2593 				    "%u\n", prop_name, error);
2594 				return;
2595 			}
2596 			if (strcmp(strval, str_ans) != 0) {
2597 				(void) fprintf(stderr,
2598 				    "%s: zfs found '%s', but zcp found '%s'\n",
2599 				    prop_name, strval, str_ans);
2600 			}
2601 		}
2602 	} else {
2603 		(void) fprintf(stderr, "%s: zcp check failed, channel program "
2604 		    "error: %u\n", prop_name, error);
2605 	}
2606 	nvlist_free(argnvl);
2607 	nvlist_free(outnvl);
2608 }
2609 
2610 /*
2611  * Retrieve a property from the given object.  If 'literal' is specified, then
2612  * numbers are left as exact values.  Otherwise, numbers are converted to a
2613  * human-readable form.
2614  *
2615  * Returns 0 on success, or -1 on error.
2616  */
2617 int
2618 zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
2619     zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
2620 {
2621 	char *source = NULL;
2622 	uint64_t val;
2623 	const char *str;
2624 	const char *strval;
2625 	boolean_t received = zfs_is_recvd_props_mode(zhp);
2626 
2627 	/*
2628 	 * Check to see if this property applies to our object
2629 	 */
2630 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE))
2631 		return (-1);
2632 
2633 	if (received && zfs_prop_readonly(prop))
2634 		return (-1);
2635 
2636 	if (src)
2637 		*src = ZPROP_SRC_NONE;
2638 
2639 	switch (prop) {
2640 	case ZFS_PROP_CREATION:
2641 		/*
2642 		 * 'creation' is a time_t stored in the statistics.  We convert
2643 		 * this into a string unless 'literal' is specified.
2644 		 */
2645 		{
2646 			val = getprop_uint64(zhp, prop, &source);
2647 			time_t time = (time_t)val;
2648 			struct tm t;
2649 
2650 			if (literal ||
2651 			    localtime_r(&time, &t) == NULL ||
2652 			    strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
2653 			    &t) == 0)
2654 				(void) snprintf(propbuf, proplen, "%llu",
2655 				    (u_longlong_t)val);
2656 		}
2657 		zcp_check(zhp, prop, val, NULL);
2658 		break;
2659 
2660 	case ZFS_PROP_MOUNTPOINT:
2661 		/*
2662 		 * Getting the precise mountpoint can be tricky.
2663 		 *
2664 		 *  - for 'none' or 'legacy', return those values.
2665 		 *  - for inherited mountpoints, we want to take everything
2666 		 *    after our ancestor and append it to the inherited value.
2667 		 *
2668 		 * If the pool has an alternate root, we want to prepend that
2669 		 * root to any values we return.
2670 		 */
2671 
2672 		str = getprop_string(zhp, prop, &source);
2673 
2674 		if (str[0] == '/') {
2675 			char buf[MAXPATHLEN];
2676 			char *root = buf;
2677 			const char *relpath;
2678 
2679 			/*
2680 			 * If we inherit the mountpoint, even from a dataset
2681 			 * with a received value, the source will be the path of
2682 			 * the dataset we inherit from. If source is
2683 			 * ZPROP_SOURCE_VAL_RECVD, the received value is not
2684 			 * inherited.
2685 			 */
2686 			if (strcmp(source, ZPROP_SOURCE_VAL_RECVD) == 0) {
2687 				relpath = "";
2688 			} else {
2689 				relpath = zhp->zfs_name + strlen(source);
2690 				if (relpath[0] == '/')
2691 					relpath++;
2692 			}
2693 
2694 			if ((zpool_get_prop(zhp->zpool_hdl,
2695 			    ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL,
2696 			    B_FALSE)) || (strcmp(root, "-") == 0))
2697 				root[0] = '\0';
2698 			/*
2699 			 * Special case an alternate root of '/'. This will
2700 			 * avoid having multiple leading slashes in the
2701 			 * mountpoint path.
2702 			 */
2703 			if (strcmp(root, "/") == 0)
2704 				root++;
2705 
2706 			/*
2707 			 * If the mountpoint is '/' then skip over this
2708 			 * if we are obtaining either an alternate root or
2709 			 * an inherited mountpoint.
2710 			 */
2711 			if (str[1] == '\0' && (root[0] != '\0' ||
2712 			    relpath[0] != '\0'))
2713 				str++;
2714 
2715 			if (relpath[0] == '\0')
2716 				(void) snprintf(propbuf, proplen, "%s%s",
2717 				    root, str);
2718 			else
2719 				(void) snprintf(propbuf, proplen, "%s%s%s%s",
2720 				    root, str, relpath[0] == '@' ? "" : "/",
2721 				    relpath);
2722 		} else {
2723 			/* 'legacy' or 'none' */
2724 			(void) strlcpy(propbuf, str, proplen);
2725 		}
2726 		zcp_check(zhp, prop, 0, propbuf);
2727 		break;
2728 
2729 	case ZFS_PROP_ORIGIN:
2730 		str = getprop_string(zhp, prop, &source);
2731 		if (str == NULL)
2732 			return (-1);
2733 		(void) strlcpy(propbuf, str, proplen);
2734 		zcp_check(zhp, prop, 0, str);
2735 		break;
2736 
2737 	case ZFS_PROP_REDACT_SNAPS:
2738 		if (get_rsnaps_string(zhp, propbuf, proplen) != 0)
2739 			return (-1);
2740 		break;
2741 
2742 	case ZFS_PROP_CLONES:
2743 		if (get_clones_string(zhp, propbuf, proplen) != 0)
2744 			return (-1);
2745 		break;
2746 
2747 	case ZFS_PROP_QUOTA:
2748 	case ZFS_PROP_REFQUOTA:
2749 	case ZFS_PROP_RESERVATION:
2750 	case ZFS_PROP_REFRESERVATION:
2751 
2752 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2753 			return (-1);
2754 		/*
2755 		 * If quota or reservation is 0, we translate this into 'none'
2756 		 * (unless literal is set), and indicate that it's the default
2757 		 * value.  Otherwise, we print the number nicely and indicate
2758 		 * that its set locally.
2759 		 */
2760 		if (val == 0) {
2761 			if (literal)
2762 				(void) strlcpy(propbuf, "0", proplen);
2763 			else
2764 				(void) strlcpy(propbuf, "none", proplen);
2765 		} else {
2766 			if (literal)
2767 				(void) snprintf(propbuf, proplen, "%llu",
2768 				    (u_longlong_t)val);
2769 			else
2770 				zfs_nicebytes(val, propbuf, proplen);
2771 		}
2772 		zcp_check(zhp, prop, val, NULL);
2773 		break;
2774 
2775 	case ZFS_PROP_FILESYSTEM_LIMIT:
2776 	case ZFS_PROP_SNAPSHOT_LIMIT:
2777 	case ZFS_PROP_FILESYSTEM_COUNT:
2778 	case ZFS_PROP_SNAPSHOT_COUNT:
2779 
2780 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2781 			return (-1);
2782 
2783 		/*
2784 		 * If limit is UINT64_MAX, we translate this into 'none', and
2785 		 * indicate that it's the default value. Otherwise, we print
2786 		 * the number nicely and indicate that it's set locally.
2787 		 */
2788 		if (val == UINT64_MAX) {
2789 			(void) strlcpy(propbuf, "none", proplen);
2790 		} else if (literal) {
2791 			(void) snprintf(propbuf, proplen, "%llu",
2792 			    (u_longlong_t)val);
2793 		} else {
2794 			zfs_nicenum(val, propbuf, proplen);
2795 		}
2796 
2797 		zcp_check(zhp, prop, val, NULL);
2798 		break;
2799 
2800 	case ZFS_PROP_REFRATIO:
2801 	case ZFS_PROP_COMPRESSRATIO:
2802 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2803 			return (-1);
2804 		if (literal)
2805 			(void) snprintf(propbuf, proplen, "%llu.%02llu",
2806 			    (u_longlong_t)(val / 100),
2807 			    (u_longlong_t)(val % 100));
2808 		else
2809 			(void) snprintf(propbuf, proplen, "%llu.%02llux",
2810 			    (u_longlong_t)(val / 100),
2811 			    (u_longlong_t)(val % 100));
2812 		zcp_check(zhp, prop, val, NULL);
2813 		break;
2814 
2815 	case ZFS_PROP_TYPE:
2816 		switch (zhp->zfs_type) {
2817 		case ZFS_TYPE_FILESYSTEM:
2818 			str = "filesystem";
2819 			break;
2820 		case ZFS_TYPE_VOLUME:
2821 			str = "volume";
2822 			break;
2823 		case ZFS_TYPE_SNAPSHOT:
2824 			str = "snapshot";
2825 			break;
2826 		case ZFS_TYPE_BOOKMARK:
2827 			str = "bookmark";
2828 			break;
2829 		default:
2830 			abort();
2831 		}
2832 		(void) snprintf(propbuf, proplen, "%s", str);
2833 		zcp_check(zhp, prop, 0, propbuf);
2834 		break;
2835 
2836 	case ZFS_PROP_MOUNTED:
2837 		/*
2838 		 * The 'mounted' property is a pseudo-property that described
2839 		 * whether the filesystem is currently mounted.  Even though
2840 		 * it's a boolean value, the typical values of "on" and "off"
2841 		 * don't make sense, so we translate to "yes" and "no".
2842 		 */
2843 		if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
2844 		    src, &source, &val) != 0)
2845 			return (-1);
2846 		if (val)
2847 			(void) strlcpy(propbuf, "yes", proplen);
2848 		else
2849 			(void) strlcpy(propbuf, "no", proplen);
2850 		break;
2851 
2852 	case ZFS_PROP_NAME:
2853 		/*
2854 		 * The 'name' property is a pseudo-property derived from the
2855 		 * dataset name.  It is presented as a real property to simplify
2856 		 * consumers.
2857 		 */
2858 		(void) strlcpy(propbuf, zhp->zfs_name, proplen);
2859 		zcp_check(zhp, prop, 0, propbuf);
2860 		break;
2861 
2862 	case ZFS_PROP_MLSLABEL:
2863 		{
2864 #ifdef HAVE_MLSLABEL
2865 			m_label_t *new_sl = NULL;
2866 			char *ascii = NULL;	/* human readable label */
2867 
2868 			(void) strlcpy(propbuf,
2869 			    getprop_string(zhp, prop, &source), proplen);
2870 
2871 			if (literal || (strcasecmp(propbuf,
2872 			    ZFS_MLSLABEL_DEFAULT) == 0))
2873 				break;
2874 
2875 			/*
2876 			 * Try to translate the internal hex string to
2877 			 * human-readable output.  If there are any
2878 			 * problems just use the hex string.
2879 			 */
2880 
2881 			if (str_to_label(propbuf, &new_sl, MAC_LABEL,
2882 			    L_NO_CORRECTION, NULL) == -1) {
2883 				m_label_free(new_sl);
2884 				break;
2885 			}
2886 
2887 			if (label_to_str(new_sl, &ascii, M_LABEL,
2888 			    DEF_NAMES) != 0) {
2889 				if (ascii)
2890 					free(ascii);
2891 				m_label_free(new_sl);
2892 				break;
2893 			}
2894 			m_label_free(new_sl);
2895 
2896 			(void) strlcpy(propbuf, ascii, proplen);
2897 			free(ascii);
2898 #else
2899 			(void) strlcpy(propbuf,
2900 			    getprop_string(zhp, prop, &source), proplen);
2901 #endif /* HAVE_MLSLABEL */
2902 		}
2903 		break;
2904 
2905 	case ZFS_PROP_GUID:
2906 	case ZFS_PROP_KEY_GUID:
2907 	case ZFS_PROP_IVSET_GUID:
2908 	case ZFS_PROP_CREATETXG:
2909 	case ZFS_PROP_OBJSETID:
2910 	case ZFS_PROP_PBKDF2_ITERS:
2911 		/*
2912 		 * These properties are stored as numbers, but they are
2913 		 * identifiers or counters.
2914 		 * We don't want them to be pretty printed, because pretty
2915 		 * printing truncates their values making them useless.
2916 		 */
2917 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2918 			return (-1);
2919 		(void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val);
2920 		zcp_check(zhp, prop, val, NULL);
2921 		break;
2922 
2923 	case ZFS_PROP_REFERENCED:
2924 	case ZFS_PROP_AVAILABLE:
2925 	case ZFS_PROP_USED:
2926 	case ZFS_PROP_USEDSNAP:
2927 	case ZFS_PROP_USEDDS:
2928 	case ZFS_PROP_USEDREFRESERV:
2929 	case ZFS_PROP_USEDCHILD:
2930 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2931 			return (-1);
2932 		if (literal) {
2933 			(void) snprintf(propbuf, proplen, "%llu",
2934 			    (u_longlong_t)val);
2935 		} else {
2936 			zfs_nicebytes(val, propbuf, proplen);
2937 		}
2938 		zcp_check(zhp, prop, val, NULL);
2939 		break;
2940 
2941 	default:
2942 		switch (zfs_prop_get_type(prop)) {
2943 		case PROP_TYPE_NUMBER:
2944 			if (get_numeric_property(zhp, prop, src,
2945 			    &source, &val) != 0) {
2946 				return (-1);
2947 			}
2948 
2949 			if (literal) {
2950 				(void) snprintf(propbuf, proplen, "%llu",
2951 				    (u_longlong_t)val);
2952 			} else {
2953 				zfs_nicenum(val, propbuf, proplen);
2954 			}
2955 			zcp_check(zhp, prop, val, NULL);
2956 			break;
2957 
2958 		case PROP_TYPE_STRING:
2959 			str = getprop_string(zhp, prop, &source);
2960 			if (str == NULL)
2961 				return (-1);
2962 
2963 			(void) strlcpy(propbuf, str, proplen);
2964 			zcp_check(zhp, prop, 0, str);
2965 			break;
2966 
2967 		case PROP_TYPE_INDEX:
2968 			if (get_numeric_property(zhp, prop, src,
2969 			    &source, &val) != 0)
2970 				return (-1);
2971 			if (zfs_prop_index_to_string(prop, val, &strval) != 0)
2972 				return (-1);
2973 
2974 			(void) strlcpy(propbuf, strval, proplen);
2975 			zcp_check(zhp, prop, 0, strval);
2976 			break;
2977 
2978 		default:
2979 			abort();
2980 		}
2981 	}
2982 
2983 	get_source(zhp, src, source, statbuf, statlen);
2984 
2985 	return (0);
2986 }
2987 
2988 /*
2989  * Utility function to get the given numeric property.  Does no validation that
2990  * the given property is the appropriate type; should only be used with
2991  * hard-coded property types.
2992  */
2993 uint64_t
2994 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
2995 {
2996 	char *source;
2997 	uint64_t val = 0;
2998 
2999 	(void) get_numeric_property(zhp, prop, NULL, &source, &val);
3000 
3001 	return (val);
3002 }
3003 
3004 static int
3005 zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val)
3006 {
3007 	char buf[64];
3008 
3009 	(void) snprintf(buf, sizeof (buf), "%llu", (longlong_t)val);
3010 	return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf));
3011 }
3012 
3013 /*
3014  * Similar to zfs_prop_get(), but returns the value as an integer.
3015  */
3016 int
3017 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
3018     zprop_source_t *src, char *statbuf, size_t statlen)
3019 {
3020 	char *source;
3021 
3022 	/*
3023 	 * Check to see if this property applies to our object
3024 	 */
3025 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE)) {
3026 		return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
3027 		    dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
3028 		    zfs_prop_to_name(prop)));
3029 	}
3030 
3031 	if (src)
3032 		*src = ZPROP_SRC_NONE;
3033 
3034 	if (get_numeric_property(zhp, prop, src, &source, value) != 0)
3035 		return (-1);
3036 
3037 	get_source(zhp, src, source, statbuf, statlen);
3038 
3039 	return (0);
3040 }
3041 
3042 #ifdef HAVE_IDMAP
3043 static int
3044 idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
3045     char **domainp, idmap_rid_t *ridp)
3046 {
3047 	idmap_get_handle_t *get_hdl = NULL;
3048 	idmap_stat status;
3049 	int err = EINVAL;
3050 
3051 	if (idmap_get_create(&get_hdl) != IDMAP_SUCCESS)
3052 		goto out;
3053 
3054 	if (isuser) {
3055 		err = idmap_get_sidbyuid(get_hdl, id,
3056 		    IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
3057 	} else {
3058 		err = idmap_get_sidbygid(get_hdl, id,
3059 		    IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
3060 	}
3061 	if (err == IDMAP_SUCCESS &&
3062 	    idmap_get_mappings(get_hdl) == IDMAP_SUCCESS &&
3063 	    status == IDMAP_SUCCESS)
3064 		err = 0;
3065 	else
3066 		err = EINVAL;
3067 out:
3068 	if (get_hdl)
3069 		idmap_get_destroy(get_hdl);
3070 	return (err);
3071 }
3072 #endif /* HAVE_IDMAP */
3073 
3074 /*
3075  * convert the propname into parameters needed by kernel
3076  * Eg: userquota@ahrens -> ZFS_PROP_USERQUOTA, "", 126829
3077  * Eg: userused@matt@domain -> ZFS_PROP_USERUSED, "S-1-123-456", 789
3078  * Eg: groupquota@staff -> ZFS_PROP_GROUPQUOTA, "", 1234
3079  * Eg: groupused@staff -> ZFS_PROP_GROUPUSED, "", 1234
3080  * Eg: projectquota@123 -> ZFS_PROP_PROJECTQUOTA, "", 123
3081  * Eg: projectused@789 -> ZFS_PROP_PROJECTUSED, "", 789
3082  */
3083 static int
3084 userquota_propname_decode(const char *propname, boolean_t zoned,
3085     zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp)
3086 {
3087 	zfs_userquota_prop_t type;
3088 	char *cp;
3089 	boolean_t isuser;
3090 	boolean_t isgroup;
3091 	boolean_t isproject;
3092 	struct passwd *pw;
3093 	struct group *gr;
3094 
3095 	domain[0] = '\0';
3096 
3097 	/* Figure out the property type ({user|group|project}{quota|space}) */
3098 	for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
3099 		if (strncmp(propname, zfs_userquota_prop_prefixes[type],
3100 		    strlen(zfs_userquota_prop_prefixes[type])) == 0)
3101 			break;
3102 	}
3103 	if (type == ZFS_NUM_USERQUOTA_PROPS)
3104 		return (EINVAL);
3105 	*typep = type;
3106 
3107 	isuser = (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_USERUSED ||
3108 	    type == ZFS_PROP_USEROBJQUOTA ||
3109 	    type == ZFS_PROP_USEROBJUSED);
3110 	isgroup = (type == ZFS_PROP_GROUPQUOTA || type == ZFS_PROP_GROUPUSED ||
3111 	    type == ZFS_PROP_GROUPOBJQUOTA ||
3112 	    type == ZFS_PROP_GROUPOBJUSED);
3113 	isproject = (type == ZFS_PROP_PROJECTQUOTA ||
3114 	    type == ZFS_PROP_PROJECTUSED || type == ZFS_PROP_PROJECTOBJQUOTA ||
3115 	    type == ZFS_PROP_PROJECTOBJUSED);
3116 
3117 	cp = strchr(propname, '@') + 1;
3118 
3119 	if (isuser && (pw = getpwnam(cp)) != NULL) {
3120 		if (zoned && getzoneid() == GLOBAL_ZONEID)
3121 			return (ENOENT);
3122 		*ridp = pw->pw_uid;
3123 	} else if (isgroup && (gr = getgrnam(cp)) != NULL) {
3124 		if (zoned && getzoneid() == GLOBAL_ZONEID)
3125 			return (ENOENT);
3126 		*ridp = gr->gr_gid;
3127 	} else if (!isproject && strchr(cp, '@')) {
3128 #ifdef HAVE_IDMAP
3129 		/*
3130 		 * It's a SID name (eg "user@domain") that needs to be
3131 		 * turned into S-1-domainID-RID.
3132 		 */
3133 		directory_error_t e;
3134 		char *numericsid = NULL;
3135 		char *end;
3136 
3137 		if (zoned && getzoneid() == GLOBAL_ZONEID)
3138 			return (ENOENT);
3139 		if (isuser) {
3140 			e = directory_sid_from_user_name(NULL,
3141 			    cp, &numericsid);
3142 		} else {
3143 			e = directory_sid_from_group_name(NULL,
3144 			    cp, &numericsid);
3145 		}
3146 		if (e != NULL) {
3147 			directory_error_free(e);
3148 			return (ENOENT);
3149 		}
3150 		if (numericsid == NULL)
3151 			return (ENOENT);
3152 		cp = numericsid;
3153 		(void) strlcpy(domain, cp, domainlen);
3154 		cp = strrchr(domain, '-');
3155 		*cp = '\0';
3156 		cp++;
3157 
3158 		errno = 0;
3159 		*ridp = strtoull(cp, &end, 10);
3160 		free(numericsid);
3161 
3162 		if (errno != 0 || *end != '\0')
3163 			return (EINVAL);
3164 #else
3165 		(void) domainlen;
3166 		return (ENOSYS);
3167 #endif /* HAVE_IDMAP */
3168 	} else {
3169 		/* It's a user/group/project ID (eg "12345"). */
3170 		uid_t id;
3171 		char *end;
3172 		id = strtoul(cp, &end, 10);
3173 		if (*end != '\0')
3174 			return (EINVAL);
3175 		if (id > MAXUID && !isproject) {
3176 #ifdef HAVE_IDMAP
3177 			/* It's an ephemeral ID. */
3178 			idmap_rid_t rid;
3179 			char *mapdomain;
3180 
3181 			if (idmap_id_to_numeric_domain_rid(id, isuser,
3182 			    &mapdomain, &rid) != 0)
3183 				return (ENOENT);
3184 			(void) strlcpy(domain, mapdomain, domainlen);
3185 			*ridp = rid;
3186 #else
3187 			return (ENOSYS);
3188 #endif /* HAVE_IDMAP */
3189 		} else {
3190 			*ridp = id;
3191 		}
3192 	}
3193 
3194 	return (0);
3195 }
3196 
3197 static int
3198 zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname,
3199     uint64_t *propvalue, zfs_userquota_prop_t *typep)
3200 {
3201 	int err;
3202 	zfs_cmd_t zc = {"\0"};
3203 
3204 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3205 
3206 	err = userquota_propname_decode(propname,
3207 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED),
3208 	    typep, zc.zc_value, sizeof (zc.zc_value), &zc.zc_guid);
3209 	zc.zc_objset_type = *typep;
3210 	if (err)
3211 		return (err);
3212 
3213 	err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_USERSPACE_ONE, &zc);
3214 	if (err)
3215 		return (err);
3216 
3217 	*propvalue = zc.zc_cookie;
3218 	return (0);
3219 }
3220 
3221 int
3222 zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname,
3223     uint64_t *propvalue)
3224 {
3225 	zfs_userquota_prop_t type;
3226 
3227 	return (zfs_prop_get_userquota_common(zhp, propname, propvalue,
3228 	    &type));
3229 }
3230 
3231 int
3232 zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
3233     char *propbuf, int proplen, boolean_t literal)
3234 {
3235 	int err;
3236 	uint64_t propvalue;
3237 	zfs_userquota_prop_t type;
3238 
3239 	err = zfs_prop_get_userquota_common(zhp, propname, &propvalue,
3240 	    &type);
3241 
3242 	if (err)
3243 		return (err);
3244 
3245 	if (literal) {
3246 		(void) snprintf(propbuf, proplen, "%llu",
3247 		    (u_longlong_t)propvalue);
3248 	} else if (propvalue == 0 &&
3249 	    (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA ||
3250 	    type == ZFS_PROP_USEROBJQUOTA || type == ZFS_PROP_GROUPOBJQUOTA ||
3251 	    type == ZFS_PROP_PROJECTQUOTA ||
3252 	    type == ZFS_PROP_PROJECTOBJQUOTA)) {
3253 		(void) strlcpy(propbuf, "none", proplen);
3254 	} else if (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA ||
3255 	    type == ZFS_PROP_USERUSED || type == ZFS_PROP_GROUPUSED ||
3256 	    type == ZFS_PROP_PROJECTUSED || type == ZFS_PROP_PROJECTQUOTA) {
3257 		zfs_nicebytes(propvalue, propbuf, proplen);
3258 	} else {
3259 		zfs_nicenum(propvalue, propbuf, proplen);
3260 	}
3261 	return (0);
3262 }
3263 
3264 /*
3265  * propname must start with "written@" or "written#".
3266  */
3267 int
3268 zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
3269     uint64_t *propvalue)
3270 {
3271 	int err;
3272 	zfs_cmd_t zc = {"\0"};
3273 	const char *snapname;
3274 
3275 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3276 
3277 	assert(zfs_prop_written(propname));
3278 	snapname = propname + strlen("written@");
3279 	if (strchr(snapname, '@') != NULL || strchr(snapname, '#') != NULL) {
3280 		/* full snapshot or bookmark name specified */
3281 		(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
3282 	} else {
3283 		/* snapname is the short name, append it to zhp's fsname */
3284 		char *cp;
3285 
3286 		(void) strlcpy(zc.zc_value, zhp->zfs_name,
3287 		    sizeof (zc.zc_value));
3288 		cp = strchr(zc.zc_value, '@');
3289 		if (cp != NULL)
3290 			*cp = '\0';
3291 		(void) strlcat(zc.zc_value, snapname - 1, sizeof (zc.zc_value));
3292 	}
3293 
3294 	err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SPACE_WRITTEN, &zc);
3295 	if (err)
3296 		return (err);
3297 
3298 	*propvalue = zc.zc_cookie;
3299 	return (0);
3300 }
3301 
3302 int
3303 zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
3304     char *propbuf, int proplen, boolean_t literal)
3305 {
3306 	int err;
3307 	uint64_t propvalue;
3308 
3309 	err = zfs_prop_get_written_int(zhp, propname, &propvalue);
3310 
3311 	if (err)
3312 		return (err);
3313 
3314 	if (literal) {
3315 		(void) snprintf(propbuf, proplen, "%llu",
3316 		    (u_longlong_t)propvalue);
3317 	} else {
3318 		zfs_nicebytes(propvalue, propbuf, proplen);
3319 	}
3320 
3321 	return (0);
3322 }
3323 
3324 /*
3325  * Returns the name of the given zfs handle.
3326  */
3327 const char *
3328 zfs_get_name(const zfs_handle_t *zhp)
3329 {
3330 	return (zhp->zfs_name);
3331 }
3332 
3333 /*
3334  * Returns the name of the parent pool for the given zfs handle.
3335  */
3336 const char *
3337 zfs_get_pool_name(const zfs_handle_t *zhp)
3338 {
3339 	return (zhp->zpool_hdl->zpool_name);
3340 }
3341 
3342 /*
3343  * Returns the type of the given zfs handle.
3344  */
3345 zfs_type_t
3346 zfs_get_type(const zfs_handle_t *zhp)
3347 {
3348 	return (zhp->zfs_type);
3349 }
3350 
3351 /*
3352  * Returns the type of the given zfs handle,
3353  * or, if a snapshot, the type of the snapshotted dataset.
3354  */
3355 zfs_type_t
3356 zfs_get_underlying_type(const zfs_handle_t *zhp)
3357 {
3358 	return (zhp->zfs_head_type);
3359 }
3360 
3361 /*
3362  * Is one dataset name a child dataset of another?
3363  *
3364  * Needs to handle these cases:
3365  * Dataset 1	"a/foo"		"a/foo"		"a/foo"		"a/foo"
3366  * Dataset 2	"a/fo"		"a/foobar"	"a/bar/baz"	"a/foo/bar"
3367  * Descendant?	No.		No.		No.		Yes.
3368  */
3369 static boolean_t
3370 is_descendant(const char *ds1, const char *ds2)
3371 {
3372 	size_t d1len = strlen(ds1);
3373 
3374 	/* ds2 can't be a descendant if it's smaller */
3375 	if (strlen(ds2) < d1len)
3376 		return (B_FALSE);
3377 
3378 	/* otherwise, compare strings and verify that there's a '/' char */
3379 	return (ds2[d1len] == '/' && (strncmp(ds1, ds2, d1len) == 0));
3380 }
3381 
3382 /*
3383  * Given a complete name, return just the portion that refers to the parent.
3384  * Will return -1 if there is no parent (path is just the name of the
3385  * pool).
3386  */
3387 static int
3388 parent_name(const char *path, char *buf, size_t buflen)
3389 {
3390 	char *slashp;
3391 
3392 	(void) strlcpy(buf, path, buflen);
3393 
3394 	if ((slashp = strrchr(buf, '/')) == NULL)
3395 		return (-1);
3396 	*slashp = '\0';
3397 
3398 	return (0);
3399 }
3400 
3401 int
3402 zfs_parent_name(zfs_handle_t *zhp, char *buf, size_t buflen)
3403 {
3404 	return (parent_name(zfs_get_name(zhp), buf, buflen));
3405 }
3406 
3407 /*
3408  * If accept_ancestor is false, then check to make sure that the given path has
3409  * a parent, and that it exists.  If accept_ancestor is true, then find the
3410  * closest existing ancestor for the given path.  In prefixlen return the
3411  * length of already existing prefix of the given path.  We also fetch the
3412  * 'zoned' property, which is used to validate property settings when creating
3413  * new datasets.
3414  */
3415 static int
3416 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
3417     boolean_t accept_ancestor, int *prefixlen)
3418 {
3419 	zfs_cmd_t zc = {"\0"};
3420 	char parent[ZFS_MAX_DATASET_NAME_LEN];
3421 	char *slash;
3422 	zfs_handle_t *zhp;
3423 	char errbuf[1024];
3424 	uint64_t is_zoned;
3425 
3426 	(void) snprintf(errbuf, sizeof (errbuf),
3427 	    dgettext(TEXT_DOMAIN, "cannot create '%s'"), path);
3428 
3429 	/* get parent, and check to see if this is just a pool */
3430 	if (parent_name(path, parent, sizeof (parent)) != 0) {
3431 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3432 		    "missing dataset name"));
3433 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3434 	}
3435 
3436 	/* check to see if the pool exists */
3437 	if ((slash = strchr(parent, '/')) == NULL)
3438 		slash = parent + strlen(parent);
3439 	(void) strncpy(zc.zc_name, parent, slash - parent);
3440 	zc.zc_name[slash - parent] = '\0';
3441 	if (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
3442 	    errno == ENOENT) {
3443 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3444 		    "no such pool '%s'"), zc.zc_name);
3445 		return (zfs_error(hdl, EZFS_NOENT, errbuf));
3446 	}
3447 
3448 	/* check to see if the parent dataset exists */
3449 	while ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
3450 		if (errno == ENOENT && accept_ancestor) {
3451 			/*
3452 			 * Go deeper to find an ancestor, give up on top level.
3453 			 */
3454 			if (parent_name(parent, parent, sizeof (parent)) != 0) {
3455 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3456 				    "no such pool '%s'"), zc.zc_name);
3457 				return (zfs_error(hdl, EZFS_NOENT, errbuf));
3458 			}
3459 		} else if (errno == ENOENT) {
3460 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3461 			    "parent does not exist"));
3462 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
3463 		} else
3464 			return (zfs_standard_error(hdl, errno, errbuf));
3465 	}
3466 
3467 	is_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
3468 	if (zoned != NULL)
3469 		*zoned = is_zoned;
3470 
3471 	/* we are in a non-global zone, but parent is in the global zone */
3472 	if (getzoneid() != GLOBAL_ZONEID && !is_zoned) {
3473 		(void) zfs_standard_error(hdl, EPERM, errbuf);
3474 		zfs_close(zhp);
3475 		return (-1);
3476 	}
3477 
3478 	/* make sure parent is a filesystem */
3479 	if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
3480 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3481 		    "parent is not a filesystem"));
3482 		(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
3483 		zfs_close(zhp);
3484 		return (-1);
3485 	}
3486 
3487 	zfs_close(zhp);
3488 	if (prefixlen != NULL)
3489 		*prefixlen = strlen(parent);
3490 	return (0);
3491 }
3492 
3493 /*
3494  * Finds whether the dataset of the given type(s) exists.
3495  */
3496 boolean_t
3497 zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types)
3498 {
3499 	zfs_handle_t *zhp;
3500 
3501 	if (!zfs_validate_name(hdl, path, types, B_FALSE))
3502 		return (B_FALSE);
3503 
3504 	/*
3505 	 * Try to get stats for the dataset, which will tell us if it exists.
3506 	 */
3507 	if ((zhp = make_dataset_handle(hdl, path)) != NULL) {
3508 		int ds_type = zhp->zfs_type;
3509 
3510 		zfs_close(zhp);
3511 		if (types & ds_type)
3512 			return (B_TRUE);
3513 	}
3514 	return (B_FALSE);
3515 }
3516 
3517 /*
3518  * Given a path to 'target', create all the ancestors between
3519  * the prefixlen portion of the path, and the target itself.
3520  * Fail if the initial prefixlen-ancestor does not already exist.
3521  */
3522 int
3523 create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
3524 {
3525 	zfs_handle_t *h;
3526 	char *cp;
3527 	const char *opname;
3528 
3529 	/* make sure prefix exists */
3530 	cp = target + prefixlen;
3531 	if (*cp != '/') {
3532 		assert(strchr(cp, '/') == NULL);
3533 		h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
3534 	} else {
3535 		*cp = '\0';
3536 		h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
3537 		*cp = '/';
3538 	}
3539 	if (h == NULL)
3540 		return (-1);
3541 	zfs_close(h);
3542 
3543 	/*
3544 	 * Attempt to create, mount, and share any ancestor filesystems,
3545 	 * up to the prefixlen-long one.
3546 	 */
3547 	for (cp = target + prefixlen + 1;
3548 	    (cp = strchr(cp, '/')) != NULL; *cp = '/', cp++) {
3549 
3550 		*cp = '\0';
3551 
3552 		h = make_dataset_handle(hdl, target);
3553 		if (h) {
3554 			/* it already exists, nothing to do here */
3555 			zfs_close(h);
3556 			continue;
3557 		}
3558 
3559 		if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
3560 		    NULL) != 0) {
3561 			opname = dgettext(TEXT_DOMAIN, "create");
3562 			goto ancestorerr;
3563 		}
3564 
3565 		h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
3566 		if (h == NULL) {
3567 			opname = dgettext(TEXT_DOMAIN, "open");
3568 			goto ancestorerr;
3569 		}
3570 
3571 		if (zfs_mount(h, NULL, 0) != 0) {
3572 			opname = dgettext(TEXT_DOMAIN, "mount");
3573 			goto ancestorerr;
3574 		}
3575 
3576 		if (zfs_share(h) != 0) {
3577 			opname = dgettext(TEXT_DOMAIN, "share");
3578 			goto ancestorerr;
3579 		}
3580 
3581 		zfs_close(h);
3582 	}
3583 	zfs_commit_all_shares();
3584 
3585 	return (0);
3586 
3587 ancestorerr:
3588 	zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3589 	    "failed to %s ancestor '%s'"), opname, target);
3590 	return (-1);
3591 }
3592 
3593 /*
3594  * Creates non-existing ancestors of the given path.
3595  */
3596 int
3597 zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
3598 {
3599 	int prefix;
3600 	char *path_copy;
3601 	char errbuf[1024];
3602 	int rc = 0;
3603 
3604 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3605 	    "cannot create '%s'"), path);
3606 
3607 	/*
3608 	 * Check that we are not passing the nesting limit
3609 	 * before we start creating any ancestors.
3610 	 */
3611 	if (dataset_nestcheck(path) != 0) {
3612 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3613 		    "maximum name nesting depth exceeded"));
3614 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3615 	}
3616 
3617 	if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
3618 		return (-1);
3619 
3620 	if ((path_copy = strdup(path)) != NULL) {
3621 		rc = create_parents(hdl, path_copy, prefix);
3622 		free(path_copy);
3623 	}
3624 	if (path_copy == NULL || rc != 0)
3625 		return (-1);
3626 
3627 	return (0);
3628 }
3629 
3630 /*
3631  * Create a new filesystem or volume.
3632  */
3633 int
3634 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
3635     nvlist_t *props)
3636 {
3637 	int ret;
3638 	uint64_t size = 0;
3639 	uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
3640 	uint64_t zoned;
3641 	enum lzc_dataset_type ost;
3642 	zpool_handle_t *zpool_handle;
3643 	uint8_t *wkeydata = NULL;
3644 	uint_t wkeylen = 0;
3645 	char errbuf[1024];
3646 	char parent[ZFS_MAX_DATASET_NAME_LEN];
3647 
3648 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3649 	    "cannot create '%s'"), path);
3650 
3651 	/* validate the path, taking care to note the extended error message */
3652 	if (!zfs_validate_name(hdl, path, type, B_TRUE))
3653 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3654 
3655 	if (dataset_nestcheck(path) != 0) {
3656 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3657 		    "maximum name nesting depth exceeded"));
3658 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3659 	}
3660 
3661 	/* validate parents exist */
3662 	if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
3663 		return (-1);
3664 
3665 	/*
3666 	 * The failure modes when creating a dataset of a different type over
3667 	 * one that already exists is a little strange.  In particular, if you
3668 	 * try to create a dataset on top of an existing dataset, the ioctl()
3669 	 * will return ENOENT, not EEXIST.  To prevent this from happening, we
3670 	 * first try to see if the dataset exists.
3671 	 */
3672 	if (zfs_dataset_exists(hdl, path, ZFS_TYPE_DATASET)) {
3673 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3674 		    "dataset already exists"));
3675 		return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3676 	}
3677 
3678 	if (type == ZFS_TYPE_VOLUME)
3679 		ost = LZC_DATSET_TYPE_ZVOL;
3680 	else
3681 		ost = LZC_DATSET_TYPE_ZFS;
3682 
3683 	/* open zpool handle for prop validation */
3684 	char pool_path[ZFS_MAX_DATASET_NAME_LEN];
3685 	(void) strlcpy(pool_path, path, sizeof (pool_path));
3686 
3687 	/* truncate pool_path at first slash */
3688 	char *p = strchr(pool_path, '/');
3689 	if (p != NULL)
3690 		*p = '\0';
3691 
3692 	if ((zpool_handle = zpool_open(hdl, pool_path)) == NULL)
3693 		return (-1);
3694 
3695 	if (props && (props = zfs_valid_proplist(hdl, type, props,
3696 	    zoned, NULL, zpool_handle, B_TRUE, errbuf)) == 0) {
3697 		zpool_close(zpool_handle);
3698 		return (-1);
3699 	}
3700 	zpool_close(zpool_handle);
3701 
3702 	if (type == ZFS_TYPE_VOLUME) {
3703 		/*
3704 		 * If we are creating a volume, the size and block size must
3705 		 * satisfy a few restraints.  First, the blocksize must be a
3706 		 * valid block size between SPA_{MIN,MAX}BLOCKSIZE.  Second, the
3707 		 * volsize must be a multiple of the block size, and cannot be
3708 		 * zero.
3709 		 */
3710 		if (props == NULL || nvlist_lookup_uint64(props,
3711 		    zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
3712 			nvlist_free(props);
3713 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3714 			    "missing volume size"));
3715 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3716 		}
3717 
3718 		if ((ret = nvlist_lookup_uint64(props,
3719 		    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
3720 		    &blocksize)) != 0) {
3721 			if (ret == ENOENT) {
3722 				blocksize = zfs_prop_default_numeric(
3723 				    ZFS_PROP_VOLBLOCKSIZE);
3724 			} else {
3725 				nvlist_free(props);
3726 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3727 				    "missing volume block size"));
3728 				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3729 			}
3730 		}
3731 
3732 		if (size == 0) {
3733 			nvlist_free(props);
3734 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3735 			    "volume size cannot be zero"));
3736 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3737 		}
3738 
3739 		if (size % blocksize != 0) {
3740 			nvlist_free(props);
3741 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3742 			    "volume size must be a multiple of volume block "
3743 			    "size"));
3744 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3745 		}
3746 	}
3747 
3748 	(void) parent_name(path, parent, sizeof (parent));
3749 	if (zfs_crypto_create(hdl, parent, props, NULL, B_TRUE,
3750 	    &wkeydata, &wkeylen) != 0) {
3751 		nvlist_free(props);
3752 		return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
3753 	}
3754 
3755 	/* create the dataset */
3756 	ret = lzc_create(path, ost, props, wkeydata, wkeylen);
3757 	nvlist_free(props);
3758 	if (wkeydata != NULL)
3759 		free(wkeydata);
3760 
3761 	/* check for failure */
3762 	if (ret != 0) {
3763 		switch (errno) {
3764 		case ENOENT:
3765 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3766 			    "no such parent '%s'"), parent);
3767 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
3768 
3769 		case ENOTSUP:
3770 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3771 			    "pool must be upgraded to set this "
3772 			    "property or value"));
3773 			return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
3774 
3775 		case EACCES:
3776 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3777 			    "encryption root's key is not loaded "
3778 			    "or provided"));
3779 			return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
3780 
3781 		case ERANGE:
3782 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3783 			    "invalid property value(s) specified"));
3784 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3785 #ifdef _ILP32
3786 		case EOVERFLOW:
3787 			/*
3788 			 * This platform can't address a volume this big.
3789 			 */
3790 			if (type == ZFS_TYPE_VOLUME)
3791 				return (zfs_error(hdl, EZFS_VOLTOOBIG,
3792 				    errbuf));
3793 			zfs_fallthrough;
3794 #endif
3795 		default:
3796 			return (zfs_standard_error(hdl, errno, errbuf));
3797 		}
3798 	}
3799 
3800 	return (0);
3801 }
3802 
3803 /*
3804  * Destroys the given dataset.  The caller must make sure that the filesystem
3805  * isn't mounted, and that there are no active dependents. If the file system
3806  * does not exist this function does nothing.
3807  */
3808 int
3809 zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
3810 {
3811 	int error;
3812 
3813 	if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT && defer)
3814 		return (EINVAL);
3815 
3816 	if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
3817 		nvlist_t *nv = fnvlist_alloc();
3818 		fnvlist_add_boolean(nv, zhp->zfs_name);
3819 		error = lzc_destroy_bookmarks(nv, NULL);
3820 		fnvlist_free(nv);
3821 		if (error != 0) {
3822 			return (zfs_standard_error_fmt(zhp->zfs_hdl, error,
3823 			    dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3824 			    zhp->zfs_name));
3825 		}
3826 		return (0);
3827 	}
3828 
3829 	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3830 		nvlist_t *nv = fnvlist_alloc();
3831 		fnvlist_add_boolean(nv, zhp->zfs_name);
3832 		error = lzc_destroy_snaps(nv, defer, NULL);
3833 		fnvlist_free(nv);
3834 	} else {
3835 		error = lzc_destroy(zhp->zfs_name);
3836 	}
3837 
3838 	if (error != 0 && error != ENOENT) {
3839 		return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3840 		    dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3841 		    zhp->zfs_name));
3842 	}
3843 
3844 	remove_mountpoint(zhp);
3845 
3846 	return (0);
3847 }
3848 
3849 struct destroydata {
3850 	nvlist_t *nvl;
3851 	const char *snapname;
3852 };
3853 
3854 static int
3855 zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
3856 {
3857 	struct destroydata *dd = arg;
3858 	char name[ZFS_MAX_DATASET_NAME_LEN];
3859 	int rv = 0;
3860 
3861 	if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
3862 	    dd->snapname) >= sizeof (name))
3863 		return (EINVAL);
3864 
3865 	if (lzc_exists(name))
3866 		verify(nvlist_add_boolean(dd->nvl, name) == 0);
3867 
3868 	rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, dd);
3869 	zfs_close(zhp);
3870 	return (rv);
3871 }
3872 
3873 /*
3874  * Destroys all snapshots with the given name in zhp & descendants.
3875  */
3876 int
3877 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
3878 {
3879 	int ret;
3880 	struct destroydata dd = { 0 };
3881 
3882 	dd.snapname = snapname;
3883 	verify(nvlist_alloc(&dd.nvl, NV_UNIQUE_NAME, 0) == 0);
3884 	(void) zfs_check_snap_cb(zfs_handle_dup(zhp), &dd);
3885 
3886 	if (nvlist_empty(dd.nvl)) {
3887 		ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
3888 		    dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
3889 		    zhp->zfs_name, snapname);
3890 	} else {
3891 		ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer);
3892 	}
3893 	nvlist_free(dd.nvl);
3894 	return (ret);
3895 }
3896 
3897 /*
3898  * Destroys all the snapshots named in the nvlist.
3899  */
3900 int
3901 zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
3902 {
3903 	nvlist_t *errlist = NULL;
3904 	nvpair_t *pair;
3905 
3906 	int ret = zfs_destroy_snaps_nvl_os(hdl, snaps);
3907 	if (ret != 0)
3908 		return (ret);
3909 
3910 	ret = lzc_destroy_snaps(snaps, defer, &errlist);
3911 
3912 	if (ret == 0) {
3913 		nvlist_free(errlist);
3914 		return (0);
3915 	}
3916 
3917 	if (nvlist_empty(errlist)) {
3918 		char errbuf[1024];
3919 		(void) snprintf(errbuf, sizeof (errbuf),
3920 		    dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
3921 
3922 		ret = zfs_standard_error(hdl, ret, errbuf);
3923 	}
3924 	for (pair = nvlist_next_nvpair(errlist, NULL);
3925 	    pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
3926 		char errbuf[1024];
3927 		(void) snprintf(errbuf, sizeof (errbuf),
3928 		    dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
3929 		    nvpair_name(pair));
3930 
3931 		switch (fnvpair_value_int32(pair)) {
3932 		case EEXIST:
3933 			zfs_error_aux(hdl,
3934 			    dgettext(TEXT_DOMAIN, "snapshot is cloned"));
3935 			ret = zfs_error(hdl, EZFS_EXISTS, errbuf);
3936 			break;
3937 		default:
3938 			ret = zfs_standard_error(hdl, errno, errbuf);
3939 			break;
3940 		}
3941 	}
3942 
3943 	nvlist_free(errlist);
3944 	return (ret);
3945 }
3946 
3947 /*
3948  * Clones the given dataset.  The target must be of the same type as the source.
3949  */
3950 int
3951 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
3952 {
3953 	char parent[ZFS_MAX_DATASET_NAME_LEN];
3954 	int ret;
3955 	char errbuf[1024];
3956 	libzfs_handle_t *hdl = zhp->zfs_hdl;
3957 	uint64_t zoned;
3958 
3959 	assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
3960 
3961 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3962 	    "cannot create '%s'"), target);
3963 
3964 	/* validate the target/clone name */
3965 	if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
3966 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3967 
3968 	/* validate parents exist */
3969 	if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
3970 		return (-1);
3971 
3972 	(void) parent_name(target, parent, sizeof (parent));
3973 
3974 	/* do the clone */
3975 
3976 	if (props) {
3977 		zfs_type_t type = ZFS_TYPE_FILESYSTEM;
3978 
3979 		if (ZFS_IS_VOLUME(zhp))
3980 			type = ZFS_TYPE_VOLUME;
3981 		if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3982 		    zhp, zhp->zpool_hdl, B_TRUE, errbuf)) == NULL)
3983 			return (-1);
3984 		if (zfs_fix_auto_resv(zhp, props) == -1) {
3985 			nvlist_free(props);
3986 			return (-1);
3987 		}
3988 	}
3989 
3990 	if (zfs_crypto_clone_check(hdl, zhp, parent, props) != 0) {
3991 		nvlist_free(props);
3992 		return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
3993 	}
3994 
3995 	ret = lzc_clone(target, zhp->zfs_name, props);
3996 	nvlist_free(props);
3997 
3998 	if (ret != 0) {
3999 		switch (errno) {
4000 
4001 		case ENOENT:
4002 			/*
4003 			 * The parent doesn't exist.  We should have caught this
4004 			 * above, but there may a race condition that has since
4005 			 * destroyed the parent.
4006 			 *
4007 			 * At this point, we don't know whether it's the source
4008 			 * that doesn't exist anymore, or whether the target
4009 			 * dataset doesn't exist.
4010 			 */
4011 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
4012 			    "no such parent '%s'"), parent);
4013 			return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
4014 
4015 		case EXDEV:
4016 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
4017 			    "source and target pools differ"));
4018 			return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
4019 			    errbuf));
4020 
4021 		default:
4022 			return (zfs_standard_error(zhp->zfs_hdl, errno,
4023 			    errbuf));
4024 		}
4025 	}
4026 
4027 	return (ret);
4028 }
4029 
4030 /*
4031  * Promotes the given clone fs to be the clone parent.
4032  */
4033 int
4034 zfs_promote(zfs_handle_t *zhp)
4035 {
4036 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4037 	char snapname[ZFS_MAX_DATASET_NAME_LEN];
4038 	int ret;
4039 	char errbuf[1024];
4040 
4041 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4042 	    "cannot promote '%s'"), zhp->zfs_name);
4043 
4044 	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
4045 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4046 		    "snapshots can not be promoted"));
4047 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4048 	}
4049 
4050 	if (zhp->zfs_dmustats.dds_origin[0] == '\0') {
4051 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4052 		    "not a cloned filesystem"));
4053 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4054 	}
4055 
4056 	if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE))
4057 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4058 
4059 	ret = lzc_promote(zhp->zfs_name, snapname, sizeof (snapname));
4060 
4061 	if (ret != 0) {
4062 		switch (ret) {
4063 		case EACCES:
4064 			/*
4065 			 * Promoting encrypted dataset outside its
4066 			 * encryption root.
4067 			 */
4068 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4069 			    "cannot promote dataset outside its "
4070 			    "encryption root"));
4071 			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
4072 
4073 		case EEXIST:
4074 			/* There is a conflicting snapshot name. */
4075 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4076 			    "conflicting snapshot '%s' from parent '%s'"),
4077 			    snapname, zhp->zfs_dmustats.dds_origin);
4078 			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
4079 
4080 		default:
4081 			return (zfs_standard_error(hdl, ret, errbuf));
4082 		}
4083 	}
4084 	return (ret);
4085 }
4086 
4087 typedef struct snapdata {
4088 	nvlist_t *sd_nvl;
4089 	const char *sd_snapname;
4090 } snapdata_t;
4091 
4092 static int
4093 zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
4094 {
4095 	snapdata_t *sd = arg;
4096 	char name[ZFS_MAX_DATASET_NAME_LEN];
4097 	int rv = 0;
4098 
4099 	if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
4100 		if (snprintf(name, sizeof (name), "%s@%s", zfs_get_name(zhp),
4101 		    sd->sd_snapname) >= sizeof (name))
4102 			return (EINVAL);
4103 
4104 		fnvlist_add_boolean(sd->sd_nvl, name);
4105 
4106 		rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
4107 	}
4108 	zfs_close(zhp);
4109 
4110 	return (rv);
4111 }
4112 
4113 /*
4114  * Creates snapshots.  The keys in the snaps nvlist are the snapshots to be
4115  * created.
4116  */
4117 int
4118 zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
4119 {
4120 	int ret;
4121 	char errbuf[1024];
4122 	nvpair_t *elem;
4123 	nvlist_t *errors;
4124 	zpool_handle_t *zpool_hdl;
4125 	char pool[ZFS_MAX_DATASET_NAME_LEN];
4126 
4127 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4128 	    "cannot create snapshots "));
4129 
4130 	elem = NULL;
4131 	while ((elem = nvlist_next_nvpair(snaps, elem)) != NULL) {
4132 		const char *snapname = nvpair_name(elem);
4133 
4134 		/* validate the target name */
4135 		if (!zfs_validate_name(hdl, snapname, ZFS_TYPE_SNAPSHOT,
4136 		    B_TRUE)) {
4137 			(void) snprintf(errbuf, sizeof (errbuf),
4138 			    dgettext(TEXT_DOMAIN,
4139 			    "cannot create snapshot '%s'"), snapname);
4140 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4141 		}
4142 	}
4143 
4144 	/*
4145 	 * get pool handle for prop validation. assumes all snaps are in the
4146 	 * same pool, as does lzc_snapshot (below).
4147 	 */
4148 	elem = nvlist_next_nvpair(snaps, NULL);
4149 	(void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
4150 	pool[strcspn(pool, "/@")] = '\0';
4151 	zpool_hdl = zpool_open(hdl, pool);
4152 	if (zpool_hdl == NULL)
4153 		return (-1);
4154 
4155 	if (props != NULL &&
4156 	    (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
4157 	    props, B_FALSE, NULL, zpool_hdl, B_FALSE, errbuf)) == NULL) {
4158 		zpool_close(zpool_hdl);
4159 		return (-1);
4160 	}
4161 	zpool_close(zpool_hdl);
4162 
4163 	ret = lzc_snapshot(snaps, props, &errors);
4164 
4165 	if (ret != 0) {
4166 		boolean_t printed = B_FALSE;
4167 		for (elem = nvlist_next_nvpair(errors, NULL);
4168 		    elem != NULL;
4169 		    elem = nvlist_next_nvpair(errors, elem)) {
4170 			(void) snprintf(errbuf, sizeof (errbuf),
4171 			    dgettext(TEXT_DOMAIN,
4172 			    "cannot create snapshot '%s'"), nvpair_name(elem));
4173 			(void) zfs_standard_error(hdl,
4174 			    fnvpair_value_int32(elem), errbuf);
4175 			printed = B_TRUE;
4176 		}
4177 		if (!printed) {
4178 			switch (ret) {
4179 			case EXDEV:
4180 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4181 				    "multiple snapshots of same "
4182 				    "fs not allowed"));
4183 				(void) zfs_error(hdl, EZFS_EXISTS, errbuf);
4184 
4185 				break;
4186 			default:
4187 				(void) zfs_standard_error(hdl, ret, errbuf);
4188 			}
4189 		}
4190 	}
4191 
4192 	nvlist_free(props);
4193 	nvlist_free(errors);
4194 	return (ret);
4195 }
4196 
4197 int
4198 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
4199     nvlist_t *props)
4200 {
4201 	int ret;
4202 	snapdata_t sd = { 0 };
4203 	char fsname[ZFS_MAX_DATASET_NAME_LEN];
4204 	char *cp;
4205 	zfs_handle_t *zhp;
4206 	char errbuf[1024];
4207 
4208 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4209 	    "cannot snapshot %s"), path);
4210 
4211 	if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
4212 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4213 
4214 	(void) strlcpy(fsname, path, sizeof (fsname));
4215 	cp = strchr(fsname, '@');
4216 	*cp = '\0';
4217 	sd.sd_snapname = cp + 1;
4218 
4219 	if ((zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM |
4220 	    ZFS_TYPE_VOLUME)) == NULL) {
4221 		return (-1);
4222 	}
4223 
4224 	verify(nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) == 0);
4225 	if (recursive) {
4226 		(void) zfs_snapshot_cb(zfs_handle_dup(zhp), &sd);
4227 	} else {
4228 		fnvlist_add_boolean(sd.sd_nvl, path);
4229 	}
4230 
4231 	ret = zfs_snapshot_nvl(hdl, sd.sd_nvl, props);
4232 	nvlist_free(sd.sd_nvl);
4233 	zfs_close(zhp);
4234 	return (ret);
4235 }
4236 
4237 /*
4238  * Destroy any more recent snapshots.  We invoke this callback on any dependents
4239  * of the snapshot first.  If the 'cb_dependent' member is non-zero, then this
4240  * is a dependent and we should just destroy it without checking the transaction
4241  * group.
4242  */
4243 typedef struct rollback_data {
4244 	const char	*cb_target;		/* the snapshot */
4245 	uint64_t	cb_create;		/* creation time reference */
4246 	boolean_t	cb_error;
4247 	boolean_t	cb_force;
4248 } rollback_data_t;
4249 
4250 static int
4251 rollback_destroy_dependent(zfs_handle_t *zhp, void *data)
4252 {
4253 	rollback_data_t *cbp = data;
4254 	prop_changelist_t *clp;
4255 
4256 	/* We must destroy this clone; first unmount it */
4257 	clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
4258 	    cbp->cb_force ? MS_FORCE: 0);
4259 	if (clp == NULL || changelist_prefix(clp) != 0) {
4260 		cbp->cb_error = B_TRUE;
4261 		zfs_close(zhp);
4262 		return (0);
4263 	}
4264 	if (zfs_destroy(zhp, B_FALSE) != 0)
4265 		cbp->cb_error = B_TRUE;
4266 	else
4267 		changelist_remove(clp, zhp->zfs_name);
4268 	(void) changelist_postfix(clp);
4269 	changelist_free(clp);
4270 
4271 	zfs_close(zhp);
4272 	return (0);
4273 }
4274 
4275 static int
4276 rollback_destroy(zfs_handle_t *zhp, void *data)
4277 {
4278 	rollback_data_t *cbp = data;
4279 
4280 	if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) {
4281 		cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
4282 		    rollback_destroy_dependent, cbp);
4283 
4284 		cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
4285 	}
4286 
4287 	zfs_close(zhp);
4288 	return (0);
4289 }
4290 
4291 /*
4292  * Given a dataset, rollback to a specific snapshot, discarding any
4293  * data changes since then and making it the active dataset.
4294  *
4295  * Any snapshots and bookmarks more recent than the target are
4296  * destroyed, along with their dependents (i.e. clones).
4297  */
4298 int
4299 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
4300 {
4301 	rollback_data_t cb = { 0 };
4302 	int err;
4303 	boolean_t restore_resv = 0;
4304 	uint64_t old_volsize = 0, new_volsize;
4305 	zfs_prop_t resv_prop = { 0 };
4306 	uint64_t min_txg = 0;
4307 
4308 	assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
4309 	    zhp->zfs_type == ZFS_TYPE_VOLUME);
4310 
4311 	/*
4312 	 * Destroy all recent snapshots and their dependents.
4313 	 */
4314 	cb.cb_force = force;
4315 	cb.cb_target = snap->zfs_name;
4316 	cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
4317 
4318 	if (cb.cb_create > 0)
4319 		min_txg = cb.cb_create;
4320 
4321 	(void) zfs_iter_snapshots(zhp, B_FALSE, rollback_destroy, &cb,
4322 	    min_txg, 0);
4323 
4324 	(void) zfs_iter_bookmarks(zhp, rollback_destroy, &cb);
4325 
4326 	if (cb.cb_error)
4327 		return (-1);
4328 
4329 	/*
4330 	 * Now that we have verified that the snapshot is the latest,
4331 	 * rollback to the given snapshot.
4332 	 */
4333 
4334 	if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
4335 		if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
4336 			return (-1);
4337 		old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
4338 		restore_resv =
4339 		    (old_volsize == zfs_prop_get_int(zhp, resv_prop));
4340 	}
4341 
4342 	/*
4343 	 * Pass both the filesystem and the wanted snapshot names,
4344 	 * we would get an error back if the snapshot is destroyed or
4345 	 * a new snapshot is created before this request is processed.
4346 	 */
4347 	err = lzc_rollback_to(zhp->zfs_name, snap->zfs_name);
4348 	if (err != 0) {
4349 		char errbuf[1024];
4350 
4351 		(void) snprintf(errbuf, sizeof (errbuf),
4352 		    dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
4353 		    zhp->zfs_name);
4354 		switch (err) {
4355 		case EEXIST:
4356 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
4357 			    "there is a snapshot or bookmark more recent "
4358 			    "than '%s'"), snap->zfs_name);
4359 			(void) zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf);
4360 			break;
4361 		case ESRCH:
4362 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
4363 			    "'%s' is not found among snapshots of '%s'"),
4364 			    snap->zfs_name, zhp->zfs_name);
4365 			(void) zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf);
4366 			break;
4367 		case EINVAL:
4368 			(void) zfs_error(zhp->zfs_hdl, EZFS_BADTYPE, errbuf);
4369 			break;
4370 		default:
4371 			(void) zfs_standard_error(zhp->zfs_hdl, err, errbuf);
4372 		}
4373 		return (err);
4374 	}
4375 
4376 	/*
4377 	 * For volumes, if the pre-rollback volsize matched the pre-
4378 	 * rollback reservation and the volsize has changed then set
4379 	 * the reservation property to the post-rollback volsize.
4380 	 * Make a new handle since the rollback closed the dataset.
4381 	 */
4382 	if ((zhp->zfs_type == ZFS_TYPE_VOLUME) &&
4383 	    (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) {
4384 		if (restore_resv) {
4385 			new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
4386 			if (old_volsize != new_volsize)
4387 				err = zfs_prop_set_int(zhp, resv_prop,
4388 				    new_volsize);
4389 		}
4390 		zfs_close(zhp);
4391 	}
4392 	return (err);
4393 }
4394 
4395 /*
4396  * Renames the given dataset.
4397  */
4398 int
4399 zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags)
4400 {
4401 	int ret = 0;
4402 	zfs_cmd_t zc = {"\0"};
4403 	char *delim;
4404 	prop_changelist_t *cl = NULL;
4405 	char parent[ZFS_MAX_DATASET_NAME_LEN];
4406 	char property[ZFS_MAXPROPLEN];
4407 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4408 	char errbuf[1024];
4409 
4410 	/* if we have the same exact name, just return success */
4411 	if (strcmp(zhp->zfs_name, target) == 0)
4412 		return (0);
4413 
4414 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4415 	    "cannot rename to '%s'"), target);
4416 
4417 	/* make sure source name is valid */
4418 	if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE))
4419 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4420 
4421 	/*
4422 	 * Make sure the target name is valid
4423 	 */
4424 	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
4425 		if ((strchr(target, '@') == NULL) ||
4426 		    *target == '@') {
4427 			/*
4428 			 * Snapshot target name is abbreviated,
4429 			 * reconstruct full dataset name
4430 			 */
4431 			(void) strlcpy(parent, zhp->zfs_name,
4432 			    sizeof (parent));
4433 			delim = strchr(parent, '@');
4434 			if (strchr(target, '@') == NULL)
4435 				*(++delim) = '\0';
4436 			else
4437 				*delim = '\0';
4438 			(void) strlcat(parent, target, sizeof (parent));
4439 			target = parent;
4440 		} else {
4441 			/*
4442 			 * Make sure we're renaming within the same dataset.
4443 			 */
4444 			delim = strchr(target, '@');
4445 			if (strncmp(zhp->zfs_name, target, delim - target)
4446 			    != 0 || zhp->zfs_name[delim - target] != '@') {
4447 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4448 				    "snapshots must be part of same "
4449 				    "dataset"));
4450 				return (zfs_error(hdl, EZFS_CROSSTARGET,
4451 				    errbuf));
4452 			}
4453 		}
4454 
4455 		if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
4456 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4457 	} else {
4458 		if (flags.recursive) {
4459 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4460 			    "recursive rename must be a snapshot"));
4461 			return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4462 		}
4463 
4464 		if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
4465 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4466 
4467 		/* validate parents */
4468 		if (check_parents(hdl, target, NULL, B_FALSE, NULL) != 0)
4469 			return (-1);
4470 
4471 		/* make sure we're in the same pool */
4472 		verify((delim = strchr(target, '/')) != NULL);
4473 		if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
4474 		    zhp->zfs_name[delim - target] != '/') {
4475 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4476 			    "datasets must be within same pool"));
4477 			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
4478 		}
4479 
4480 		/* new name cannot be a child of the current dataset name */
4481 		if (is_descendant(zhp->zfs_name, target)) {
4482 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4483 			    "New dataset name cannot be a descendant of "
4484 			    "current dataset name"));
4485 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4486 		}
4487 	}
4488 
4489 	(void) snprintf(errbuf, sizeof (errbuf),
4490 	    dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
4491 
4492 	if (getzoneid() == GLOBAL_ZONEID &&
4493 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
4494 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4495 		    "dataset is used in a non-global zone"));
4496 		return (zfs_error(hdl, EZFS_ZONED, errbuf));
4497 	}
4498 
4499 	/*
4500 	 * Avoid unmounting file systems with mountpoint property set to
4501 	 * 'legacy' or 'none' even if -u option is not given.
4502 	 */
4503 	if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
4504 	    !flags.recursive && !flags.nounmount &&
4505 	    zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, property,
4506 	    sizeof (property), NULL, NULL, 0, B_FALSE) == 0 &&
4507 	    (strcmp(property, "legacy") == 0 ||
4508 	    strcmp(property, "none") == 0)) {
4509 		flags.nounmount = B_TRUE;
4510 	}
4511 	if (flags.recursive) {
4512 		char *parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
4513 		if (parentname == NULL) {
4514 			ret = -1;
4515 			goto error;
4516 		}
4517 		delim = strchr(parentname, '@');
4518 		*delim = '\0';
4519 		zfs_handle_t *zhrp = zfs_open(zhp->zfs_hdl, parentname,
4520 		    ZFS_TYPE_DATASET);
4521 		free(parentname);
4522 		if (zhrp == NULL) {
4523 			ret = -1;
4524 			goto error;
4525 		}
4526 		zfs_close(zhrp);
4527 	} else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
4528 		if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
4529 		    flags.nounmount ? CL_GATHER_DONT_UNMOUNT :
4530 		    CL_GATHER_ITER_MOUNTED,
4531 		    flags.forceunmount ? MS_FORCE : 0)) == NULL)
4532 			return (-1);
4533 
4534 		if (changelist_haszonedchild(cl)) {
4535 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4536 			    "child dataset with inherited mountpoint is used "
4537 			    "in a non-global zone"));
4538 			(void) zfs_error(hdl, EZFS_ZONED, errbuf);
4539 			ret = -1;
4540 			goto error;
4541 		}
4542 
4543 		if ((ret = changelist_prefix(cl)) != 0)
4544 			goto error;
4545 	}
4546 
4547 	if (ZFS_IS_VOLUME(zhp))
4548 		zc.zc_objset_type = DMU_OST_ZVOL;
4549 	else
4550 		zc.zc_objset_type = DMU_OST_ZFS;
4551 
4552 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4553 	(void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
4554 
4555 	zc.zc_cookie = !!flags.recursive;
4556 	zc.zc_cookie |= (!!flags.nounmount) << 1;
4557 
4558 	if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
4559 		/*
4560 		 * if it was recursive, the one that actually failed will
4561 		 * be in zc.zc_name
4562 		 */
4563 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4564 		    "cannot rename '%s'"), zc.zc_name);
4565 
4566 		if (flags.recursive && errno == EEXIST) {
4567 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4568 			    "a child dataset already has a snapshot "
4569 			    "with the new name"));
4570 			(void) zfs_error(hdl, EZFS_EXISTS, errbuf);
4571 		} else if (errno == EACCES) {
4572 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4573 			    "cannot move encrypted child outside of "
4574 			    "its encryption root"));
4575 			(void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
4576 		} else {
4577 			(void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
4578 		}
4579 
4580 		/*
4581 		 * On failure, we still want to remount any filesystems that
4582 		 * were previously mounted, so we don't alter the system state.
4583 		 */
4584 		if (cl != NULL)
4585 			(void) changelist_postfix(cl);
4586 	} else {
4587 		if (cl != NULL) {
4588 			changelist_rename(cl, zfs_get_name(zhp), target);
4589 			ret = changelist_postfix(cl);
4590 		}
4591 	}
4592 
4593 error:
4594 	if (cl != NULL) {
4595 		changelist_free(cl);
4596 	}
4597 	return (ret);
4598 }
4599 
4600 nvlist_t *
4601 zfs_get_all_props(zfs_handle_t *zhp)
4602 {
4603 	return (zhp->zfs_props);
4604 }
4605 
4606 nvlist_t *
4607 zfs_get_recvd_props(zfs_handle_t *zhp)
4608 {
4609 	if (zhp->zfs_recvd_props == NULL)
4610 		if (get_recvd_props_ioctl(zhp) != 0)
4611 			return (NULL);
4612 	return (zhp->zfs_recvd_props);
4613 }
4614 
4615 nvlist_t *
4616 zfs_get_user_props(zfs_handle_t *zhp)
4617 {
4618 	return (zhp->zfs_user_props);
4619 }
4620 
4621 /*
4622  * This function is used by 'zfs list' to determine the exact set of columns to
4623  * display, and their maximum widths.  This does two main things:
4624  *
4625  *      - If this is a list of all properties, then expand the list to include
4626  *        all native properties, and set a flag so that for each dataset we look
4627  *        for new unique user properties and add them to the list.
4628  *
4629  *      - For non fixed-width properties, keep track of the maximum width seen
4630  *        so that we can size the column appropriately. If the user has
4631  *        requested received property values, we also need to compute the width
4632  *        of the RECEIVED column.
4633  */
4634 int
4635 zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received,
4636     boolean_t literal)
4637 {
4638 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4639 	zprop_list_t *entry;
4640 	zprop_list_t **last, **start;
4641 	nvlist_t *userprops, *propval;
4642 	nvpair_t *elem;
4643 	char *strval;
4644 	char buf[ZFS_MAXPROPLEN];
4645 
4646 	if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0)
4647 		return (-1);
4648 
4649 	userprops = zfs_get_user_props(zhp);
4650 
4651 	entry = *plp;
4652 	if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
4653 		/*
4654 		 * Go through and add any user properties as necessary.  We
4655 		 * start by incrementing our list pointer to the first
4656 		 * non-native property.
4657 		 */
4658 		start = plp;
4659 		while (*start != NULL) {
4660 			if ((*start)->pl_prop == ZPROP_INVAL)
4661 				break;
4662 			start = &(*start)->pl_next;
4663 		}
4664 
4665 		elem = NULL;
4666 		while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
4667 			/*
4668 			 * See if we've already found this property in our list.
4669 			 */
4670 			for (last = start; *last != NULL;
4671 			    last = &(*last)->pl_next) {
4672 				if (strcmp((*last)->pl_user_prop,
4673 				    nvpair_name(elem)) == 0)
4674 					break;
4675 			}
4676 
4677 			if (*last == NULL) {
4678 				if ((entry = zfs_alloc(hdl,
4679 				    sizeof (zprop_list_t))) == NULL ||
4680 				    ((entry->pl_user_prop = zfs_strdup(hdl,
4681 				    nvpair_name(elem)))) == NULL) {
4682 					free(entry);
4683 					return (-1);
4684 				}
4685 
4686 				entry->pl_prop = ZPROP_INVAL;
4687 				entry->pl_width = strlen(nvpair_name(elem));
4688 				entry->pl_all = B_TRUE;
4689 				*last = entry;
4690 			}
4691 		}
4692 	}
4693 
4694 	/*
4695 	 * Now go through and check the width of any non-fixed columns
4696 	 */
4697 	for (entry = *plp; entry != NULL; entry = entry->pl_next) {
4698 		if (entry->pl_fixed && !literal)
4699 			continue;
4700 
4701 		if (entry->pl_prop != ZPROP_INVAL) {
4702 			if (zfs_prop_get(zhp, entry->pl_prop,
4703 			    buf, sizeof (buf), NULL, NULL, 0, literal) == 0) {
4704 				if (strlen(buf) > entry->pl_width)
4705 					entry->pl_width = strlen(buf);
4706 			}
4707 			if (received && zfs_prop_get_recvd(zhp,
4708 			    zfs_prop_to_name(entry->pl_prop),
4709 			    buf, sizeof (buf), literal) == 0)
4710 				if (strlen(buf) > entry->pl_recvd_width)
4711 					entry->pl_recvd_width = strlen(buf);
4712 		} else {
4713 			if (nvlist_lookup_nvlist(userprops, entry->pl_user_prop,
4714 			    &propval) == 0) {
4715 				verify(nvlist_lookup_string(propval,
4716 				    ZPROP_VALUE, &strval) == 0);
4717 				if (strlen(strval) > entry->pl_width)
4718 					entry->pl_width = strlen(strval);
4719 			}
4720 			if (received && zfs_prop_get_recvd(zhp,
4721 			    entry->pl_user_prop,
4722 			    buf, sizeof (buf), literal) == 0)
4723 				if (strlen(buf) > entry->pl_recvd_width)
4724 					entry->pl_recvd_width = strlen(buf);
4725 		}
4726 	}
4727 
4728 	return (0);
4729 }
4730 
4731 void
4732 zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
4733 {
4734 	nvpair_t *curr;
4735 	nvpair_t *next;
4736 
4737 	/*
4738 	 * Keep a reference to the props-table against which we prune the
4739 	 * properties.
4740 	 */
4741 	zhp->zfs_props_table = props;
4742 
4743 	curr = nvlist_next_nvpair(zhp->zfs_props, NULL);
4744 
4745 	while (curr) {
4746 		zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
4747 		next = nvlist_next_nvpair(zhp->zfs_props, curr);
4748 
4749 		/*
4750 		 * User properties will result in ZPROP_INVAL, and since we
4751 		 * only know how to prune standard ZFS properties, we always
4752 		 * leave these in the list.  This can also happen if we
4753 		 * encounter an unknown DSL property (when running older
4754 		 * software, for example).
4755 		 */
4756 		if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE)
4757 			(void) nvlist_remove(zhp->zfs_props,
4758 			    nvpair_name(curr), nvpair_type(curr));
4759 		curr = next;
4760 	}
4761 }
4762 
4763 static int
4764 zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
4765     zfs_smb_acl_op_t cmd, char *resource1, char *resource2)
4766 {
4767 	zfs_cmd_t zc = {"\0"};
4768 	nvlist_t *nvlist = NULL;
4769 	int error;
4770 
4771 	(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4772 	(void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
4773 	zc.zc_cookie = (uint64_t)cmd;
4774 
4775 	if (cmd == ZFS_SMB_ACL_RENAME) {
4776 		if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
4777 			(void) no_memory(hdl);
4778 			return (0);
4779 		}
4780 	}
4781 
4782 	switch (cmd) {
4783 	case ZFS_SMB_ACL_ADD:
4784 	case ZFS_SMB_ACL_REMOVE:
4785 		(void) strlcpy(zc.zc_string, resource1, sizeof (zc.zc_string));
4786 		break;
4787 	case ZFS_SMB_ACL_RENAME:
4788 		if (nvlist_add_string(nvlist, ZFS_SMB_ACL_SRC,
4789 		    resource1) != 0) {
4790 				(void) no_memory(hdl);
4791 				return (-1);
4792 		}
4793 		if (nvlist_add_string(nvlist, ZFS_SMB_ACL_TARGET,
4794 		    resource2) != 0) {
4795 				(void) no_memory(hdl);
4796 				return (-1);
4797 		}
4798 		if (zcmd_write_src_nvlist(hdl, &zc, nvlist) != 0) {
4799 			nvlist_free(nvlist);
4800 			return (-1);
4801 		}
4802 		break;
4803 	case ZFS_SMB_ACL_PURGE:
4804 		break;
4805 	default:
4806 		return (-1);
4807 	}
4808 	error = ioctl(hdl->libzfs_fd, ZFS_IOC_SMB_ACL, &zc);
4809 	nvlist_free(nvlist);
4810 	return (error);
4811 }
4812 
4813 int
4814 zfs_smb_acl_add(libzfs_handle_t *hdl, char *dataset,
4815     char *path, char *resource)
4816 {
4817 	return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_ADD,
4818 	    resource, NULL));
4819 }
4820 
4821 int
4822 zfs_smb_acl_remove(libzfs_handle_t *hdl, char *dataset,
4823     char *path, char *resource)
4824 {
4825 	return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_REMOVE,
4826 	    resource, NULL));
4827 }
4828 
4829 int
4830 zfs_smb_acl_purge(libzfs_handle_t *hdl, char *dataset, char *path)
4831 {
4832 	return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_PURGE,
4833 	    NULL, NULL));
4834 }
4835 
4836 int
4837 zfs_smb_acl_rename(libzfs_handle_t *hdl, char *dataset, char *path,
4838     char *oldname, char *newname)
4839 {
4840 	return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_RENAME,
4841 	    oldname, newname));
4842 }
4843 
4844 int
4845 zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
4846     zfs_userspace_cb_t func, void *arg)
4847 {
4848 	zfs_cmd_t zc = {"\0"};
4849 	zfs_useracct_t buf[100];
4850 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4851 	int ret;
4852 
4853 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4854 
4855 	zc.zc_objset_type = type;
4856 	zc.zc_nvlist_dst = (uintptr_t)buf;
4857 
4858 	for (;;) {
4859 		zfs_useracct_t *zua = buf;
4860 
4861 		zc.zc_nvlist_dst_size = sizeof (buf);
4862 		if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) {
4863 			if ((errno == ENOTSUP &&
4864 			    (type == ZFS_PROP_USEROBJUSED ||
4865 			    type == ZFS_PROP_GROUPOBJUSED ||
4866 			    type == ZFS_PROP_USEROBJQUOTA ||
4867 			    type == ZFS_PROP_GROUPOBJQUOTA ||
4868 			    type == ZFS_PROP_PROJECTOBJUSED ||
4869 			    type == ZFS_PROP_PROJECTOBJQUOTA ||
4870 			    type == ZFS_PROP_PROJECTUSED ||
4871 			    type == ZFS_PROP_PROJECTQUOTA)))
4872 				break;
4873 
4874 			return (zfs_standard_error_fmt(hdl, errno,
4875 			    dgettext(TEXT_DOMAIN,
4876 			    "cannot get used/quota for %s"), zc.zc_name));
4877 		}
4878 		if (zc.zc_nvlist_dst_size == 0)
4879 			break;
4880 
4881 		while (zc.zc_nvlist_dst_size > 0) {
4882 			if ((ret = func(arg, zua->zu_domain, zua->zu_rid,
4883 			    zua->zu_space)) != 0)
4884 				return (ret);
4885 			zua++;
4886 			zc.zc_nvlist_dst_size -= sizeof (zfs_useracct_t);
4887 		}
4888 	}
4889 
4890 	return (0);
4891 }
4892 
4893 struct holdarg {
4894 	nvlist_t *nvl;
4895 	const char *snapname;
4896 	const char *tag;
4897 	boolean_t recursive;
4898 	int error;
4899 };
4900 
4901 static int
4902 zfs_hold_one(zfs_handle_t *zhp, void *arg)
4903 {
4904 	struct holdarg *ha = arg;
4905 	char name[ZFS_MAX_DATASET_NAME_LEN];
4906 	int rv = 0;
4907 
4908 	if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
4909 	    ha->snapname) >= sizeof (name))
4910 		return (EINVAL);
4911 
4912 	if (lzc_exists(name))
4913 		fnvlist_add_string(ha->nvl, name, ha->tag);
4914 
4915 	if (ha->recursive)
4916 		rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
4917 	zfs_close(zhp);
4918 	return (rv);
4919 }
4920 
4921 int
4922 zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
4923     boolean_t recursive, int cleanup_fd)
4924 {
4925 	int ret;
4926 	struct holdarg ha;
4927 
4928 	ha.nvl = fnvlist_alloc();
4929 	ha.snapname = snapname;
4930 	ha.tag = tag;
4931 	ha.recursive = recursive;
4932 	(void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
4933 
4934 	if (nvlist_empty(ha.nvl)) {
4935 		char errbuf[1024];
4936 
4937 		fnvlist_free(ha.nvl);
4938 		ret = ENOENT;
4939 		(void) snprintf(errbuf, sizeof (errbuf),
4940 		    dgettext(TEXT_DOMAIN,
4941 		    "cannot hold snapshot '%s@%s'"),
4942 		    zhp->zfs_name, snapname);
4943 		(void) zfs_standard_error(zhp->zfs_hdl, ret, errbuf);
4944 		return (ret);
4945 	}
4946 
4947 	ret = zfs_hold_nvl(zhp, cleanup_fd, ha.nvl);
4948 	fnvlist_free(ha.nvl);
4949 
4950 	return (ret);
4951 }
4952 
4953 int
4954 zfs_hold_nvl(zfs_handle_t *zhp, int cleanup_fd, nvlist_t *holds)
4955 {
4956 	int ret;
4957 	nvlist_t *errors;
4958 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4959 	char errbuf[1024];
4960 	nvpair_t *elem;
4961 
4962 	errors = NULL;
4963 	ret = lzc_hold(holds, cleanup_fd, &errors);
4964 
4965 	if (ret == 0) {
4966 		/* There may be errors even in the success case. */
4967 		fnvlist_free(errors);
4968 		return (0);
4969 	}
4970 
4971 	if (nvlist_empty(errors)) {
4972 		/* no hold-specific errors */
4973 		(void) snprintf(errbuf, sizeof (errbuf),
4974 		    dgettext(TEXT_DOMAIN, "cannot hold"));
4975 		switch (ret) {
4976 		case ENOTSUP:
4977 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4978 			    "pool must be upgraded"));
4979 			(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4980 			break;
4981 		case EINVAL:
4982 			(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4983 			break;
4984 		default:
4985 			(void) zfs_standard_error(hdl, ret, errbuf);
4986 		}
4987 	}
4988 
4989 	for (elem = nvlist_next_nvpair(errors, NULL);
4990 	    elem != NULL;
4991 	    elem = nvlist_next_nvpair(errors, elem)) {
4992 		(void) snprintf(errbuf, sizeof (errbuf),
4993 		    dgettext(TEXT_DOMAIN,
4994 		    "cannot hold snapshot '%s'"), nvpair_name(elem));
4995 		switch (fnvpair_value_int32(elem)) {
4996 		case E2BIG:
4997 			/*
4998 			 * Temporary tags wind up having the ds object id
4999 			 * prepended. So even if we passed the length check
5000 			 * above, it's still possible for the tag to wind
5001 			 * up being slightly too long.
5002 			 */
5003 			(void) zfs_error(hdl, EZFS_TAGTOOLONG, errbuf);
5004 			break;
5005 		case EINVAL:
5006 			(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
5007 			break;
5008 		case EEXIST:
5009 			(void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf);
5010 			break;
5011 		default:
5012 			(void) zfs_standard_error(hdl,
5013 			    fnvpair_value_int32(elem), errbuf);
5014 		}
5015 	}
5016 
5017 	fnvlist_free(errors);
5018 	return (ret);
5019 }
5020 
5021 static int
5022 zfs_release_one(zfs_handle_t *zhp, void *arg)
5023 {
5024 	struct holdarg *ha = arg;
5025 	char name[ZFS_MAX_DATASET_NAME_LEN];
5026 	int rv = 0;
5027 	nvlist_t *existing_holds;
5028 
5029 	if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
5030 	    ha->snapname) >= sizeof (name)) {
5031 		ha->error = EINVAL;
5032 		rv = EINVAL;
5033 	}
5034 
5035 	if (lzc_get_holds(name, &existing_holds) != 0) {
5036 		ha->error = ENOENT;
5037 	} else if (!nvlist_exists(existing_holds, ha->tag)) {
5038 		ha->error = ESRCH;
5039 	} else {
5040 		nvlist_t *torelease = fnvlist_alloc();
5041 		fnvlist_add_boolean(torelease, ha->tag);
5042 		fnvlist_add_nvlist(ha->nvl, name, torelease);
5043 		fnvlist_free(torelease);
5044 	}
5045 
5046 	if (ha->recursive)
5047 		rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
5048 	zfs_close(zhp);
5049 	return (rv);
5050 }
5051 
5052 int
5053 zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
5054     boolean_t recursive)
5055 {
5056 	int ret;
5057 	struct holdarg ha;
5058 	nvlist_t *errors = NULL;
5059 	nvpair_t *elem;
5060 	libzfs_handle_t *hdl = zhp->zfs_hdl;
5061 	char errbuf[1024];
5062 
5063 	ha.nvl = fnvlist_alloc();
5064 	ha.snapname = snapname;
5065 	ha.tag = tag;
5066 	ha.recursive = recursive;
5067 	ha.error = 0;
5068 	(void) zfs_release_one(zfs_handle_dup(zhp), &ha);
5069 
5070 	if (nvlist_empty(ha.nvl)) {
5071 		fnvlist_free(ha.nvl);
5072 		ret = ha.error;
5073 		(void) snprintf(errbuf, sizeof (errbuf),
5074 		    dgettext(TEXT_DOMAIN,
5075 		    "cannot release hold from snapshot '%s@%s'"),
5076 		    zhp->zfs_name, snapname);
5077 		if (ret == ESRCH) {
5078 			(void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
5079 		} else {
5080 			(void) zfs_standard_error(hdl, ret, errbuf);
5081 		}
5082 		return (ret);
5083 	}
5084 
5085 	ret = lzc_release(ha.nvl, &errors);
5086 	fnvlist_free(ha.nvl);
5087 
5088 	if (ret == 0) {
5089 		/* There may be errors even in the success case. */
5090 		fnvlist_free(errors);
5091 		return (0);
5092 	}
5093 
5094 	if (nvlist_empty(errors)) {
5095 		/* no hold-specific errors */
5096 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
5097 		    "cannot release"));
5098 		switch (errno) {
5099 		case ENOTSUP:
5100 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5101 			    "pool must be upgraded"));
5102 			(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
5103 			break;
5104 		default:
5105 			(void) zfs_standard_error(hdl, errno, errbuf);
5106 		}
5107 	}
5108 
5109 	for (elem = nvlist_next_nvpair(errors, NULL);
5110 	    elem != NULL;
5111 	    elem = nvlist_next_nvpair(errors, elem)) {
5112 		(void) snprintf(errbuf, sizeof (errbuf),
5113 		    dgettext(TEXT_DOMAIN,
5114 		    "cannot release hold from snapshot '%s'"),
5115 		    nvpair_name(elem));
5116 		switch (fnvpair_value_int32(elem)) {
5117 		case ESRCH:
5118 			(void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
5119 			break;
5120 		case EINVAL:
5121 			(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
5122 			break;
5123 		default:
5124 			(void) zfs_standard_error(hdl,
5125 			    fnvpair_value_int32(elem), errbuf);
5126 		}
5127 	}
5128 
5129 	fnvlist_free(errors);
5130 	return (ret);
5131 }
5132 
5133 int
5134 zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl)
5135 {
5136 	zfs_cmd_t zc = {"\0"};
5137 	libzfs_handle_t *hdl = zhp->zfs_hdl;
5138 	int nvsz = 2048;
5139 	void *nvbuf;
5140 	int err = 0;
5141 	char errbuf[1024];
5142 
5143 	assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
5144 	    zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
5145 
5146 tryagain:
5147 
5148 	nvbuf = malloc(nvsz);
5149 	if (nvbuf == NULL) {
5150 		err = (zfs_error(hdl, EZFS_NOMEM, strerror(errno)));
5151 		goto out;
5152 	}
5153 
5154 	zc.zc_nvlist_dst_size = nvsz;
5155 	zc.zc_nvlist_dst = (uintptr_t)nvbuf;
5156 
5157 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
5158 
5159 	if (zfs_ioctl(hdl, ZFS_IOC_GET_FSACL, &zc) != 0) {
5160 		(void) snprintf(errbuf, sizeof (errbuf),
5161 		    dgettext(TEXT_DOMAIN, "cannot get permissions on '%s'"),
5162 		    zc.zc_name);
5163 		switch (errno) {
5164 		case ENOMEM:
5165 			free(nvbuf);
5166 			nvsz = zc.zc_nvlist_dst_size;
5167 			goto tryagain;
5168 
5169 		case ENOTSUP:
5170 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5171 			    "pool must be upgraded"));
5172 			err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
5173 			break;
5174 		case EINVAL:
5175 			err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
5176 			break;
5177 		case ENOENT:
5178 			err = zfs_error(hdl, EZFS_NOENT, errbuf);
5179 			break;
5180 		default:
5181 			err = zfs_standard_error(hdl, errno, errbuf);
5182 			break;
5183 		}
5184 	} else {
5185 		/* success */
5186 		int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0);
5187 		if (rc) {
5188 			err = zfs_standard_error_fmt(hdl, rc, dgettext(
5189 			    TEXT_DOMAIN, "cannot get permissions on '%s'"),
5190 			    zc.zc_name);
5191 		}
5192 	}
5193 
5194 	free(nvbuf);
5195 out:
5196 	return (err);
5197 }
5198 
5199 int
5200 zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
5201 {
5202 	zfs_cmd_t zc = {"\0"};
5203 	libzfs_handle_t *hdl = zhp->zfs_hdl;
5204 	char *nvbuf;
5205 	char errbuf[1024];
5206 	size_t nvsz;
5207 	int err;
5208 
5209 	assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
5210 	    zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
5211 
5212 	err = nvlist_size(nvl, &nvsz, NV_ENCODE_NATIVE);
5213 	assert(err == 0);
5214 
5215 	nvbuf = malloc(nvsz);
5216 
5217 	err = nvlist_pack(nvl, &nvbuf, &nvsz, NV_ENCODE_NATIVE, 0);
5218 	assert(err == 0);
5219 
5220 	zc.zc_nvlist_src_size = nvsz;
5221 	zc.zc_nvlist_src = (uintptr_t)nvbuf;
5222 	zc.zc_perm_action = un;
5223 
5224 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
5225 
5226 	if (zfs_ioctl(hdl, ZFS_IOC_SET_FSACL, &zc) != 0) {
5227 		(void) snprintf(errbuf, sizeof (errbuf),
5228 		    dgettext(TEXT_DOMAIN, "cannot set permissions on '%s'"),
5229 		    zc.zc_name);
5230 		switch (errno) {
5231 		case ENOTSUP:
5232 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5233 			    "pool must be upgraded"));
5234 			err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
5235 			break;
5236 		case EINVAL:
5237 			err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
5238 			break;
5239 		case ENOENT:
5240 			err = zfs_error(hdl, EZFS_NOENT, errbuf);
5241 			break;
5242 		default:
5243 			err = zfs_standard_error(hdl, errno, errbuf);
5244 			break;
5245 		}
5246 	}
5247 
5248 	free(nvbuf);
5249 
5250 	return (err);
5251 }
5252 
5253 int
5254 zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl)
5255 {
5256 	int err;
5257 	char errbuf[1024];
5258 
5259 	err = lzc_get_holds(zhp->zfs_name, nvl);
5260 
5261 	if (err != 0) {
5262 		libzfs_handle_t *hdl = zhp->zfs_hdl;
5263 
5264 		(void) snprintf(errbuf, sizeof (errbuf),
5265 		    dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
5266 		    zhp->zfs_name);
5267 		switch (err) {
5268 		case ENOTSUP:
5269 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5270 			    "pool must be upgraded"));
5271 			err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
5272 			break;
5273 		case EINVAL:
5274 			err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
5275 			break;
5276 		case ENOENT:
5277 			err = zfs_error(hdl, EZFS_NOENT, errbuf);
5278 			break;
5279 		default:
5280 			err = zfs_standard_error(hdl, errno, errbuf);
5281 			break;
5282 		}
5283 	}
5284 
5285 	return (err);
5286 }
5287 
5288 /*
5289  * The theory of raidz space accounting
5290  *
5291  * The "referenced" property of RAIDZ vdevs is scaled such that a 128KB block
5292  * will "reference" 128KB, even though it allocates more than that, to store the
5293  * parity information (and perhaps skip sectors). This concept of the
5294  * "referenced" (and other DMU space accounting) being lower than the allocated
5295  * space by a constant factor is called "raidz deflation."
5296  *
5297  * As mentioned above, the constant factor for raidz deflation assumes a 128KB
5298  * block size. However, zvols typically have a much smaller block size (default
5299  * 8KB). These smaller blocks may require proportionally much more parity
5300  * information (and perhaps skip sectors). In this case, the change to the
5301  * "referenced" property may be much more than the logical block size.
5302  *
5303  * Suppose a raidz vdev has 5 disks with ashift=12.  A 128k block may be written
5304  * as follows.
5305  *
5306  * +-------+-------+-------+-------+-------+
5307  * | disk1 | disk2 | disk3 | disk4 | disk5 |
5308  * +-------+-------+-------+-------+-------+
5309  * |  P0   |  D0   |  D8   |  D16  |  D24  |
5310  * |  P1   |  D1   |  D9   |  D17  |  D25  |
5311  * |  P2   |  D2   |  D10  |  D18  |  D26  |
5312  * |  P3   |  D3   |  D11  |  D19  |  D27  |
5313  * |  P4   |  D4   |  D12  |  D20  |  D28  |
5314  * |  P5   |  D5   |  D13  |  D21  |  D29  |
5315  * |  P6   |  D6   |  D14  |  D22  |  D30  |
5316  * |  P7   |  D7   |  D15  |  D23  |  D31  |
5317  * +-------+-------+-------+-------+-------+
5318  *
5319  * Above, notice that 160k was allocated: 8 x 4k parity sectors + 32 x 4k data
5320  * sectors.  The dataset's referenced will increase by 128k and the pool's
5321  * allocated and free properties will be adjusted by 160k.
5322  *
5323  * A 4k block written to the same raidz vdev will require two 4k sectors.  The
5324  * blank cells represent unallocated space.
5325  *
5326  * +-------+-------+-------+-------+-------+
5327  * | disk1 | disk2 | disk3 | disk4 | disk5 |
5328  * +-------+-------+-------+-------+-------+
5329  * |  P0   |  D0   |       |       |       |
5330  * +-------+-------+-------+-------+-------+
5331  *
5332  * Above, notice that the 4k block required one sector for parity and another
5333  * for data.  vdev_raidz_asize() will return 8k and as such the pool's allocated
5334  * and free properties will be adjusted by 8k.  The dataset will not be charged
5335  * 8k.  Rather, it will be charged a value that is scaled according to the
5336  * overhead of the 128k block on the same vdev.  This 8k allocation will be
5337  * charged 8k * 128k / 160k.  128k is from SPA_OLD_MAXBLOCKSIZE and 160k is as
5338  * calculated in the 128k block example above.
5339  *
5340  * Every raidz allocation is sized to be a multiple of nparity+1 sectors.  That
5341  * is, every raidz1 allocation will be a multiple of 2 sectors, raidz2
5342  * allocations are a multiple of 3 sectors, and raidz3 allocations are a
5343  * multiple of of 4 sectors.  When a block does not fill the required number of
5344  * sectors, skip blocks (sectors) are used.
5345  *
5346  * An 8k block being written to a raidz vdev may be written as follows:
5347  *
5348  * +-------+-------+-------+-------+-------+
5349  * | disk1 | disk2 | disk3 | disk4 | disk5 |
5350  * +-------+-------+-------+-------+-------+
5351  * |  P0   |  D0   |  D1   |  S0   |       |
5352  * +-------+-------+-------+-------+-------+
5353  *
5354  * In order to maintain the nparity+1 allocation size, a skip block (S0) was
5355  * added.  For this 8k block, the pool's allocated and free properties are
5356  * adjusted by 16k and the dataset's referenced is increased by 16k * 128k /
5357  * 160k.  Again, 128k is from SPA_OLD_MAXBLOCKSIZE and 160k is as calculated in
5358  * the 128k block example above.
5359  *
5360  * The situation is slightly different for dRAID since the minimum allocation
5361  * size is the full group width.  The same 8K block above would be written as
5362  * follows in a dRAID group:
5363  *
5364  * +-------+-------+-------+-------+-------+
5365  * | disk1 | disk2 | disk3 | disk4 | disk5 |
5366  * +-------+-------+-------+-------+-------+
5367  * |  P0   |  D0   |  D1   |  S0   |  S1   |
5368  * +-------+-------+-------+-------+-------+
5369  *
5370  * Compression may lead to a variety of block sizes being written for the same
5371  * volume or file.  There is no clear way to reserve just the amount of space
5372  * that will be required, so the worst case (no compression) is assumed.
5373  * Note that metadata blocks will typically be compressed, so the reservation
5374  * size returned by zvol_volsize_to_reservation() will generally be slightly
5375  * larger than the maximum that the volume can reference.
5376  */
5377 
5378 /*
5379  * Derived from function of same name in module/zfs/vdev_raidz.c.  Returns the
5380  * amount of space (in bytes) that will be allocated for the specified block
5381  * size. Note that the "referenced" space accounted will be less than this, but
5382  * not necessarily equal to "blksize", due to RAIDZ deflation.
5383  */
5384 static uint64_t
5385 vdev_raidz_asize(uint64_t ndisks, uint64_t nparity, uint64_t ashift,
5386     uint64_t blksize)
5387 {
5388 	uint64_t asize, ndata;
5389 
5390 	ASSERT3U(ndisks, >, nparity);
5391 	ndata = ndisks - nparity;
5392 	asize = ((blksize - 1) >> ashift) + 1;
5393 	asize += nparity * ((asize + ndata - 1) / ndata);
5394 	asize = roundup(asize, nparity + 1) << ashift;
5395 
5396 	return (asize);
5397 }
5398 
5399 /*
5400  * Derived from function of same name in module/zfs/vdev_draid.c.  Returns the
5401  * amount of space (in bytes) that will be allocated for the specified block
5402  * size.
5403  */
5404 static uint64_t
5405 vdev_draid_asize(uint64_t ndisks, uint64_t nparity, uint64_t ashift,
5406     uint64_t blksize)
5407 {
5408 	ASSERT3U(ndisks, >, nparity);
5409 	uint64_t ndata = ndisks - nparity;
5410 	uint64_t rows = ((blksize - 1) / (ndata << ashift)) + 1;
5411 	uint64_t asize = (rows * ndisks) << ashift;
5412 
5413 	return (asize);
5414 }
5415 
5416 /*
5417  * Determine how much space will be allocated if it lands on the most space-
5418  * inefficient top-level vdev.  Returns the size in bytes required to store one
5419  * copy of the volume data.  See theory comment above.
5420  */
5421 static uint64_t
5422 volsize_from_vdevs(zpool_handle_t *zhp, uint64_t nblocks, uint64_t blksize)
5423 {
5424 	nvlist_t *config, *tree, **vdevs;
5425 	uint_t nvdevs;
5426 	uint64_t ret = 0;
5427 
5428 	config = zpool_get_config(zhp, NULL);
5429 	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &tree) != 0 ||
5430 	    nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN,
5431 	    &vdevs, &nvdevs) != 0) {
5432 		return (nblocks * blksize);
5433 	}
5434 
5435 	for (int v = 0; v < nvdevs; v++) {
5436 		char *type;
5437 		uint64_t nparity, ashift, asize, tsize;
5438 		uint64_t volsize;
5439 
5440 		if (nvlist_lookup_string(vdevs[v], ZPOOL_CONFIG_TYPE,
5441 		    &type) != 0)
5442 			continue;
5443 
5444 		if (strcmp(type, VDEV_TYPE_RAIDZ) != 0 &&
5445 		    strcmp(type, VDEV_TYPE_DRAID) != 0)
5446 			continue;
5447 
5448 		if (nvlist_lookup_uint64(vdevs[v],
5449 		    ZPOOL_CONFIG_NPARITY, &nparity) != 0)
5450 			continue;
5451 
5452 		if (nvlist_lookup_uint64(vdevs[v],
5453 		    ZPOOL_CONFIG_ASHIFT, &ashift) != 0)
5454 			continue;
5455 
5456 		if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
5457 			nvlist_t **disks;
5458 			uint_t ndisks;
5459 
5460 			if (nvlist_lookup_nvlist_array(vdevs[v],
5461 			    ZPOOL_CONFIG_CHILDREN, &disks, &ndisks) != 0)
5462 				continue;
5463 
5464 			/* allocation size for the "typical" 128k block */
5465 			tsize = vdev_raidz_asize(ndisks, nparity, ashift,
5466 			    SPA_OLD_MAXBLOCKSIZE);
5467 
5468 			/* allocation size for the blksize block */
5469 			asize = vdev_raidz_asize(ndisks, nparity, ashift,
5470 			    blksize);
5471 		} else {
5472 			uint64_t ndata;
5473 
5474 			if (nvlist_lookup_uint64(vdevs[v],
5475 			    ZPOOL_CONFIG_DRAID_NDATA, &ndata) != 0)
5476 				continue;
5477 
5478 			/* allocation size for the "typical" 128k block */
5479 			tsize = vdev_draid_asize(ndata + nparity, nparity,
5480 			    ashift, SPA_OLD_MAXBLOCKSIZE);
5481 
5482 			/* allocation size for the blksize block */
5483 			asize = vdev_draid_asize(ndata + nparity, nparity,
5484 			    ashift, blksize);
5485 		}
5486 
5487 		/*
5488 		 * Scale this size down as a ratio of 128k / tsize.
5489 		 * See theory statement above.
5490 		 */
5491 		volsize = nblocks * asize * SPA_OLD_MAXBLOCKSIZE / tsize;
5492 		if (volsize > ret) {
5493 			ret = volsize;
5494 		}
5495 	}
5496 
5497 	if (ret == 0) {
5498 		ret = nblocks * blksize;
5499 	}
5500 
5501 	return (ret);
5502 }
5503 
5504 /*
5505  * Convert the zvol's volume size to an appropriate reservation.  See theory
5506  * comment above.
5507  *
5508  * Note: If this routine is updated, it is necessary to update the ZFS test
5509  * suite's shell version in reservation.shlib.
5510  */
5511 uint64_t
5512 zvol_volsize_to_reservation(zpool_handle_t *zph, uint64_t volsize,
5513     nvlist_t *props)
5514 {
5515 	uint64_t numdb;
5516 	uint64_t nblocks, volblocksize;
5517 	int ncopies;
5518 	char *strval;
5519 
5520 	if (nvlist_lookup_string(props,
5521 	    zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)
5522 		ncopies = atoi(strval);
5523 	else
5524 		ncopies = 1;
5525 	if (nvlist_lookup_uint64(props,
5526 	    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
5527 	    &volblocksize) != 0)
5528 		volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
5529 
5530 	nblocks = volsize / volblocksize;
5531 	/*
5532 	 * Metadata defaults to using 128k blocks, not volblocksize blocks.  For
5533 	 * this reason, only the data blocks are scaled based on vdev config.
5534 	 */
5535 	volsize = volsize_from_vdevs(zph, nblocks, volblocksize);
5536 
5537 	/* start with metadnode L0-L6 */
5538 	numdb = 7;
5539 	/* calculate number of indirects */
5540 	while (nblocks > 1) {
5541 		nblocks += DNODES_PER_LEVEL - 1;
5542 		nblocks /= DNODES_PER_LEVEL;
5543 		numdb += nblocks;
5544 	}
5545 	numdb *= MIN(SPA_DVAS_PER_BP, ncopies + 1);
5546 	volsize *= ncopies;
5547 	/*
5548 	 * this is exactly DN_MAX_INDBLKSHIFT when metadata isn't
5549 	 * compressed, but in practice they compress down to about
5550 	 * 1100 bytes
5551 	 */
5552 	numdb *= 1ULL << DN_MAX_INDBLKSHIFT;
5553 	volsize += numdb;
5554 	return (volsize);
5555 }
5556 
5557 /*
5558  * Wait for the given activity and return the status of the wait (whether or not
5559  * any waiting was done) in the 'waited' parameter. Non-existent fses are
5560  * reported via the 'missing' parameter, rather than by printing an error
5561  * message. This is convenient when this function is called in a loop over a
5562  * long period of time (as it is, for example, by zfs's wait cmd). In that
5563  * scenario, a fs being exported or destroyed should be considered a normal
5564  * event, so we don't want to print an error when we find that the fs doesn't
5565  * exist.
5566  */
5567 int
5568 zfs_wait_status(zfs_handle_t *zhp, zfs_wait_activity_t activity,
5569     boolean_t *missing, boolean_t *waited)
5570 {
5571 	int error = lzc_wait_fs(zhp->zfs_name, activity, waited);
5572 	*missing = (error == ENOENT);
5573 	if (*missing)
5574 		return (0);
5575 
5576 	if (error != 0) {
5577 		(void) zfs_standard_error_fmt(zhp->zfs_hdl, error,
5578 		    dgettext(TEXT_DOMAIN, "error waiting in fs '%s'"),
5579 		    zhp->zfs_name);
5580 	}
5581 
5582 	return (error);
5583 }
5584