xref: /titanic_51/usr/src/lib/libzfs/common/libzfs_dataset.c (revision 8cd81a20c40b49e1fad4022a2774ec6ad5066532)
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 (c) 2013 by Delphix. All rights reserved.
25  * Copyright (c) 2012 DEY Storage Systems, Inc.  All rights reserved.
26  * Copyright (c) 2013 Martin Matuska. All rights reserved.
27  * Copyright (c) 2013 Steven Hartland. All rights reserved.
28  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
29  */
30 
31 #include <ctype.h>
32 #include <errno.h>
33 #include <libintl.h>
34 #include <math.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <strings.h>
38 #include <unistd.h>
39 #include <stddef.h>
40 #include <zone.h>
41 #include <fcntl.h>
42 #include <sys/mntent.h>
43 #include <sys/mount.h>
44 #include <priv.h>
45 #include <pwd.h>
46 #include <grp.h>
47 #include <stddef.h>
48 #include <ucred.h>
49 #include <idmap.h>
50 #include <aclutils.h>
51 #include <directory.h>
52 
53 #include <sys/dnode.h>
54 #include <sys/spa.h>
55 #include <sys/zap.h>
56 #include <libzfs.h>
57 
58 #include "zfs_namecheck.h"
59 #include "zfs_prop.h"
60 #include "libzfs_impl.h"
61 #include "zfs_deleg.h"
62 
63 static int userquota_propname_decode(const char *propname, boolean_t zoned,
64     zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
65 
66 /*
67  * Given a single type (not a mask of types), return the type in a human
68  * readable form.
69  */
70 const char *
71 zfs_type_to_name(zfs_type_t type)
72 {
73 	switch (type) {
74 	case ZFS_TYPE_FILESYSTEM:
75 		return (dgettext(TEXT_DOMAIN, "filesystem"));
76 	case ZFS_TYPE_SNAPSHOT:
77 		return (dgettext(TEXT_DOMAIN, "snapshot"));
78 	case ZFS_TYPE_VOLUME:
79 		return (dgettext(TEXT_DOMAIN, "volume"));
80 	}
81 
82 	return (NULL);
83 }
84 
85 /*
86  * Given a path and mask of ZFS types, return a string describing this dataset.
87  * This is used when we fail to open a dataset and we cannot get an exact type.
88  * We guess what the type would have been based on the path and the mask of
89  * acceptable types.
90  */
91 static const char *
92 path_to_str(const char *path, int types)
93 {
94 	/*
95 	 * When given a single type, always report the exact type.
96 	 */
97 	if (types == ZFS_TYPE_SNAPSHOT)
98 		return (dgettext(TEXT_DOMAIN, "snapshot"));
99 	if (types == ZFS_TYPE_FILESYSTEM)
100 		return (dgettext(TEXT_DOMAIN, "filesystem"));
101 	if (types == ZFS_TYPE_VOLUME)
102 		return (dgettext(TEXT_DOMAIN, "volume"));
103 
104 	/*
105 	 * The user is requesting more than one type of dataset.  If this is the
106 	 * case, consult the path itself.  If we're looking for a snapshot, and
107 	 * a '@' is found, then report it as "snapshot".  Otherwise, remove the
108 	 * snapshot attribute and try again.
109 	 */
110 	if (types & ZFS_TYPE_SNAPSHOT) {
111 		if (strchr(path, '@') != NULL)
112 			return (dgettext(TEXT_DOMAIN, "snapshot"));
113 		return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT));
114 	}
115 
116 	/*
117 	 * The user has requested either filesystems or volumes.
118 	 * We have no way of knowing a priori what type this would be, so always
119 	 * report it as "filesystem" or "volume", our two primitive types.
120 	 */
121 	if (types & ZFS_TYPE_FILESYSTEM)
122 		return (dgettext(TEXT_DOMAIN, "filesystem"));
123 
124 	assert(types & ZFS_TYPE_VOLUME);
125 	return (dgettext(TEXT_DOMAIN, "volume"));
126 }
127 
128 /*
129  * Validate a ZFS path.  This is used even before trying to open the dataset, to
130  * provide a more meaningful error message.  We call zfs_error_aux() to
131  * explain exactly why the name was not valid.
132  */
133 int
134 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
135     boolean_t modifying)
136 {
137 	namecheck_err_t why;
138 	char what;
139 
140 	(void) zfs_prop_get_table();
141 	if (dataset_namecheck(path, &why, &what) != 0) {
142 		if (hdl != NULL) {
143 			switch (why) {
144 			case NAME_ERR_TOOLONG:
145 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
146 				    "name is too long"));
147 				break;
148 
149 			case NAME_ERR_LEADING_SLASH:
150 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
151 				    "leading slash in name"));
152 				break;
153 
154 			case NAME_ERR_EMPTY_COMPONENT:
155 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
156 				    "empty component in name"));
157 				break;
158 
159 			case NAME_ERR_TRAILING_SLASH:
160 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
161 				    "trailing slash in name"));
162 				break;
163 
164 			case NAME_ERR_INVALCHAR:
165 				zfs_error_aux(hdl,
166 				    dgettext(TEXT_DOMAIN, "invalid character "
167 				    "'%c' in name"), what);
168 				break;
169 
170 			case NAME_ERR_MULTIPLE_AT:
171 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
172 				    "multiple '@' delimiters in name"));
173 				break;
174 
175 			case NAME_ERR_NOLETTER:
176 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
177 				    "pool doesn't begin with a letter"));
178 				break;
179 
180 			case NAME_ERR_RESERVED:
181 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
182 				    "name is reserved"));
183 				break;
184 
185 			case NAME_ERR_DISKLIKE:
186 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
187 				    "reserved disk name"));
188 				break;
189 			}
190 		}
191 
192 		return (0);
193 	}
194 
195 	if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
196 		if (hdl != NULL)
197 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
198 			    "snapshot delimiter '@' in filesystem name"));
199 		return (0);
200 	}
201 
202 	if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) {
203 		if (hdl != NULL)
204 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
205 			    "missing '@' delimiter in snapshot name"));
206 		return (0);
207 	}
208 
209 	if (modifying && strchr(path, '%') != NULL) {
210 		if (hdl != NULL)
211 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
212 			    "invalid character %c in name"), '%');
213 		return (0);
214 	}
215 
216 	return (-1);
217 }
218 
219 int
220 zfs_name_valid(const char *name, zfs_type_t type)
221 {
222 	if (type == ZFS_TYPE_POOL)
223 		return (zpool_name_valid(NULL, B_FALSE, name));
224 	return (zfs_validate_name(NULL, name, type, B_FALSE));
225 }
226 
227 /*
228  * This function takes the raw DSL properties, and filters out the user-defined
229  * properties into a separate nvlist.
230  */
231 static nvlist_t *
232 process_user_props(zfs_handle_t *zhp, nvlist_t *props)
233 {
234 	libzfs_handle_t *hdl = zhp->zfs_hdl;
235 	nvpair_t *elem;
236 	nvlist_t *propval;
237 	nvlist_t *nvl;
238 
239 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
240 		(void) no_memory(hdl);
241 		return (NULL);
242 	}
243 
244 	elem = NULL;
245 	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
246 		if (!zfs_prop_user(nvpair_name(elem)))
247 			continue;
248 
249 		verify(nvpair_value_nvlist(elem, &propval) == 0);
250 		if (nvlist_add_nvlist(nvl, nvpair_name(elem), propval) != 0) {
251 			nvlist_free(nvl);
252 			(void) no_memory(hdl);
253 			return (NULL);
254 		}
255 	}
256 
257 	return (nvl);
258 }
259 
260 static zpool_handle_t *
261 zpool_add_handle(zfs_handle_t *zhp, const char *pool_name)
262 {
263 	libzfs_handle_t *hdl = zhp->zfs_hdl;
264 	zpool_handle_t *zph;
265 
266 	if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) {
267 		if (hdl->libzfs_pool_handles != NULL)
268 			zph->zpool_next = hdl->libzfs_pool_handles;
269 		hdl->libzfs_pool_handles = zph;
270 	}
271 	return (zph);
272 }
273 
274 static zpool_handle_t *
275 zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len)
276 {
277 	libzfs_handle_t *hdl = zhp->zfs_hdl;
278 	zpool_handle_t *zph = hdl->libzfs_pool_handles;
279 
280 	while ((zph != NULL) &&
281 	    (strncmp(pool_name, zpool_get_name(zph), len) != 0))
282 		zph = zph->zpool_next;
283 	return (zph);
284 }
285 
286 /*
287  * Returns a handle to the pool that contains the provided dataset.
288  * If a handle to that pool already exists then that handle is returned.
289  * Otherwise, a new handle is created and added to the list of handles.
290  */
291 static zpool_handle_t *
292 zpool_handle(zfs_handle_t *zhp)
293 {
294 	char *pool_name;
295 	int len;
296 	zpool_handle_t *zph;
297 
298 	len = strcspn(zhp->zfs_name, "/@#") + 1;
299 	pool_name = zfs_alloc(zhp->zfs_hdl, len);
300 	(void) strlcpy(pool_name, zhp->zfs_name, len);
301 
302 	zph = zpool_find_handle(zhp, pool_name, len);
303 	if (zph == NULL)
304 		zph = zpool_add_handle(zhp, pool_name);
305 
306 	free(pool_name);
307 	return (zph);
308 }
309 
310 void
311 zpool_free_handles(libzfs_handle_t *hdl)
312 {
313 	zpool_handle_t *next, *zph = hdl->libzfs_pool_handles;
314 
315 	while (zph != NULL) {
316 		next = zph->zpool_next;
317 		zpool_close(zph);
318 		zph = next;
319 	}
320 	hdl->libzfs_pool_handles = NULL;
321 }
322 
323 /*
324  * Utility function to gather stats (objset and zpl) for the given object.
325  */
326 static int
327 get_stats_ioctl(zfs_handle_t *zhp, zfs_cmd_t *zc)
328 {
329 	libzfs_handle_t *hdl = zhp->zfs_hdl;
330 
331 	(void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
332 
333 	while (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, zc) != 0) {
334 		if (errno == ENOMEM) {
335 			if (zcmd_expand_dst_nvlist(hdl, zc) != 0) {
336 				return (-1);
337 			}
338 		} else {
339 			return (-1);
340 		}
341 	}
342 	return (0);
343 }
344 
345 /*
346  * Utility function to get the received properties of the given object.
347  */
348 static int
349 get_recvd_props_ioctl(zfs_handle_t *zhp)
350 {
351 	libzfs_handle_t *hdl = zhp->zfs_hdl;
352 	nvlist_t *recvdprops;
353 	zfs_cmd_t zc = { 0 };
354 	int err;
355 
356 	if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
357 		return (-1);
358 
359 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
360 
361 	while (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_RECVD_PROPS, &zc) != 0) {
362 		if (errno == ENOMEM) {
363 			if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
364 				return (-1);
365 			}
366 		} else {
367 			zcmd_free_nvlists(&zc);
368 			return (-1);
369 		}
370 	}
371 
372 	err = zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &recvdprops);
373 	zcmd_free_nvlists(&zc);
374 	if (err != 0)
375 		return (-1);
376 
377 	nvlist_free(zhp->zfs_recvd_props);
378 	zhp->zfs_recvd_props = recvdprops;
379 
380 	return (0);
381 }
382 
383 static int
384 put_stats_zhdl(zfs_handle_t *zhp, zfs_cmd_t *zc)
385 {
386 	nvlist_t *allprops, *userprops;
387 
388 	zhp->zfs_dmustats = zc->zc_objset_stats; /* structure assignment */
389 
390 	if (zcmd_read_dst_nvlist(zhp->zfs_hdl, zc, &allprops) != 0) {
391 		return (-1);
392 	}
393 
394 	/*
395 	 * XXX Why do we store the user props separately, in addition to
396 	 * storing them in zfs_props?
397 	 */
398 	if ((userprops = process_user_props(zhp, allprops)) == NULL) {
399 		nvlist_free(allprops);
400 		return (-1);
401 	}
402 
403 	nvlist_free(zhp->zfs_props);
404 	nvlist_free(zhp->zfs_user_props);
405 
406 	zhp->zfs_props = allprops;
407 	zhp->zfs_user_props = userprops;
408 
409 	return (0);
410 }
411 
412 static int
413 get_stats(zfs_handle_t *zhp)
414 {
415 	int rc = 0;
416 	zfs_cmd_t zc = { 0 };
417 
418 	if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
419 		return (-1);
420 	if (get_stats_ioctl(zhp, &zc) != 0)
421 		rc = -1;
422 	else if (put_stats_zhdl(zhp, &zc) != 0)
423 		rc = -1;
424 	zcmd_free_nvlists(&zc);
425 	return (rc);
426 }
427 
428 /*
429  * Refresh the properties currently stored in the handle.
430  */
431 void
432 zfs_refresh_properties(zfs_handle_t *zhp)
433 {
434 	(void) get_stats(zhp);
435 }
436 
437 /*
438  * Makes a handle from the given dataset name.  Used by zfs_open() and
439  * zfs_iter_* to create child handles on the fly.
440  */
441 static int
442 make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
443 {
444 	if (put_stats_zhdl(zhp, zc) != 0)
445 		return (-1);
446 
447 	/*
448 	 * We've managed to open the dataset and gather statistics.  Determine
449 	 * the high-level type.
450 	 */
451 	if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
452 		zhp->zfs_head_type = ZFS_TYPE_VOLUME;
453 	else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
454 		zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM;
455 	else
456 		abort();
457 
458 	if (zhp->zfs_dmustats.dds_is_snapshot)
459 		zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
460 	else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
461 		zhp->zfs_type = ZFS_TYPE_VOLUME;
462 	else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
463 		zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
464 	else
465 		abort();	/* we should never see any other types */
466 
467 	if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL)
468 		return (-1);
469 
470 	return (0);
471 }
472 
473 zfs_handle_t *
474 make_dataset_handle(libzfs_handle_t *hdl, const char *path)
475 {
476 	zfs_cmd_t zc = { 0 };
477 
478 	zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
479 
480 	if (zhp == NULL)
481 		return (NULL);
482 
483 	zhp->zfs_hdl = hdl;
484 	(void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
485 	if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) {
486 		free(zhp);
487 		return (NULL);
488 	}
489 	if (get_stats_ioctl(zhp, &zc) == -1) {
490 		zcmd_free_nvlists(&zc);
491 		free(zhp);
492 		return (NULL);
493 	}
494 	if (make_dataset_handle_common(zhp, &zc) == -1) {
495 		free(zhp);
496 		zhp = NULL;
497 	}
498 	zcmd_free_nvlists(&zc);
499 	return (zhp);
500 }
501 
502 zfs_handle_t *
503 make_dataset_handle_zc(libzfs_handle_t *hdl, zfs_cmd_t *zc)
504 {
505 	zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
506 
507 	if (zhp == NULL)
508 		return (NULL);
509 
510 	zhp->zfs_hdl = hdl;
511 	(void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name));
512 	if (make_dataset_handle_common(zhp, zc) == -1) {
513 		free(zhp);
514 		return (NULL);
515 	}
516 	return (zhp);
517 }
518 
519 zfs_handle_t *
520 zfs_handle_dup(zfs_handle_t *zhp_orig)
521 {
522 	zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
523 
524 	if (zhp == NULL)
525 		return (NULL);
526 
527 	zhp->zfs_hdl = zhp_orig->zfs_hdl;
528 	zhp->zpool_hdl = zhp_orig->zpool_hdl;
529 	(void) strlcpy(zhp->zfs_name, zhp_orig->zfs_name,
530 	    sizeof (zhp->zfs_name));
531 	zhp->zfs_type = zhp_orig->zfs_type;
532 	zhp->zfs_head_type = zhp_orig->zfs_head_type;
533 	zhp->zfs_dmustats = zhp_orig->zfs_dmustats;
534 	if (zhp_orig->zfs_props != NULL) {
535 		if (nvlist_dup(zhp_orig->zfs_props, &zhp->zfs_props, 0) != 0) {
536 			(void) no_memory(zhp->zfs_hdl);
537 			zfs_close(zhp);
538 			return (NULL);
539 		}
540 	}
541 	if (zhp_orig->zfs_user_props != NULL) {
542 		if (nvlist_dup(zhp_orig->zfs_user_props,
543 		    &zhp->zfs_user_props, 0) != 0) {
544 			(void) no_memory(zhp->zfs_hdl);
545 			zfs_close(zhp);
546 			return (NULL);
547 		}
548 	}
549 	if (zhp_orig->zfs_recvd_props != NULL) {
550 		if (nvlist_dup(zhp_orig->zfs_recvd_props,
551 		    &zhp->zfs_recvd_props, 0)) {
552 			(void) no_memory(zhp->zfs_hdl);
553 			zfs_close(zhp);
554 			return (NULL);
555 		}
556 	}
557 	zhp->zfs_mntcheck = zhp_orig->zfs_mntcheck;
558 	if (zhp_orig->zfs_mntopts != NULL) {
559 		zhp->zfs_mntopts = zfs_strdup(zhp_orig->zfs_hdl,
560 		    zhp_orig->zfs_mntopts);
561 	}
562 	zhp->zfs_props_table = zhp_orig->zfs_props_table;
563 	return (zhp);
564 }
565 
566 boolean_t
567 zfs_bookmark_exists(const char *path)
568 {
569 	nvlist_t *bmarks;
570 	nvlist_t *props;
571 	char fsname[ZFS_MAXNAMELEN];
572 	char *bmark_name;
573 	char *pound;
574 	int err;
575 	boolean_t rv;
576 
577 
578 	(void) strlcpy(fsname, path, sizeof (fsname));
579 	pound = strchr(fsname, '#');
580 	if (pound == NULL)
581 		return (B_FALSE);
582 
583 	*pound = '\0';
584 	bmark_name = pound + 1;
585 	props = fnvlist_alloc();
586 	err = lzc_get_bookmarks(fsname, props, &bmarks);
587 	nvlist_free(props);
588 	if (err != 0) {
589 		nvlist_free(bmarks);
590 		return (B_FALSE);
591 	}
592 
593 	rv = nvlist_exists(bmarks, bmark_name);
594 	nvlist_free(bmarks);
595 	return (rv);
596 }
597 
598 zfs_handle_t *
599 make_bookmark_handle(zfs_handle_t *parent, const char *path,
600     nvlist_t *bmark_props)
601 {
602 	zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
603 
604 	if (zhp == NULL)
605 		return (NULL);
606 
607 	/* Fill in the name. */
608 	zhp->zfs_hdl = parent->zfs_hdl;
609 	(void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
610 
611 	/* Set the property lists. */
612 	if (nvlist_dup(bmark_props, &zhp->zfs_props, 0) != 0) {
613 		free(zhp);
614 		return (NULL);
615 	}
616 
617 	/* Set the types. */
618 	zhp->zfs_head_type = parent->zfs_head_type;
619 	zhp->zfs_type = ZFS_TYPE_BOOKMARK;
620 
621 	if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL) {
622 		nvlist_free(zhp->zfs_props);
623 		free(zhp);
624 		return (NULL);
625 	}
626 
627 	return (zhp);
628 }
629 
630 /*
631  * Opens the given snapshot, filesystem, or volume.   The 'types'
632  * argument is a mask of acceptable types.  The function will print an
633  * appropriate error message and return NULL if it can't be opened.
634  */
635 zfs_handle_t *
636 zfs_open(libzfs_handle_t *hdl, const char *path, int types)
637 {
638 	zfs_handle_t *zhp;
639 	char errbuf[1024];
640 
641 	(void) snprintf(errbuf, sizeof (errbuf),
642 	    dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
643 
644 	/*
645 	 * Validate the name before we even try to open it.
646 	 */
647 	if (!zfs_validate_name(hdl, path, ZFS_TYPE_DATASET, B_FALSE)) {
648 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
649 		    "invalid dataset name"));
650 		(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
651 		return (NULL);
652 	}
653 
654 	/*
655 	 * Try to get stats for the dataset, which will tell us if it exists.
656 	 */
657 	errno = 0;
658 	if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
659 		(void) zfs_standard_error(hdl, errno, errbuf);
660 		return (NULL);
661 	}
662 
663 	if (!(types & zhp->zfs_type)) {
664 		(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
665 		zfs_close(zhp);
666 		return (NULL);
667 	}
668 
669 	return (zhp);
670 }
671 
672 /*
673  * Release a ZFS handle.  Nothing to do but free the associated memory.
674  */
675 void
676 zfs_close(zfs_handle_t *zhp)
677 {
678 	if (zhp->zfs_mntopts)
679 		free(zhp->zfs_mntopts);
680 	nvlist_free(zhp->zfs_props);
681 	nvlist_free(zhp->zfs_user_props);
682 	nvlist_free(zhp->zfs_recvd_props);
683 	free(zhp);
684 }
685 
686 typedef struct mnttab_node {
687 	struct mnttab mtn_mt;
688 	avl_node_t mtn_node;
689 } mnttab_node_t;
690 
691 static int
692 libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
693 {
694 	const mnttab_node_t *mtn1 = arg1;
695 	const mnttab_node_t *mtn2 = arg2;
696 	int rv;
697 
698 	rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
699 
700 	if (rv == 0)
701 		return (0);
702 	return (rv > 0 ? 1 : -1);
703 }
704 
705 void
706 libzfs_mnttab_init(libzfs_handle_t *hdl)
707 {
708 	assert(avl_numnodes(&hdl->libzfs_mnttab_cache) == 0);
709 	avl_create(&hdl->libzfs_mnttab_cache, libzfs_mnttab_cache_compare,
710 	    sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
711 }
712 
713 void
714 libzfs_mnttab_update(libzfs_handle_t *hdl)
715 {
716 	struct mnttab entry;
717 
718 	rewind(hdl->libzfs_mnttab);
719 	while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
720 		mnttab_node_t *mtn;
721 
722 		if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
723 			continue;
724 		mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
725 		mtn->mtn_mt.mnt_special = zfs_strdup(hdl, entry.mnt_special);
726 		mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp);
727 		mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype);
728 		mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
729 		avl_add(&hdl->libzfs_mnttab_cache, mtn);
730 	}
731 }
732 
733 void
734 libzfs_mnttab_fini(libzfs_handle_t *hdl)
735 {
736 	void *cookie = NULL;
737 	mnttab_node_t *mtn;
738 
739 	while (mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie)) {
740 		free(mtn->mtn_mt.mnt_special);
741 		free(mtn->mtn_mt.mnt_mountp);
742 		free(mtn->mtn_mt.mnt_fstype);
743 		free(mtn->mtn_mt.mnt_mntopts);
744 		free(mtn);
745 	}
746 	avl_destroy(&hdl->libzfs_mnttab_cache);
747 }
748 
749 void
750 libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
751 {
752 	hdl->libzfs_mnttab_enable = enable;
753 }
754 
755 int
756 libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
757     struct mnttab *entry)
758 {
759 	mnttab_node_t find;
760 	mnttab_node_t *mtn;
761 
762 	if (!hdl->libzfs_mnttab_enable) {
763 		struct mnttab srch = { 0 };
764 
765 		if (avl_numnodes(&hdl->libzfs_mnttab_cache))
766 			libzfs_mnttab_fini(hdl);
767 		rewind(hdl->libzfs_mnttab);
768 		srch.mnt_special = (char *)fsname;
769 		srch.mnt_fstype = MNTTYPE_ZFS;
770 		if (getmntany(hdl->libzfs_mnttab, entry, &srch) == 0)
771 			return (0);
772 		else
773 			return (ENOENT);
774 	}
775 
776 	if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0)
777 		libzfs_mnttab_update(hdl);
778 
779 	find.mtn_mt.mnt_special = (char *)fsname;
780 	mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL);
781 	if (mtn) {
782 		*entry = mtn->mtn_mt;
783 		return (0);
784 	}
785 	return (ENOENT);
786 }
787 
788 void
789 libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
790     const char *mountp, const char *mntopts)
791 {
792 	mnttab_node_t *mtn;
793 
794 	if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0)
795 		return;
796 	mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
797 	mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special);
798 	mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp);
799 	mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, MNTTYPE_ZFS);
800 	mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts);
801 	avl_add(&hdl->libzfs_mnttab_cache, mtn);
802 }
803 
804 void
805 libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
806 {
807 	mnttab_node_t find;
808 	mnttab_node_t *ret;
809 
810 	find.mtn_mt.mnt_special = (char *)fsname;
811 	if (ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL)) {
812 		avl_remove(&hdl->libzfs_mnttab_cache, ret);
813 		free(ret->mtn_mt.mnt_special);
814 		free(ret->mtn_mt.mnt_mountp);
815 		free(ret->mtn_mt.mnt_fstype);
816 		free(ret->mtn_mt.mnt_mntopts);
817 		free(ret);
818 	}
819 }
820 
821 int
822 zfs_spa_version(zfs_handle_t *zhp, int *spa_version)
823 {
824 	zpool_handle_t *zpool_handle = zhp->zpool_hdl;
825 
826 	if (zpool_handle == NULL)
827 		return (-1);
828 
829 	*spa_version = zpool_get_prop_int(zpool_handle,
830 	    ZPOOL_PROP_VERSION, NULL);
831 	return (0);
832 }
833 
834 /*
835  * The choice of reservation property depends on the SPA version.
836  */
837 static int
838 zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
839 {
840 	int spa_version;
841 
842 	if (zfs_spa_version(zhp, &spa_version) < 0)
843 		return (-1);
844 
845 	if (spa_version >= SPA_VERSION_REFRESERVATION)
846 		*resv_prop = ZFS_PROP_REFRESERVATION;
847 	else
848 		*resv_prop = ZFS_PROP_RESERVATION;
849 
850 	return (0);
851 }
852 
853 /*
854  * Given an nvlist of properties to set, validates that they are correct, and
855  * parses any numeric properties (index, boolean, etc) if they are specified as
856  * strings.
857  */
858 nvlist_t *
859 zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
860     uint64_t zoned, zfs_handle_t *zhp, const char *errbuf)
861 {
862 	nvpair_t *elem;
863 	uint64_t intval;
864 	char *strval;
865 	zfs_prop_t prop;
866 	nvlist_t *ret;
867 	int chosen_normal = -1;
868 	int chosen_utf = -1;
869 
870 	if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
871 		(void) no_memory(hdl);
872 		return (NULL);
873 	}
874 
875 	/*
876 	 * Make sure this property is valid and applies to this type.
877 	 */
878 
879 	elem = NULL;
880 	while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
881 		const char *propname = nvpair_name(elem);
882 
883 		prop = zfs_name_to_prop(propname);
884 		if (prop == ZPROP_INVAL && zfs_prop_user(propname)) {
885 			/*
886 			 * This is a user property: make sure it's a
887 			 * string, and that it's less than ZAP_MAXNAMELEN.
888 			 */
889 			if (nvpair_type(elem) != DATA_TYPE_STRING) {
890 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
891 				    "'%s' must be a string"), propname);
892 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
893 				goto error;
894 			}
895 
896 			if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
897 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
898 				    "property name '%s' is too long"),
899 				    propname);
900 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
901 				goto error;
902 			}
903 
904 			(void) nvpair_value_string(elem, &strval);
905 			if (nvlist_add_string(ret, propname, strval) != 0) {
906 				(void) no_memory(hdl);
907 				goto error;
908 			}
909 			continue;
910 		}
911 
912 		/*
913 		 * Currently, only user properties can be modified on
914 		 * snapshots.
915 		 */
916 		if (type == ZFS_TYPE_SNAPSHOT) {
917 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
918 			    "this property can not be modified for snapshots"));
919 			(void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
920 			goto error;
921 		}
922 
923 		if (prop == ZPROP_INVAL && zfs_prop_userquota(propname)) {
924 			zfs_userquota_prop_t uqtype;
925 			char newpropname[128];
926 			char domain[128];
927 			uint64_t rid;
928 			uint64_t valary[3];
929 
930 			if (userquota_propname_decode(propname, zoned,
931 			    &uqtype, domain, sizeof (domain), &rid) != 0) {
932 				zfs_error_aux(hdl,
933 				    dgettext(TEXT_DOMAIN,
934 				    "'%s' has an invalid user/group name"),
935 				    propname);
936 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
937 				goto error;
938 			}
939 
940 			if (uqtype != ZFS_PROP_USERQUOTA &&
941 			    uqtype != ZFS_PROP_GROUPQUOTA) {
942 				zfs_error_aux(hdl,
943 				    dgettext(TEXT_DOMAIN, "'%s' is readonly"),
944 				    propname);
945 				(void) zfs_error(hdl, EZFS_PROPREADONLY,
946 				    errbuf);
947 				goto error;
948 			}
949 
950 			if (nvpair_type(elem) == DATA_TYPE_STRING) {
951 				(void) nvpair_value_string(elem, &strval);
952 				if (strcmp(strval, "none") == 0) {
953 					intval = 0;
954 				} else if (zfs_nicestrtonum(hdl,
955 				    strval, &intval) != 0) {
956 					(void) zfs_error(hdl,
957 					    EZFS_BADPROP, errbuf);
958 					goto error;
959 				}
960 			} else if (nvpair_type(elem) ==
961 			    DATA_TYPE_UINT64) {
962 				(void) nvpair_value_uint64(elem, &intval);
963 				if (intval == 0) {
964 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
965 					    "use 'none' to disable "
966 					    "userquota/groupquota"));
967 					goto error;
968 				}
969 			} else {
970 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
971 				    "'%s' must be a number"), propname);
972 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
973 				goto error;
974 			}
975 
976 			/*
977 			 * Encode the prop name as
978 			 * userquota@<hex-rid>-domain, to make it easy
979 			 * for the kernel to decode.
980 			 */
981 			(void) snprintf(newpropname, sizeof (newpropname),
982 			    "%s%llx-%s", zfs_userquota_prop_prefixes[uqtype],
983 			    (longlong_t)rid, domain);
984 			valary[0] = uqtype;
985 			valary[1] = rid;
986 			valary[2] = intval;
987 			if (nvlist_add_uint64_array(ret, newpropname,
988 			    valary, 3) != 0) {
989 				(void) no_memory(hdl);
990 				goto error;
991 			}
992 			continue;
993 		} else if (prop == ZPROP_INVAL && zfs_prop_written(propname)) {
994 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
995 			    "'%s' is readonly"),
996 			    propname);
997 			(void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
998 			goto error;
999 		}
1000 
1001 		if (prop == ZPROP_INVAL) {
1002 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1003 			    "invalid property '%s'"), propname);
1004 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1005 			goto error;
1006 		}
1007 
1008 		if (!zfs_prop_valid_for_type(prop, type)) {
1009 			zfs_error_aux(hdl,
1010 			    dgettext(TEXT_DOMAIN, "'%s' does not "
1011 			    "apply to datasets of this type"), propname);
1012 			(void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
1013 			goto error;
1014 		}
1015 
1016 		if (zfs_prop_readonly(prop) &&
1017 		    (!zfs_prop_setonce(prop) || zhp != NULL)) {
1018 			zfs_error_aux(hdl,
1019 			    dgettext(TEXT_DOMAIN, "'%s' is readonly"),
1020 			    propname);
1021 			(void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
1022 			goto error;
1023 		}
1024 
1025 		if (zprop_parse_value(hdl, elem, prop, type, ret,
1026 		    &strval, &intval, errbuf) != 0)
1027 			goto error;
1028 
1029 		/*
1030 		 * Perform some additional checks for specific properties.
1031 		 */
1032 		switch (prop) {
1033 		case ZFS_PROP_VERSION:
1034 		{
1035 			int version;
1036 
1037 			if (zhp == NULL)
1038 				break;
1039 			version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
1040 			if (intval < version) {
1041 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1042 				    "Can not downgrade; already at version %u"),
1043 				    version);
1044 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1045 				goto error;
1046 			}
1047 			break;
1048 		}
1049 
1050 		case ZFS_PROP_RECORDSIZE:
1051 		case ZFS_PROP_VOLBLOCKSIZE:
1052 			/* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */
1053 			if (intval < SPA_MINBLOCKSIZE ||
1054 			    intval > SPA_MAXBLOCKSIZE || !ISP2(intval)) {
1055 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1056 				    "'%s' must be power of 2 from %u "
1057 				    "to %uk"), propname,
1058 				    (uint_t)SPA_MINBLOCKSIZE,
1059 				    (uint_t)SPA_MAXBLOCKSIZE >> 10);
1060 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1061 				goto error;
1062 			}
1063 			break;
1064 
1065 		case ZFS_PROP_MLSLABEL:
1066 		{
1067 			/*
1068 			 * Verify the mlslabel string and convert to
1069 			 * internal hex label string.
1070 			 */
1071 
1072 			m_label_t *new_sl;
1073 			char *hex = NULL;	/* internal label string */
1074 
1075 			/* Default value is already OK. */
1076 			if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
1077 				break;
1078 
1079 			/* Verify the label can be converted to binary form */
1080 			if (((new_sl = m_label_alloc(MAC_LABEL)) == NULL) ||
1081 			    (str_to_label(strval, &new_sl, MAC_LABEL,
1082 			    L_NO_CORRECTION, NULL) == -1)) {
1083 				goto badlabel;
1084 			}
1085 
1086 			/* Now translate to hex internal label string */
1087 			if (label_to_str(new_sl, &hex, M_INTERNAL,
1088 			    DEF_NAMES) != 0) {
1089 				if (hex)
1090 					free(hex);
1091 				goto badlabel;
1092 			}
1093 			m_label_free(new_sl);
1094 
1095 			/* If string is already in internal form, we're done. */
1096 			if (strcmp(strval, hex) == 0) {
1097 				free(hex);
1098 				break;
1099 			}
1100 
1101 			/* Replace the label string with the internal form. */
1102 			(void) nvlist_remove(ret, zfs_prop_to_name(prop),
1103 			    DATA_TYPE_STRING);
1104 			verify(nvlist_add_string(ret, zfs_prop_to_name(prop),
1105 			    hex) == 0);
1106 			free(hex);
1107 
1108 			break;
1109 
1110 badlabel:
1111 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1112 			    "invalid mlslabel '%s'"), strval);
1113 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1114 			m_label_free(new_sl);	/* OK if null */
1115 			goto error;
1116 
1117 		}
1118 
1119 		case ZFS_PROP_MOUNTPOINT:
1120 		{
1121 			namecheck_err_t why;
1122 
1123 			if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 ||
1124 			    strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0)
1125 				break;
1126 
1127 			if (mountpoint_namecheck(strval, &why)) {
1128 				switch (why) {
1129 				case NAME_ERR_LEADING_SLASH:
1130 					zfs_error_aux(hdl,
1131 					    dgettext(TEXT_DOMAIN,
1132 					    "'%s' must be an absolute path, "
1133 					    "'none', or 'legacy'"), propname);
1134 					break;
1135 				case NAME_ERR_TOOLONG:
1136 					zfs_error_aux(hdl,
1137 					    dgettext(TEXT_DOMAIN,
1138 					    "component of '%s' is too long"),
1139 					    propname);
1140 					break;
1141 				}
1142 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1143 				goto error;
1144 			}
1145 		}
1146 
1147 			/*FALLTHRU*/
1148 
1149 		case ZFS_PROP_SHARESMB:
1150 		case ZFS_PROP_SHARENFS:
1151 			/*
1152 			 * For the mountpoint and sharenfs or sharesmb
1153 			 * properties, check if it can be set in a
1154 			 * global/non-global zone based on
1155 			 * the zoned property value:
1156 			 *
1157 			 *		global zone	    non-global zone
1158 			 * --------------------------------------------------
1159 			 * zoned=on	mountpoint (no)	    mountpoint (yes)
1160 			 *		sharenfs (no)	    sharenfs (no)
1161 			 *		sharesmb (no)	    sharesmb (no)
1162 			 *
1163 			 * zoned=off	mountpoint (yes)	N/A
1164 			 *		sharenfs (yes)
1165 			 *		sharesmb (yes)
1166 			 */
1167 			if (zoned) {
1168 				if (getzoneid() == GLOBAL_ZONEID) {
1169 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1170 					    "'%s' cannot be set on "
1171 					    "dataset in a non-global zone"),
1172 					    propname);
1173 					(void) zfs_error(hdl, EZFS_ZONED,
1174 					    errbuf);
1175 					goto error;
1176 				} else if (prop == ZFS_PROP_SHARENFS ||
1177 				    prop == ZFS_PROP_SHARESMB) {
1178 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1179 					    "'%s' cannot be set in "
1180 					    "a non-global zone"), propname);
1181 					(void) zfs_error(hdl, EZFS_ZONED,
1182 					    errbuf);
1183 					goto error;
1184 				}
1185 			} else if (getzoneid() != GLOBAL_ZONEID) {
1186 				/*
1187 				 * If zoned property is 'off', this must be in
1188 				 * a global zone. If not, something is wrong.
1189 				 */
1190 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1191 				    "'%s' cannot be set while dataset "
1192 				    "'zoned' property is set"), propname);
1193 				(void) zfs_error(hdl, EZFS_ZONED, errbuf);
1194 				goto error;
1195 			}
1196 
1197 			/*
1198 			 * At this point, it is legitimate to set the
1199 			 * property. Now we want to make sure that the
1200 			 * property value is valid if it is sharenfs.
1201 			 */
1202 			if ((prop == ZFS_PROP_SHARENFS ||
1203 			    prop == ZFS_PROP_SHARESMB) &&
1204 			    strcmp(strval, "on") != 0 &&
1205 			    strcmp(strval, "off") != 0) {
1206 				zfs_share_proto_t proto;
1207 
1208 				if (prop == ZFS_PROP_SHARESMB)
1209 					proto = PROTO_SMB;
1210 				else
1211 					proto = PROTO_NFS;
1212 
1213 				/*
1214 				 * Must be an valid sharing protocol
1215 				 * option string so init the libshare
1216 				 * in order to enable the parser and
1217 				 * then parse the options. We use the
1218 				 * control API since we don't care about
1219 				 * the current configuration and don't
1220 				 * want the overhead of loading it
1221 				 * until we actually do something.
1222 				 */
1223 
1224 				if (zfs_init_libshare(hdl,
1225 				    SA_INIT_CONTROL_API) != SA_OK) {
1226 					/*
1227 					 * An error occurred so we can't do
1228 					 * anything
1229 					 */
1230 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1231 					    "'%s' cannot be set: problem "
1232 					    "in share initialization"),
1233 					    propname);
1234 					(void) zfs_error(hdl, EZFS_BADPROP,
1235 					    errbuf);
1236 					goto error;
1237 				}
1238 
1239 				if (zfs_parse_options(strval, proto) != SA_OK) {
1240 					/*
1241 					 * There was an error in parsing so
1242 					 * deal with it by issuing an error
1243 					 * message and leaving after
1244 					 * uninitializing the the libshare
1245 					 * interface.
1246 					 */
1247 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1248 					    "'%s' cannot be set to invalid "
1249 					    "options"), propname);
1250 					(void) zfs_error(hdl, EZFS_BADPROP,
1251 					    errbuf);
1252 					zfs_uninit_libshare(hdl);
1253 					goto error;
1254 				}
1255 				zfs_uninit_libshare(hdl);
1256 			}
1257 
1258 			break;
1259 		case ZFS_PROP_UTF8ONLY:
1260 			chosen_utf = (int)intval;
1261 			break;
1262 		case ZFS_PROP_NORMALIZE:
1263 			chosen_normal = (int)intval;
1264 			break;
1265 		}
1266 
1267 		/*
1268 		 * For changes to existing volumes, we have some additional
1269 		 * checks to enforce.
1270 		 */
1271 		if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
1272 			uint64_t volsize = zfs_prop_get_int(zhp,
1273 			    ZFS_PROP_VOLSIZE);
1274 			uint64_t blocksize = zfs_prop_get_int(zhp,
1275 			    ZFS_PROP_VOLBLOCKSIZE);
1276 			char buf[64];
1277 
1278 			switch (prop) {
1279 			case ZFS_PROP_RESERVATION:
1280 			case ZFS_PROP_REFRESERVATION:
1281 				if (intval > volsize) {
1282 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1283 					    "'%s' is greater than current "
1284 					    "volume size"), propname);
1285 					(void) zfs_error(hdl, EZFS_BADPROP,
1286 					    errbuf);
1287 					goto error;
1288 				}
1289 				break;
1290 
1291 			case ZFS_PROP_VOLSIZE:
1292 				if (intval % blocksize != 0) {
1293 					zfs_nicenum(blocksize, buf,
1294 					    sizeof (buf));
1295 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1296 					    "'%s' must be a multiple of "
1297 					    "volume block size (%s)"),
1298 					    propname, buf);
1299 					(void) zfs_error(hdl, EZFS_BADPROP,
1300 					    errbuf);
1301 					goto error;
1302 				}
1303 
1304 				if (intval == 0) {
1305 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1306 					    "'%s' cannot be zero"),
1307 					    propname);
1308 					(void) zfs_error(hdl, EZFS_BADPROP,
1309 					    errbuf);
1310 					goto error;
1311 				}
1312 				break;
1313 			}
1314 		}
1315 	}
1316 
1317 	/*
1318 	 * If normalization was chosen, but no UTF8 choice was made,
1319 	 * enforce rejection of non-UTF8 names.
1320 	 *
1321 	 * If normalization was chosen, but rejecting non-UTF8 names
1322 	 * was explicitly not chosen, it is an error.
1323 	 */
1324 	if (chosen_normal > 0 && chosen_utf < 0) {
1325 		if (nvlist_add_uint64(ret,
1326 		    zfs_prop_to_name(ZFS_PROP_UTF8ONLY), 1) != 0) {
1327 			(void) no_memory(hdl);
1328 			goto error;
1329 		}
1330 	} else if (chosen_normal > 0 && chosen_utf == 0) {
1331 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1332 		    "'%s' must be set 'on' if normalization chosen"),
1333 		    zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
1334 		(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1335 		goto error;
1336 	}
1337 	return (ret);
1338 
1339 error:
1340 	nvlist_free(ret);
1341 	return (NULL);
1342 }
1343 
1344 int
1345 zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl)
1346 {
1347 	uint64_t old_volsize;
1348 	uint64_t new_volsize;
1349 	uint64_t old_reservation;
1350 	uint64_t new_reservation;
1351 	zfs_prop_t resv_prop;
1352 	nvlist_t *props;
1353 
1354 	/*
1355 	 * If this is an existing volume, and someone is setting the volsize,
1356 	 * make sure that it matches the reservation, or add it if necessary.
1357 	 */
1358 	old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
1359 	if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
1360 		return (-1);
1361 	old_reservation = zfs_prop_get_int(zhp, resv_prop);
1362 
1363 	props = fnvlist_alloc();
1364 	fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
1365 	    zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
1366 
1367 	if ((zvol_volsize_to_reservation(old_volsize, props) !=
1368 	    old_reservation) || nvlist_exists(nvl,
1369 	    zfs_prop_to_name(resv_prop))) {
1370 		fnvlist_free(props);
1371 		return (0);
1372 	}
1373 	if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
1374 	    &new_volsize) != 0) {
1375 		fnvlist_free(props);
1376 		return (-1);
1377 	}
1378 	new_reservation = zvol_volsize_to_reservation(new_volsize, props);
1379 	fnvlist_free(props);
1380 
1381 	if (nvlist_add_uint64(nvl, zfs_prop_to_name(resv_prop),
1382 	    new_reservation) != 0) {
1383 		(void) no_memory(zhp->zfs_hdl);
1384 		return (-1);
1385 	}
1386 	return (1);
1387 }
1388 
1389 void
1390 zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
1391     char *errbuf)
1392 {
1393 	switch (err) {
1394 
1395 	case ENOSPC:
1396 		/*
1397 		 * For quotas and reservations, ENOSPC indicates
1398 		 * something different; setting a quota or reservation
1399 		 * doesn't use any disk space.
1400 		 */
1401 		switch (prop) {
1402 		case ZFS_PROP_QUOTA:
1403 		case ZFS_PROP_REFQUOTA:
1404 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1405 			    "size is less than current used or "
1406 			    "reserved space"));
1407 			(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1408 			break;
1409 
1410 		case ZFS_PROP_RESERVATION:
1411 		case ZFS_PROP_REFRESERVATION:
1412 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1413 			    "size is greater than available space"));
1414 			(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1415 			break;
1416 
1417 		default:
1418 			(void) zfs_standard_error(hdl, err, errbuf);
1419 			break;
1420 		}
1421 		break;
1422 
1423 	case EBUSY:
1424 		(void) zfs_standard_error(hdl, EBUSY, errbuf);
1425 		break;
1426 
1427 	case EROFS:
1428 		(void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
1429 		break;
1430 
1431 	case ENOTSUP:
1432 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1433 		    "pool and or dataset must be upgraded to set this "
1434 		    "property or value"));
1435 		(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
1436 		break;
1437 
1438 	case ERANGE:
1439 		if (prop == ZFS_PROP_COMPRESSION) {
1440 			(void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1441 			    "property setting is not allowed on "
1442 			    "bootable datasets"));
1443 			(void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
1444 		} else {
1445 			(void) zfs_standard_error(hdl, err, errbuf);
1446 		}
1447 		break;
1448 
1449 	case EINVAL:
1450 		if (prop == ZPROP_INVAL) {
1451 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1452 		} else {
1453 			(void) zfs_standard_error(hdl, err, errbuf);
1454 		}
1455 		break;
1456 
1457 	case EOVERFLOW:
1458 		/*
1459 		 * This platform can't address a volume this big.
1460 		 */
1461 #ifdef _ILP32
1462 		if (prop == ZFS_PROP_VOLSIZE) {
1463 			(void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
1464 			break;
1465 		}
1466 #endif
1467 		/* FALLTHROUGH */
1468 	default:
1469 		(void) zfs_standard_error(hdl, err, errbuf);
1470 	}
1471 }
1472 
1473 /*
1474  * Given a property name and value, set the property for the given dataset.
1475  */
1476 int
1477 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
1478 {
1479 	zfs_cmd_t zc = { 0 };
1480 	int ret = -1;
1481 	prop_changelist_t *cl = NULL;
1482 	char errbuf[1024];
1483 	libzfs_handle_t *hdl = zhp->zfs_hdl;
1484 	nvlist_t *nvl = NULL, *realprops;
1485 	zfs_prop_t prop;
1486 	boolean_t do_prefix = B_TRUE;
1487 	int added_resv;
1488 
1489 	(void) snprintf(errbuf, sizeof (errbuf),
1490 	    dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
1491 	    zhp->zfs_name);
1492 
1493 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
1494 	    nvlist_add_string(nvl, propname, propval) != 0) {
1495 		(void) no_memory(hdl);
1496 		goto error;
1497 	}
1498 
1499 	if ((realprops = zfs_valid_proplist(hdl, zhp->zfs_type, nvl,
1500 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
1501 		goto error;
1502 
1503 	nvlist_free(nvl);
1504 	nvl = realprops;
1505 
1506 	prop = zfs_name_to_prop(propname);
1507 
1508 	if (prop == ZFS_PROP_VOLSIZE) {
1509 		if ((added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1)
1510 			goto error;
1511 	}
1512 
1513 	if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
1514 		goto error;
1515 
1516 	if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
1517 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1518 		    "child dataset with inherited mountpoint is used "
1519 		    "in a non-global zone"));
1520 		ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1521 		goto error;
1522 	}
1523 
1524 	/*
1525 	 * We don't want to unmount & remount the dataset when changing
1526 	 * its canmount property to 'on' or 'noauto'.  We only use
1527 	 * the changelist logic to unmount when setting canmount=off.
1528 	 */
1529 	if (prop == ZFS_PROP_CANMOUNT) {
1530 		uint64_t idx;
1531 		int err = zprop_string_to_index(prop, propval, &idx,
1532 		    ZFS_TYPE_DATASET);
1533 		if (err == 0 && idx != ZFS_CANMOUNT_OFF)
1534 			do_prefix = B_FALSE;
1535 	}
1536 
1537 	if (do_prefix && (ret = changelist_prefix(cl)) != 0)
1538 		goto error;
1539 
1540 	/*
1541 	 * Execute the corresponding ioctl() to set this property.
1542 	 */
1543 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1544 
1545 	if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
1546 		goto error;
1547 
1548 	ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1549 
1550 	if (ret != 0) {
1551 		zfs_setprop_error(hdl, prop, errno, errbuf);
1552 		if (added_resv && errno == ENOSPC) {
1553 			/* clean up the volsize property we tried to set */
1554 			uint64_t old_volsize = zfs_prop_get_int(zhp,
1555 			    ZFS_PROP_VOLSIZE);
1556 			nvlist_free(nvl);
1557 			zcmd_free_nvlists(&zc);
1558 			if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
1559 				goto error;
1560 			if (nvlist_add_uint64(nvl,
1561 			    zfs_prop_to_name(ZFS_PROP_VOLSIZE),
1562 			    old_volsize) != 0)
1563 				goto error;
1564 			if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
1565 				goto error;
1566 			(void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1567 		}
1568 	} else {
1569 		if (do_prefix)
1570 			ret = changelist_postfix(cl);
1571 
1572 		/*
1573 		 * Refresh the statistics so the new property value
1574 		 * is reflected.
1575 		 */
1576 		if (ret == 0)
1577 			(void) get_stats(zhp);
1578 	}
1579 
1580 error:
1581 	nvlist_free(nvl);
1582 	zcmd_free_nvlists(&zc);
1583 	if (cl)
1584 		changelist_free(cl);
1585 	return (ret);
1586 }
1587 
1588 /*
1589  * Given a property, inherit the value from the parent dataset, or if received
1590  * is TRUE, revert to the received value, if any.
1591  */
1592 int
1593 zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
1594 {
1595 	zfs_cmd_t zc = { 0 };
1596 	int ret;
1597 	prop_changelist_t *cl;
1598 	libzfs_handle_t *hdl = zhp->zfs_hdl;
1599 	char errbuf[1024];
1600 	zfs_prop_t prop;
1601 
1602 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1603 	    "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
1604 
1605 	zc.zc_cookie = received;
1606 	if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
1607 		/*
1608 		 * For user properties, the amount of work we have to do is very
1609 		 * small, so just do it here.
1610 		 */
1611 		if (!zfs_prop_user(propname)) {
1612 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1613 			    "invalid property"));
1614 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1615 		}
1616 
1617 		(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1618 		(void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1619 
1620 		if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0)
1621 			return (zfs_standard_error(hdl, errno, errbuf));
1622 
1623 		return (0);
1624 	}
1625 
1626 	/*
1627 	 * Verify that this property is inheritable.
1628 	 */
1629 	if (zfs_prop_readonly(prop))
1630 		return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
1631 
1632 	if (!zfs_prop_inheritable(prop) && !received)
1633 		return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
1634 
1635 	/*
1636 	 * Check to see if the value applies to this type
1637 	 */
1638 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1639 		return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
1640 
1641 	/*
1642 	 * Normalize the name, to get rid of shorthand abbreviations.
1643 	 */
1644 	propname = zfs_prop_to_name(prop);
1645 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1646 	(void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1647 
1648 	if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
1649 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
1650 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1651 		    "dataset is used in a non-global zone"));
1652 		return (zfs_error(hdl, EZFS_ZONED, errbuf));
1653 	}
1654 
1655 	/*
1656 	 * Determine datasets which will be affected by this change, if any.
1657 	 */
1658 	if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
1659 		return (-1);
1660 
1661 	if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
1662 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1663 		    "child dataset with inherited mountpoint is used "
1664 		    "in a non-global zone"));
1665 		ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1666 		goto error;
1667 	}
1668 
1669 	if ((ret = changelist_prefix(cl)) != 0)
1670 		goto error;
1671 
1672 	if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) {
1673 		return (zfs_standard_error(hdl, errno, errbuf));
1674 	} else {
1675 
1676 		if ((ret = changelist_postfix(cl)) != 0)
1677 			goto error;
1678 
1679 		/*
1680 		 * Refresh the statistics so the new property is reflected.
1681 		 */
1682 		(void) get_stats(zhp);
1683 	}
1684 
1685 error:
1686 	changelist_free(cl);
1687 	return (ret);
1688 }
1689 
1690 /*
1691  * True DSL properties are stored in an nvlist.  The following two functions
1692  * extract them appropriately.
1693  */
1694 static uint64_t
1695 getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
1696 {
1697 	nvlist_t *nv;
1698 	uint64_t value;
1699 
1700 	*source = NULL;
1701 	if (nvlist_lookup_nvlist(zhp->zfs_props,
1702 	    zfs_prop_to_name(prop), &nv) == 0) {
1703 		verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
1704 		(void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
1705 	} else {
1706 		verify(!zhp->zfs_props_table ||
1707 		    zhp->zfs_props_table[prop] == B_TRUE);
1708 		value = zfs_prop_default_numeric(prop);
1709 		*source = "";
1710 	}
1711 
1712 	return (value);
1713 }
1714 
1715 static char *
1716 getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
1717 {
1718 	nvlist_t *nv;
1719 	char *value;
1720 
1721 	*source = NULL;
1722 	if (nvlist_lookup_nvlist(zhp->zfs_props,
1723 	    zfs_prop_to_name(prop), &nv) == 0) {
1724 		verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
1725 		(void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
1726 	} else {
1727 		verify(!zhp->zfs_props_table ||
1728 		    zhp->zfs_props_table[prop] == B_TRUE);
1729 		if ((value = (char *)zfs_prop_default_string(prop)) == NULL)
1730 			value = "";
1731 		*source = "";
1732 	}
1733 
1734 	return (value);
1735 }
1736 
1737 static boolean_t
1738 zfs_is_recvd_props_mode(zfs_handle_t *zhp)
1739 {
1740 	return (zhp->zfs_props == zhp->zfs_recvd_props);
1741 }
1742 
1743 static void
1744 zfs_set_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
1745 {
1746 	*cookie = (uint64_t)(uintptr_t)zhp->zfs_props;
1747 	zhp->zfs_props = zhp->zfs_recvd_props;
1748 }
1749 
1750 static void
1751 zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
1752 {
1753 	zhp->zfs_props = (nvlist_t *)(uintptr_t)*cookie;
1754 	*cookie = 0;
1755 }
1756 
1757 /*
1758  * Internal function for getting a numeric property.  Both zfs_prop_get() and
1759  * zfs_prop_get_int() are built using this interface.
1760  *
1761  * Certain properties can be overridden using 'mount -o'.  In this case, scan
1762  * the contents of the /etc/mnttab entry, searching for the appropriate options.
1763  * If they differ from the on-disk values, report the current values and mark
1764  * the source "temporary".
1765  */
1766 static int
1767 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
1768     char **source, uint64_t *val)
1769 {
1770 	zfs_cmd_t zc = { 0 };
1771 	nvlist_t *zplprops = NULL;
1772 	struct mnttab mnt;
1773 	char *mntopt_on = NULL;
1774 	char *mntopt_off = NULL;
1775 	boolean_t received = zfs_is_recvd_props_mode(zhp);
1776 
1777 	*source = NULL;
1778 
1779 	switch (prop) {
1780 	case ZFS_PROP_ATIME:
1781 		mntopt_on = MNTOPT_ATIME;
1782 		mntopt_off = MNTOPT_NOATIME;
1783 		break;
1784 
1785 	case ZFS_PROP_DEVICES:
1786 		mntopt_on = MNTOPT_DEVICES;
1787 		mntopt_off = MNTOPT_NODEVICES;
1788 		break;
1789 
1790 	case ZFS_PROP_EXEC:
1791 		mntopt_on = MNTOPT_EXEC;
1792 		mntopt_off = MNTOPT_NOEXEC;
1793 		break;
1794 
1795 	case ZFS_PROP_READONLY:
1796 		mntopt_on = MNTOPT_RO;
1797 		mntopt_off = MNTOPT_RW;
1798 		break;
1799 
1800 	case ZFS_PROP_SETUID:
1801 		mntopt_on = MNTOPT_SETUID;
1802 		mntopt_off = MNTOPT_NOSETUID;
1803 		break;
1804 
1805 	case ZFS_PROP_XATTR:
1806 		mntopt_on = MNTOPT_XATTR;
1807 		mntopt_off = MNTOPT_NOXATTR;
1808 		break;
1809 
1810 	case ZFS_PROP_NBMAND:
1811 		mntopt_on = MNTOPT_NBMAND;
1812 		mntopt_off = MNTOPT_NONBMAND;
1813 		break;
1814 	}
1815 
1816 	/*
1817 	 * Because looking up the mount options is potentially expensive
1818 	 * (iterating over all of /etc/mnttab), we defer its calculation until
1819 	 * we're looking up a property which requires its presence.
1820 	 */
1821 	if (!zhp->zfs_mntcheck &&
1822 	    (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
1823 		libzfs_handle_t *hdl = zhp->zfs_hdl;
1824 		struct mnttab entry;
1825 
1826 		if (libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0) {
1827 			zhp->zfs_mntopts = zfs_strdup(hdl,
1828 			    entry.mnt_mntopts);
1829 			if (zhp->zfs_mntopts == NULL)
1830 				return (-1);
1831 		}
1832 
1833 		zhp->zfs_mntcheck = B_TRUE;
1834 	}
1835 
1836 	if (zhp->zfs_mntopts == NULL)
1837 		mnt.mnt_mntopts = "";
1838 	else
1839 		mnt.mnt_mntopts = zhp->zfs_mntopts;
1840 
1841 	switch (prop) {
1842 	case ZFS_PROP_ATIME:
1843 	case ZFS_PROP_DEVICES:
1844 	case ZFS_PROP_EXEC:
1845 	case ZFS_PROP_READONLY:
1846 	case ZFS_PROP_SETUID:
1847 	case ZFS_PROP_XATTR:
1848 	case ZFS_PROP_NBMAND:
1849 		*val = getprop_uint64(zhp, prop, source);
1850 
1851 		if (received)
1852 			break;
1853 
1854 		if (hasmntopt(&mnt, mntopt_on) && !*val) {
1855 			*val = B_TRUE;
1856 			if (src)
1857 				*src = ZPROP_SRC_TEMPORARY;
1858 		} else if (hasmntopt(&mnt, mntopt_off) && *val) {
1859 			*val = B_FALSE;
1860 			if (src)
1861 				*src = ZPROP_SRC_TEMPORARY;
1862 		}
1863 		break;
1864 
1865 	case ZFS_PROP_CANMOUNT:
1866 	case ZFS_PROP_VOLSIZE:
1867 	case ZFS_PROP_QUOTA:
1868 	case ZFS_PROP_REFQUOTA:
1869 	case ZFS_PROP_RESERVATION:
1870 	case ZFS_PROP_REFRESERVATION:
1871 		*val = getprop_uint64(zhp, prop, source);
1872 
1873 		if (*source == NULL) {
1874 			/* not default, must be local */
1875 			*source = zhp->zfs_name;
1876 		}
1877 		break;
1878 
1879 	case ZFS_PROP_MOUNTED:
1880 		*val = (zhp->zfs_mntopts != NULL);
1881 		break;
1882 
1883 	case ZFS_PROP_NUMCLONES:
1884 		*val = zhp->zfs_dmustats.dds_num_clones;
1885 		break;
1886 
1887 	case ZFS_PROP_VERSION:
1888 	case ZFS_PROP_NORMALIZE:
1889 	case ZFS_PROP_UTF8ONLY:
1890 	case ZFS_PROP_CASE:
1891 		if (!zfs_prop_valid_for_type(prop, zhp->zfs_head_type) ||
1892 		    zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
1893 			return (-1);
1894 		(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1895 		if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) {
1896 			zcmd_free_nvlists(&zc);
1897 			return (-1);
1898 		}
1899 		if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 ||
1900 		    nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop),
1901 		    val) != 0) {
1902 			zcmd_free_nvlists(&zc);
1903 			return (-1);
1904 		}
1905 		if (zplprops)
1906 			nvlist_free(zplprops);
1907 		zcmd_free_nvlists(&zc);
1908 		break;
1909 
1910 	case ZFS_PROP_INCONSISTENT:
1911 		*val = zhp->zfs_dmustats.dds_inconsistent;
1912 		break;
1913 
1914 	default:
1915 		switch (zfs_prop_get_type(prop)) {
1916 		case PROP_TYPE_NUMBER:
1917 		case PROP_TYPE_INDEX:
1918 			*val = getprop_uint64(zhp, prop, source);
1919 			/*
1920 			 * If we tried to use a default value for a
1921 			 * readonly property, it means that it was not
1922 			 * present.
1923 			 */
1924 			if (zfs_prop_readonly(prop) &&
1925 			    *source != NULL && (*source)[0] == '\0') {
1926 				*source = NULL;
1927 			}
1928 			break;
1929 
1930 		case PROP_TYPE_STRING:
1931 		default:
1932 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
1933 			    "cannot get non-numeric property"));
1934 			return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
1935 			    dgettext(TEXT_DOMAIN, "internal error")));
1936 		}
1937 	}
1938 
1939 	return (0);
1940 }
1941 
1942 /*
1943  * Calculate the source type, given the raw source string.
1944  */
1945 static void
1946 get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source,
1947     char *statbuf, size_t statlen)
1948 {
1949 	if (statbuf == NULL || *srctype == ZPROP_SRC_TEMPORARY)
1950 		return;
1951 
1952 	if (source == NULL) {
1953 		*srctype = ZPROP_SRC_NONE;
1954 	} else if (source[0] == '\0') {
1955 		*srctype = ZPROP_SRC_DEFAULT;
1956 	} else if (strstr(source, ZPROP_SOURCE_VAL_RECVD) != NULL) {
1957 		*srctype = ZPROP_SRC_RECEIVED;
1958 	} else {
1959 		if (strcmp(source, zhp->zfs_name) == 0) {
1960 			*srctype = ZPROP_SRC_LOCAL;
1961 		} else {
1962 			(void) strlcpy(statbuf, source, statlen);
1963 			*srctype = ZPROP_SRC_INHERITED;
1964 		}
1965 	}
1966 
1967 }
1968 
1969 int
1970 zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
1971     size_t proplen, boolean_t literal)
1972 {
1973 	zfs_prop_t prop;
1974 	int err = 0;
1975 
1976 	if (zhp->zfs_recvd_props == NULL)
1977 		if (get_recvd_props_ioctl(zhp) != 0)
1978 			return (-1);
1979 
1980 	prop = zfs_name_to_prop(propname);
1981 
1982 	if (prop != ZPROP_INVAL) {
1983 		uint64_t cookie;
1984 		if (!nvlist_exists(zhp->zfs_recvd_props, propname))
1985 			return (-1);
1986 		zfs_set_recvd_props_mode(zhp, &cookie);
1987 		err = zfs_prop_get(zhp, prop, propbuf, proplen,
1988 		    NULL, NULL, 0, literal);
1989 		zfs_unset_recvd_props_mode(zhp, &cookie);
1990 	} else {
1991 		nvlist_t *propval;
1992 		char *recvdval;
1993 		if (nvlist_lookup_nvlist(zhp->zfs_recvd_props,
1994 		    propname, &propval) != 0)
1995 			return (-1);
1996 		verify(nvlist_lookup_string(propval, ZPROP_VALUE,
1997 		    &recvdval) == 0);
1998 		(void) strlcpy(propbuf, recvdval, proplen);
1999 	}
2000 
2001 	return (err == 0 ? 0 : -1);
2002 }
2003 
2004 static int
2005 get_clones_string(zfs_handle_t *zhp, char *propbuf, size_t proplen)
2006 {
2007 	nvlist_t *value;
2008 	nvpair_t *pair;
2009 
2010 	value = zfs_get_clones_nvl(zhp);
2011 	if (value == NULL)
2012 		return (-1);
2013 
2014 	propbuf[0] = '\0';
2015 	for (pair = nvlist_next_nvpair(value, NULL); pair != NULL;
2016 	    pair = nvlist_next_nvpair(value, pair)) {
2017 		if (propbuf[0] != '\0')
2018 			(void) strlcat(propbuf, ",", proplen);
2019 		(void) strlcat(propbuf, nvpair_name(pair), proplen);
2020 	}
2021 
2022 	return (0);
2023 }
2024 
2025 struct get_clones_arg {
2026 	uint64_t numclones;
2027 	nvlist_t *value;
2028 	const char *origin;
2029 	char buf[ZFS_MAXNAMELEN];
2030 };
2031 
2032 int
2033 get_clones_cb(zfs_handle_t *zhp, void *arg)
2034 {
2035 	struct get_clones_arg *gca = arg;
2036 
2037 	if (gca->numclones == 0) {
2038 		zfs_close(zhp);
2039 		return (0);
2040 	}
2041 
2042 	if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, gca->buf, sizeof (gca->buf),
2043 	    NULL, NULL, 0, B_TRUE) != 0)
2044 		goto out;
2045 	if (strcmp(gca->buf, gca->origin) == 0) {
2046 		fnvlist_add_boolean(gca->value, zfs_get_name(zhp));
2047 		gca->numclones--;
2048 	}
2049 
2050 out:
2051 	(void) zfs_iter_children(zhp, get_clones_cb, gca);
2052 	zfs_close(zhp);
2053 	return (0);
2054 }
2055 
2056 nvlist_t *
2057 zfs_get_clones_nvl(zfs_handle_t *zhp)
2058 {
2059 	nvlist_t *nv, *value;
2060 
2061 	if (nvlist_lookup_nvlist(zhp->zfs_props,
2062 	    zfs_prop_to_name(ZFS_PROP_CLONES), &nv) != 0) {
2063 		struct get_clones_arg gca;
2064 
2065 		/*
2066 		 * if this is a snapshot, then the kernel wasn't able
2067 		 * to get the clones.  Do it by slowly iterating.
2068 		 */
2069 		if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT)
2070 			return (NULL);
2071 		if (nvlist_alloc(&nv, NV_UNIQUE_NAME, 0) != 0)
2072 			return (NULL);
2073 		if (nvlist_alloc(&value, NV_UNIQUE_NAME, 0) != 0) {
2074 			nvlist_free(nv);
2075 			return (NULL);
2076 		}
2077 
2078 		gca.numclones = zfs_prop_get_int(zhp, ZFS_PROP_NUMCLONES);
2079 		gca.value = value;
2080 		gca.origin = zhp->zfs_name;
2081 
2082 		if (gca.numclones != 0) {
2083 			zfs_handle_t *root;
2084 			char pool[ZFS_MAXNAMELEN];
2085 			char *cp = pool;
2086 
2087 			/* get the pool name */
2088 			(void) strlcpy(pool, zhp->zfs_name, sizeof (pool));
2089 			(void) strsep(&cp, "/@");
2090 			root = zfs_open(zhp->zfs_hdl, pool,
2091 			    ZFS_TYPE_FILESYSTEM);
2092 
2093 			(void) get_clones_cb(root, &gca);
2094 		}
2095 
2096 		if (gca.numclones != 0 ||
2097 		    nvlist_add_nvlist(nv, ZPROP_VALUE, value) != 0 ||
2098 		    nvlist_add_nvlist(zhp->zfs_props,
2099 		    zfs_prop_to_name(ZFS_PROP_CLONES), nv) != 0) {
2100 			nvlist_free(nv);
2101 			nvlist_free(value);
2102 			return (NULL);
2103 		}
2104 		nvlist_free(nv);
2105 		nvlist_free(value);
2106 		verify(0 == nvlist_lookup_nvlist(zhp->zfs_props,
2107 		    zfs_prop_to_name(ZFS_PROP_CLONES), &nv));
2108 	}
2109 
2110 	verify(nvlist_lookup_nvlist(nv, ZPROP_VALUE, &value) == 0);
2111 
2112 	return (value);
2113 }
2114 
2115 /*
2116  * Retrieve a property from the given object.  If 'literal' is specified, then
2117  * numbers are left as exact values.  Otherwise, numbers are converted to a
2118  * human-readable form.
2119  *
2120  * Returns 0 on success, or -1 on error.
2121  */
2122 int
2123 zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
2124     zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
2125 {
2126 	char *source = NULL;
2127 	uint64_t val;
2128 	char *str;
2129 	const char *strval;
2130 	boolean_t received = zfs_is_recvd_props_mode(zhp);
2131 
2132 	/*
2133 	 * Check to see if this property applies to our object
2134 	 */
2135 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
2136 		return (-1);
2137 
2138 	if (received && zfs_prop_readonly(prop))
2139 		return (-1);
2140 
2141 	if (src)
2142 		*src = ZPROP_SRC_NONE;
2143 
2144 	switch (prop) {
2145 	case ZFS_PROP_CREATION:
2146 		/*
2147 		 * 'creation' is a time_t stored in the statistics.  We convert
2148 		 * this into a string unless 'literal' is specified.
2149 		 */
2150 		{
2151 			val = getprop_uint64(zhp, prop, &source);
2152 			time_t time = (time_t)val;
2153 			struct tm t;
2154 
2155 			if (literal ||
2156 			    localtime_r(&time, &t) == NULL ||
2157 			    strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
2158 			    &t) == 0)
2159 				(void) snprintf(propbuf, proplen, "%llu", val);
2160 		}
2161 		break;
2162 
2163 	case ZFS_PROP_MOUNTPOINT:
2164 		/*
2165 		 * Getting the precise mountpoint can be tricky.
2166 		 *
2167 		 *  - for 'none' or 'legacy', return those values.
2168 		 *  - for inherited mountpoints, we want to take everything
2169 		 *    after our ancestor and append it to the inherited value.
2170 		 *
2171 		 * If the pool has an alternate root, we want to prepend that
2172 		 * root to any values we return.
2173 		 */
2174 
2175 		str = getprop_string(zhp, prop, &source);
2176 
2177 		if (str[0] == '/') {
2178 			char buf[MAXPATHLEN];
2179 			char *root = buf;
2180 			const char *relpath;
2181 
2182 			/*
2183 			 * If we inherit the mountpoint, even from a dataset
2184 			 * with a received value, the source will be the path of
2185 			 * the dataset we inherit from. If source is
2186 			 * ZPROP_SOURCE_VAL_RECVD, the received value is not
2187 			 * inherited.
2188 			 */
2189 			if (strcmp(source, ZPROP_SOURCE_VAL_RECVD) == 0) {
2190 				relpath = "";
2191 			} else {
2192 				relpath = zhp->zfs_name + strlen(source);
2193 				if (relpath[0] == '/')
2194 					relpath++;
2195 			}
2196 
2197 			if ((zpool_get_prop(zhp->zpool_hdl,
2198 			    ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL,
2199 			    B_FALSE)) || (strcmp(root, "-") == 0))
2200 				root[0] = '\0';
2201 			/*
2202 			 * Special case an alternate root of '/'. This will
2203 			 * avoid having multiple leading slashes in the
2204 			 * mountpoint path.
2205 			 */
2206 			if (strcmp(root, "/") == 0)
2207 				root++;
2208 
2209 			/*
2210 			 * If the mountpoint is '/' then skip over this
2211 			 * if we are obtaining either an alternate root or
2212 			 * an inherited mountpoint.
2213 			 */
2214 			if (str[1] == '\0' && (root[0] != '\0' ||
2215 			    relpath[0] != '\0'))
2216 				str++;
2217 
2218 			if (relpath[0] == '\0')
2219 				(void) snprintf(propbuf, proplen, "%s%s",
2220 				    root, str);
2221 			else
2222 				(void) snprintf(propbuf, proplen, "%s%s%s%s",
2223 				    root, str, relpath[0] == '@' ? "" : "/",
2224 				    relpath);
2225 		} else {
2226 			/* 'legacy' or 'none' */
2227 			(void) strlcpy(propbuf, str, proplen);
2228 		}
2229 
2230 		break;
2231 
2232 	case ZFS_PROP_ORIGIN:
2233 		(void) strlcpy(propbuf, getprop_string(zhp, prop, &source),
2234 		    proplen);
2235 		/*
2236 		 * If there is no parent at all, return failure to indicate that
2237 		 * it doesn't apply to this dataset.
2238 		 */
2239 		if (propbuf[0] == '\0')
2240 			return (-1);
2241 		break;
2242 
2243 	case ZFS_PROP_CLONES:
2244 		if (get_clones_string(zhp, propbuf, proplen) != 0)
2245 			return (-1);
2246 		break;
2247 
2248 	case ZFS_PROP_QUOTA:
2249 	case ZFS_PROP_REFQUOTA:
2250 	case ZFS_PROP_RESERVATION:
2251 	case ZFS_PROP_REFRESERVATION:
2252 
2253 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2254 			return (-1);
2255 
2256 		/*
2257 		 * If quota or reservation is 0, we translate this into 'none'
2258 		 * (unless literal is set), and indicate that it's the default
2259 		 * value.  Otherwise, we print the number nicely and indicate
2260 		 * that its set locally.
2261 		 */
2262 		if (val == 0) {
2263 			if (literal)
2264 				(void) strlcpy(propbuf, "0", proplen);
2265 			else
2266 				(void) strlcpy(propbuf, "none", proplen);
2267 		} else {
2268 			if (literal)
2269 				(void) snprintf(propbuf, proplen, "%llu",
2270 				    (u_longlong_t)val);
2271 			else
2272 				zfs_nicenum(val, propbuf, proplen);
2273 		}
2274 		break;
2275 
2276 	case ZFS_PROP_REFRATIO:
2277 	case ZFS_PROP_COMPRESSRATIO:
2278 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2279 			return (-1);
2280 		(void) snprintf(propbuf, proplen, "%llu.%02llux",
2281 		    (u_longlong_t)(val / 100),
2282 		    (u_longlong_t)(val % 100));
2283 		break;
2284 
2285 	case ZFS_PROP_TYPE:
2286 		switch (zhp->zfs_type) {
2287 		case ZFS_TYPE_FILESYSTEM:
2288 			str = "filesystem";
2289 			break;
2290 		case ZFS_TYPE_VOLUME:
2291 			str = "volume";
2292 			break;
2293 		case ZFS_TYPE_SNAPSHOT:
2294 			str = "snapshot";
2295 			break;
2296 		case ZFS_TYPE_BOOKMARK:
2297 			str = "bookmark";
2298 			break;
2299 		default:
2300 			abort();
2301 		}
2302 		(void) snprintf(propbuf, proplen, "%s", str);
2303 		break;
2304 
2305 	case ZFS_PROP_MOUNTED:
2306 		/*
2307 		 * The 'mounted' property is a pseudo-property that described
2308 		 * whether the filesystem is currently mounted.  Even though
2309 		 * it's a boolean value, the typical values of "on" and "off"
2310 		 * don't make sense, so we translate to "yes" and "no".
2311 		 */
2312 		if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
2313 		    src, &source, &val) != 0)
2314 			return (-1);
2315 		if (val)
2316 			(void) strlcpy(propbuf, "yes", proplen);
2317 		else
2318 			(void) strlcpy(propbuf, "no", proplen);
2319 		break;
2320 
2321 	case ZFS_PROP_NAME:
2322 		/*
2323 		 * The 'name' property is a pseudo-property derived from the
2324 		 * dataset name.  It is presented as a real property to simplify
2325 		 * consumers.
2326 		 */
2327 		(void) strlcpy(propbuf, zhp->zfs_name, proplen);
2328 		break;
2329 
2330 	case ZFS_PROP_MLSLABEL:
2331 		{
2332 			m_label_t *new_sl = NULL;
2333 			char *ascii = NULL;	/* human readable label */
2334 
2335 			(void) strlcpy(propbuf,
2336 			    getprop_string(zhp, prop, &source), proplen);
2337 
2338 			if (literal || (strcasecmp(propbuf,
2339 			    ZFS_MLSLABEL_DEFAULT) == 0))
2340 				break;
2341 
2342 			/*
2343 			 * Try to translate the internal hex string to
2344 			 * human-readable output.  If there are any
2345 			 * problems just use the hex string.
2346 			 */
2347 
2348 			if (str_to_label(propbuf, &new_sl, MAC_LABEL,
2349 			    L_NO_CORRECTION, NULL) == -1) {
2350 				m_label_free(new_sl);
2351 				break;
2352 			}
2353 
2354 			if (label_to_str(new_sl, &ascii, M_LABEL,
2355 			    DEF_NAMES) != 0) {
2356 				if (ascii)
2357 					free(ascii);
2358 				m_label_free(new_sl);
2359 				break;
2360 			}
2361 			m_label_free(new_sl);
2362 
2363 			(void) strlcpy(propbuf, ascii, proplen);
2364 			free(ascii);
2365 		}
2366 		break;
2367 
2368 	case ZFS_PROP_GUID:
2369 		/*
2370 		 * GUIDs are stored as numbers, but they are identifiers.
2371 		 * We don't want them to be pretty printed, because pretty
2372 		 * printing mangles the ID into a truncated and useless value.
2373 		 */
2374 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2375 			return (-1);
2376 		(void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val);
2377 		break;
2378 
2379 	default:
2380 		switch (zfs_prop_get_type(prop)) {
2381 		case PROP_TYPE_NUMBER:
2382 			if (get_numeric_property(zhp, prop, src,
2383 			    &source, &val) != 0)
2384 				return (-1);
2385 			if (literal)
2386 				(void) snprintf(propbuf, proplen, "%llu",
2387 				    (u_longlong_t)val);
2388 			else
2389 				zfs_nicenum(val, propbuf, proplen);
2390 			break;
2391 
2392 		case PROP_TYPE_STRING:
2393 			(void) strlcpy(propbuf,
2394 			    getprop_string(zhp, prop, &source), proplen);
2395 			break;
2396 
2397 		case PROP_TYPE_INDEX:
2398 			if (get_numeric_property(zhp, prop, src,
2399 			    &source, &val) != 0)
2400 				return (-1);
2401 			if (zfs_prop_index_to_string(prop, val, &strval) != 0)
2402 				return (-1);
2403 			(void) strlcpy(propbuf, strval, proplen);
2404 			break;
2405 
2406 		default:
2407 			abort();
2408 		}
2409 	}
2410 
2411 	get_source(zhp, src, source, statbuf, statlen);
2412 
2413 	return (0);
2414 }
2415 
2416 /*
2417  * Utility function to get the given numeric property.  Does no validation that
2418  * the given property is the appropriate type; should only be used with
2419  * hard-coded property types.
2420  */
2421 uint64_t
2422 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
2423 {
2424 	char *source;
2425 	uint64_t val;
2426 
2427 	(void) get_numeric_property(zhp, prop, NULL, &source, &val);
2428 
2429 	return (val);
2430 }
2431 
2432 int
2433 zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val)
2434 {
2435 	char buf[64];
2436 
2437 	(void) snprintf(buf, sizeof (buf), "%llu", (longlong_t)val);
2438 	return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf));
2439 }
2440 
2441 /*
2442  * Similar to zfs_prop_get(), but returns the value as an integer.
2443  */
2444 int
2445 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
2446     zprop_source_t *src, char *statbuf, size_t statlen)
2447 {
2448 	char *source;
2449 
2450 	/*
2451 	 * Check to see if this property applies to our object
2452 	 */
2453 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type)) {
2454 		return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
2455 		    dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
2456 		    zfs_prop_to_name(prop)));
2457 	}
2458 
2459 	if (src)
2460 		*src = ZPROP_SRC_NONE;
2461 
2462 	if (get_numeric_property(zhp, prop, src, &source, value) != 0)
2463 		return (-1);
2464 
2465 	get_source(zhp, src, source, statbuf, statlen);
2466 
2467 	return (0);
2468 }
2469 
2470 static int
2471 idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
2472     char **domainp, idmap_rid_t *ridp)
2473 {
2474 	idmap_get_handle_t *get_hdl = NULL;
2475 	idmap_stat status;
2476 	int err = EINVAL;
2477 
2478 	if (idmap_get_create(&get_hdl) != IDMAP_SUCCESS)
2479 		goto out;
2480 
2481 	if (isuser) {
2482 		err = idmap_get_sidbyuid(get_hdl, id,
2483 		    IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
2484 	} else {
2485 		err = idmap_get_sidbygid(get_hdl, id,
2486 		    IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
2487 	}
2488 	if (err == IDMAP_SUCCESS &&
2489 	    idmap_get_mappings(get_hdl) == IDMAP_SUCCESS &&
2490 	    status == IDMAP_SUCCESS)
2491 		err = 0;
2492 	else
2493 		err = EINVAL;
2494 out:
2495 	if (get_hdl)
2496 		idmap_get_destroy(get_hdl);
2497 	return (err);
2498 }
2499 
2500 /*
2501  * convert the propname into parameters needed by kernel
2502  * Eg: userquota@ahrens -> ZFS_PROP_USERQUOTA, "", 126829
2503  * Eg: userused@matt@domain -> ZFS_PROP_USERUSED, "S-1-123-456", 789
2504  */
2505 static int
2506 userquota_propname_decode(const char *propname, boolean_t zoned,
2507     zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp)
2508 {
2509 	zfs_userquota_prop_t type;
2510 	char *cp, *end;
2511 	char *numericsid = NULL;
2512 	boolean_t isuser;
2513 
2514 	domain[0] = '\0';
2515 
2516 	/* Figure out the property type ({user|group}{quota|space}) */
2517 	for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
2518 		if (strncmp(propname, zfs_userquota_prop_prefixes[type],
2519 		    strlen(zfs_userquota_prop_prefixes[type])) == 0)
2520 			break;
2521 	}
2522 	if (type == ZFS_NUM_USERQUOTA_PROPS)
2523 		return (EINVAL);
2524 	*typep = type;
2525 
2526 	isuser = (type == ZFS_PROP_USERQUOTA ||
2527 	    type == ZFS_PROP_USERUSED);
2528 
2529 	cp = strchr(propname, '@') + 1;
2530 
2531 	if (strchr(cp, '@')) {
2532 		/*
2533 		 * It's a SID name (eg "user@domain") that needs to be
2534 		 * turned into S-1-domainID-RID.
2535 		 */
2536 		directory_error_t e;
2537 		if (zoned && getzoneid() == GLOBAL_ZONEID)
2538 			return (ENOENT);
2539 		if (isuser) {
2540 			e = directory_sid_from_user_name(NULL,
2541 			    cp, &numericsid);
2542 		} else {
2543 			e = directory_sid_from_group_name(NULL,
2544 			    cp, &numericsid);
2545 		}
2546 		if (e != NULL) {
2547 			directory_error_free(e);
2548 			return (ENOENT);
2549 		}
2550 		if (numericsid == NULL)
2551 			return (ENOENT);
2552 		cp = numericsid;
2553 		/* will be further decoded below */
2554 	}
2555 
2556 	if (strncmp(cp, "S-1-", 4) == 0) {
2557 		/* It's a numeric SID (eg "S-1-234-567-89") */
2558 		(void) strlcpy(domain, cp, domainlen);
2559 		cp = strrchr(domain, '-');
2560 		*cp = '\0';
2561 		cp++;
2562 
2563 		errno = 0;
2564 		*ridp = strtoull(cp, &end, 10);
2565 		if (numericsid) {
2566 			free(numericsid);
2567 			numericsid = NULL;
2568 		}
2569 		if (errno != 0 || *end != '\0')
2570 			return (EINVAL);
2571 	} else if (!isdigit(*cp)) {
2572 		/*
2573 		 * It's a user/group name (eg "user") that needs to be
2574 		 * turned into a uid/gid
2575 		 */
2576 		if (zoned && getzoneid() == GLOBAL_ZONEID)
2577 			return (ENOENT);
2578 		if (isuser) {
2579 			struct passwd *pw;
2580 			pw = getpwnam(cp);
2581 			if (pw == NULL)
2582 				return (ENOENT);
2583 			*ridp = pw->pw_uid;
2584 		} else {
2585 			struct group *gr;
2586 			gr = getgrnam(cp);
2587 			if (gr == NULL)
2588 				return (ENOENT);
2589 			*ridp = gr->gr_gid;
2590 		}
2591 	} else {
2592 		/* It's a user/group ID (eg "12345"). */
2593 		uid_t id = strtoul(cp, &end, 10);
2594 		idmap_rid_t rid;
2595 		char *mapdomain;
2596 
2597 		if (*end != '\0')
2598 			return (EINVAL);
2599 		if (id > MAXUID) {
2600 			/* It's an ephemeral ID. */
2601 			if (idmap_id_to_numeric_domain_rid(id, isuser,
2602 			    &mapdomain, &rid) != 0)
2603 				return (ENOENT);
2604 			(void) strlcpy(domain, mapdomain, domainlen);
2605 			*ridp = rid;
2606 		} else {
2607 			*ridp = id;
2608 		}
2609 	}
2610 
2611 	ASSERT3P(numericsid, ==, NULL);
2612 	return (0);
2613 }
2614 
2615 static int
2616 zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname,
2617     uint64_t *propvalue, zfs_userquota_prop_t *typep)
2618 {
2619 	int err;
2620 	zfs_cmd_t zc = { 0 };
2621 
2622 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2623 
2624 	err = userquota_propname_decode(propname,
2625 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED),
2626 	    typep, zc.zc_value, sizeof (zc.zc_value), &zc.zc_guid);
2627 	zc.zc_objset_type = *typep;
2628 	if (err)
2629 		return (err);
2630 
2631 	err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_USERSPACE_ONE, &zc);
2632 	if (err)
2633 		return (err);
2634 
2635 	*propvalue = zc.zc_cookie;
2636 	return (0);
2637 }
2638 
2639 int
2640 zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname,
2641     uint64_t *propvalue)
2642 {
2643 	zfs_userquota_prop_t type;
2644 
2645 	return (zfs_prop_get_userquota_common(zhp, propname, propvalue,
2646 	    &type));
2647 }
2648 
2649 int
2650 zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
2651     char *propbuf, int proplen, boolean_t literal)
2652 {
2653 	int err;
2654 	uint64_t propvalue;
2655 	zfs_userquota_prop_t type;
2656 
2657 	err = zfs_prop_get_userquota_common(zhp, propname, &propvalue,
2658 	    &type);
2659 
2660 	if (err)
2661 		return (err);
2662 
2663 	if (literal) {
2664 		(void) snprintf(propbuf, proplen, "%llu", propvalue);
2665 	} else if (propvalue == 0 &&
2666 	    (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA)) {
2667 		(void) strlcpy(propbuf, "none", proplen);
2668 	} else {
2669 		zfs_nicenum(propvalue, propbuf, proplen);
2670 	}
2671 	return (0);
2672 }
2673 
2674 int
2675 zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
2676     uint64_t *propvalue)
2677 {
2678 	int err;
2679 	zfs_cmd_t zc = { 0 };
2680 	const char *snapname;
2681 
2682 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2683 
2684 	snapname = strchr(propname, '@') + 1;
2685 	if (strchr(snapname, '@')) {
2686 		(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
2687 	} else {
2688 		/* snapname is the short name, append it to zhp's fsname */
2689 		char *cp;
2690 
2691 		(void) strlcpy(zc.zc_value, zhp->zfs_name,
2692 		    sizeof (zc.zc_value));
2693 		cp = strchr(zc.zc_value, '@');
2694 		if (cp != NULL)
2695 			*cp = '\0';
2696 		(void) strlcat(zc.zc_value, "@", sizeof (zc.zc_value));
2697 		(void) strlcat(zc.zc_value, snapname, sizeof (zc.zc_value));
2698 	}
2699 
2700 	err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SPACE_WRITTEN, &zc);
2701 	if (err)
2702 		return (err);
2703 
2704 	*propvalue = zc.zc_cookie;
2705 	return (0);
2706 }
2707 
2708 int
2709 zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
2710     char *propbuf, int proplen, boolean_t literal)
2711 {
2712 	int err;
2713 	uint64_t propvalue;
2714 
2715 	err = zfs_prop_get_written_int(zhp, propname, &propvalue);
2716 
2717 	if (err)
2718 		return (err);
2719 
2720 	if (literal) {
2721 		(void) snprintf(propbuf, proplen, "%llu", propvalue);
2722 	} else {
2723 		zfs_nicenum(propvalue, propbuf, proplen);
2724 	}
2725 	return (0);
2726 }
2727 
2728 /*
2729  * Returns the name of the given zfs handle.
2730  */
2731 const char *
2732 zfs_get_name(const zfs_handle_t *zhp)
2733 {
2734 	return (zhp->zfs_name);
2735 }
2736 
2737 /*
2738  * Returns the type of the given zfs handle.
2739  */
2740 zfs_type_t
2741 zfs_get_type(const zfs_handle_t *zhp)
2742 {
2743 	return (zhp->zfs_type);
2744 }
2745 
2746 /*
2747  * Is one dataset name a child dataset of another?
2748  *
2749  * Needs to handle these cases:
2750  * Dataset 1	"a/foo"		"a/foo"		"a/foo"		"a/foo"
2751  * Dataset 2	"a/fo"		"a/foobar"	"a/bar/baz"	"a/foo/bar"
2752  * Descendant?	No.		No.		No.		Yes.
2753  */
2754 static boolean_t
2755 is_descendant(const char *ds1, const char *ds2)
2756 {
2757 	size_t d1len = strlen(ds1);
2758 
2759 	/* ds2 can't be a descendant if it's smaller */
2760 	if (strlen(ds2) < d1len)
2761 		return (B_FALSE);
2762 
2763 	/* otherwise, compare strings and verify that there's a '/' char */
2764 	return (ds2[d1len] == '/' && (strncmp(ds1, ds2, d1len) == 0));
2765 }
2766 
2767 /*
2768  * Given a complete name, return just the portion that refers to the parent.
2769  * Will return -1 if there is no parent (path is just the name of the
2770  * pool).
2771  */
2772 static int
2773 parent_name(const char *path, char *buf, size_t buflen)
2774 {
2775 	char *slashp;
2776 
2777 	(void) strlcpy(buf, path, buflen);
2778 
2779 	if ((slashp = strrchr(buf, '/')) == NULL)
2780 		return (-1);
2781 	*slashp = '\0';
2782 
2783 	return (0);
2784 }
2785 
2786 /*
2787  * If accept_ancestor is false, then check to make sure that the given path has
2788  * a parent, and that it exists.  If accept_ancestor is true, then find the
2789  * closest existing ancestor for the given path.  In prefixlen return the
2790  * length of already existing prefix of the given path.  We also fetch the
2791  * 'zoned' property, which is used to validate property settings when creating
2792  * new datasets.
2793  */
2794 static int
2795 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
2796     boolean_t accept_ancestor, int *prefixlen)
2797 {
2798 	zfs_cmd_t zc = { 0 };
2799 	char parent[ZFS_MAXNAMELEN];
2800 	char *slash;
2801 	zfs_handle_t *zhp;
2802 	char errbuf[1024];
2803 	uint64_t is_zoned;
2804 
2805 	(void) snprintf(errbuf, sizeof (errbuf),
2806 	    dgettext(TEXT_DOMAIN, "cannot create '%s'"), path);
2807 
2808 	/* get parent, and check to see if this is just a pool */
2809 	if (parent_name(path, parent, sizeof (parent)) != 0) {
2810 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2811 		    "missing dataset name"));
2812 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2813 	}
2814 
2815 	/* check to see if the pool exists */
2816 	if ((slash = strchr(parent, '/')) == NULL)
2817 		slash = parent + strlen(parent);
2818 	(void) strncpy(zc.zc_name, parent, slash - parent);
2819 	zc.zc_name[slash - parent] = '\0';
2820 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
2821 	    errno == ENOENT) {
2822 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2823 		    "no such pool '%s'"), zc.zc_name);
2824 		return (zfs_error(hdl, EZFS_NOENT, errbuf));
2825 	}
2826 
2827 	/* check to see if the parent dataset exists */
2828 	while ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
2829 		if (errno == ENOENT && accept_ancestor) {
2830 			/*
2831 			 * Go deeper to find an ancestor, give up on top level.
2832 			 */
2833 			if (parent_name(parent, parent, sizeof (parent)) != 0) {
2834 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2835 				    "no such pool '%s'"), zc.zc_name);
2836 				return (zfs_error(hdl, EZFS_NOENT, errbuf));
2837 			}
2838 		} else if (errno == ENOENT) {
2839 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2840 			    "parent does not exist"));
2841 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
2842 		} else
2843 			return (zfs_standard_error(hdl, errno, errbuf));
2844 	}
2845 
2846 	is_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
2847 	if (zoned != NULL)
2848 		*zoned = is_zoned;
2849 
2850 	/* we are in a non-global zone, but parent is in the global zone */
2851 	if (getzoneid() != GLOBAL_ZONEID && !is_zoned) {
2852 		(void) zfs_standard_error(hdl, EPERM, errbuf);
2853 		zfs_close(zhp);
2854 		return (-1);
2855 	}
2856 
2857 	/* make sure parent is a filesystem */
2858 	if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
2859 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2860 		    "parent is not a filesystem"));
2861 		(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
2862 		zfs_close(zhp);
2863 		return (-1);
2864 	}
2865 
2866 	zfs_close(zhp);
2867 	if (prefixlen != NULL)
2868 		*prefixlen = strlen(parent);
2869 	return (0);
2870 }
2871 
2872 /*
2873  * Finds whether the dataset of the given type(s) exists.
2874  */
2875 boolean_t
2876 zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types)
2877 {
2878 	zfs_handle_t *zhp;
2879 
2880 	if (!zfs_validate_name(hdl, path, types, B_FALSE))
2881 		return (B_FALSE);
2882 
2883 	/*
2884 	 * Try to get stats for the dataset, which will tell us if it exists.
2885 	 */
2886 	if ((zhp = make_dataset_handle(hdl, path)) != NULL) {
2887 		int ds_type = zhp->zfs_type;
2888 
2889 		zfs_close(zhp);
2890 		if (types & ds_type)
2891 			return (B_TRUE);
2892 	}
2893 	return (B_FALSE);
2894 }
2895 
2896 /*
2897  * Given a path to 'target', create all the ancestors between
2898  * the prefixlen portion of the path, and the target itself.
2899  * Fail if the initial prefixlen-ancestor does not already exist.
2900  */
2901 int
2902 create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
2903 {
2904 	zfs_handle_t *h;
2905 	char *cp;
2906 	const char *opname;
2907 
2908 	/* make sure prefix exists */
2909 	cp = target + prefixlen;
2910 	if (*cp != '/') {
2911 		assert(strchr(cp, '/') == NULL);
2912 		h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2913 	} else {
2914 		*cp = '\0';
2915 		h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2916 		*cp = '/';
2917 	}
2918 	if (h == NULL)
2919 		return (-1);
2920 	zfs_close(h);
2921 
2922 	/*
2923 	 * Attempt to create, mount, and share any ancestor filesystems,
2924 	 * up to the prefixlen-long one.
2925 	 */
2926 	for (cp = target + prefixlen + 1;
2927 	    cp = strchr(cp, '/'); *cp = '/', cp++) {
2928 
2929 		*cp = '\0';
2930 
2931 		h = make_dataset_handle(hdl, target);
2932 		if (h) {
2933 			/* it already exists, nothing to do here */
2934 			zfs_close(h);
2935 			continue;
2936 		}
2937 
2938 		if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
2939 		    NULL) != 0) {
2940 			opname = dgettext(TEXT_DOMAIN, "create");
2941 			goto ancestorerr;
2942 		}
2943 
2944 		h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2945 		if (h == NULL) {
2946 			opname = dgettext(TEXT_DOMAIN, "open");
2947 			goto ancestorerr;
2948 		}
2949 
2950 		if (zfs_mount(h, NULL, 0) != 0) {
2951 			opname = dgettext(TEXT_DOMAIN, "mount");
2952 			goto ancestorerr;
2953 		}
2954 
2955 		if (zfs_share(h) != 0) {
2956 			opname = dgettext(TEXT_DOMAIN, "share");
2957 			goto ancestorerr;
2958 		}
2959 
2960 		zfs_close(h);
2961 	}
2962 
2963 	return (0);
2964 
2965 ancestorerr:
2966 	zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2967 	    "failed to %s ancestor '%s'"), opname, target);
2968 	return (-1);
2969 }
2970 
2971 /*
2972  * Creates non-existing ancestors of the given path.
2973  */
2974 int
2975 zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
2976 {
2977 	int prefix;
2978 	char *path_copy;
2979 	int rc;
2980 
2981 	if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
2982 		return (-1);
2983 
2984 	if ((path_copy = strdup(path)) != NULL) {
2985 		rc = create_parents(hdl, path_copy, prefix);
2986 		free(path_copy);
2987 	}
2988 	if (path_copy == NULL || rc != 0)
2989 		return (-1);
2990 
2991 	return (0);
2992 }
2993 
2994 /*
2995  * Create a new filesystem or volume.
2996  */
2997 int
2998 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
2999     nvlist_t *props)
3000 {
3001 	int ret;
3002 	uint64_t size = 0;
3003 	uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
3004 	char errbuf[1024];
3005 	uint64_t zoned;
3006 	dmu_objset_type_t ost;
3007 
3008 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3009 	    "cannot create '%s'"), path);
3010 
3011 	/* validate the path, taking care to note the extended error message */
3012 	if (!zfs_validate_name(hdl, path, type, B_TRUE))
3013 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3014 
3015 	/* validate parents exist */
3016 	if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
3017 		return (-1);
3018 
3019 	/*
3020 	 * The failure modes when creating a dataset of a different type over
3021 	 * one that already exists is a little strange.  In particular, if you
3022 	 * try to create a dataset on top of an existing dataset, the ioctl()
3023 	 * will return ENOENT, not EEXIST.  To prevent this from happening, we
3024 	 * first try to see if the dataset exists.
3025 	 */
3026 	if (zfs_dataset_exists(hdl, path, ZFS_TYPE_DATASET)) {
3027 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3028 		    "dataset already exists"));
3029 		return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3030 	}
3031 
3032 	if (type == ZFS_TYPE_VOLUME)
3033 		ost = DMU_OST_ZVOL;
3034 	else
3035 		ost = DMU_OST_ZFS;
3036 
3037 	if (props && (props = zfs_valid_proplist(hdl, type, props,
3038 	    zoned, NULL, errbuf)) == 0)
3039 		return (-1);
3040 
3041 	if (type == ZFS_TYPE_VOLUME) {
3042 		/*
3043 		 * If we are creating a volume, the size and block size must
3044 		 * satisfy a few restraints.  First, the blocksize must be a
3045 		 * valid block size between SPA_{MIN,MAX}BLOCKSIZE.  Second, the
3046 		 * volsize must be a multiple of the block size, and cannot be
3047 		 * zero.
3048 		 */
3049 		if (props == NULL || nvlist_lookup_uint64(props,
3050 		    zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
3051 			nvlist_free(props);
3052 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3053 			    "missing volume size"));
3054 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3055 		}
3056 
3057 		if ((ret = nvlist_lookup_uint64(props,
3058 		    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
3059 		    &blocksize)) != 0) {
3060 			if (ret == ENOENT) {
3061 				blocksize = zfs_prop_default_numeric(
3062 				    ZFS_PROP_VOLBLOCKSIZE);
3063 			} else {
3064 				nvlist_free(props);
3065 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3066 				    "missing volume block size"));
3067 				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3068 			}
3069 		}
3070 
3071 		if (size == 0) {
3072 			nvlist_free(props);
3073 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3074 			    "volume size cannot be zero"));
3075 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3076 		}
3077 
3078 		if (size % blocksize != 0) {
3079 			nvlist_free(props);
3080 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3081 			    "volume size must be a multiple of volume block "
3082 			    "size"));
3083 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3084 		}
3085 	}
3086 
3087 	/* create the dataset */
3088 	ret = lzc_create(path, ost, props);
3089 	nvlist_free(props);
3090 
3091 	/* check for failure */
3092 	if (ret != 0) {
3093 		char parent[ZFS_MAXNAMELEN];
3094 		(void) parent_name(path, parent, sizeof (parent));
3095 
3096 		switch (errno) {
3097 		case ENOENT:
3098 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3099 			    "no such parent '%s'"), parent);
3100 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
3101 
3102 		case EINVAL:
3103 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3104 			    "parent '%s' is not a filesystem"), parent);
3105 			return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3106 
3107 		case EDOM:
3108 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3109 			    "volume block size must be power of 2 from "
3110 			    "%u to %uk"),
3111 			    (uint_t)SPA_MINBLOCKSIZE,
3112 			    (uint_t)SPA_MAXBLOCKSIZE >> 10);
3113 
3114 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3115 
3116 		case ENOTSUP:
3117 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3118 			    "pool must be upgraded to set this "
3119 			    "property or value"));
3120 			return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
3121 #ifdef _ILP32
3122 		case EOVERFLOW:
3123 			/*
3124 			 * This platform can't address a volume this big.
3125 			 */
3126 			if (type == ZFS_TYPE_VOLUME)
3127 				return (zfs_error(hdl, EZFS_VOLTOOBIG,
3128 				    errbuf));
3129 #endif
3130 			/* FALLTHROUGH */
3131 		default:
3132 			return (zfs_standard_error(hdl, errno, errbuf));
3133 		}
3134 	}
3135 
3136 	return (0);
3137 }
3138 
3139 /*
3140  * Destroys the given dataset.  The caller must make sure that the filesystem
3141  * isn't mounted, and that there are no active dependents. If the file system
3142  * does not exist this function does nothing.
3143  */
3144 int
3145 zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
3146 {
3147 	zfs_cmd_t zc = { 0 };
3148 
3149 	if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
3150 		nvlist_t *nv = fnvlist_alloc();
3151 		fnvlist_add_boolean(nv, zhp->zfs_name);
3152 		int error = lzc_destroy_bookmarks(nv, NULL);
3153 		fnvlist_free(nv);
3154 		if (error != 0) {
3155 			return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3156 			    dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3157 			    zhp->zfs_name));
3158 		}
3159 		return (0);
3160 	}
3161 
3162 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3163 
3164 	if (ZFS_IS_VOLUME(zhp)) {
3165 		zc.zc_objset_type = DMU_OST_ZVOL;
3166 	} else {
3167 		zc.zc_objset_type = DMU_OST_ZFS;
3168 	}
3169 
3170 	zc.zc_defer_destroy = defer;
3171 	if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY, &zc) != 0 &&
3172 	    errno != ENOENT) {
3173 		return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3174 		    dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3175 		    zhp->zfs_name));
3176 	}
3177 
3178 	remove_mountpoint(zhp);
3179 
3180 	return (0);
3181 }
3182 
3183 struct destroydata {
3184 	nvlist_t *nvl;
3185 	const char *snapname;
3186 };
3187 
3188 static int
3189 zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
3190 {
3191 	struct destroydata *dd = arg;
3192 	char name[ZFS_MAXNAMELEN];
3193 	int rv = 0;
3194 
3195 	(void) snprintf(name, sizeof (name),
3196 	    "%s@%s", zhp->zfs_name, dd->snapname);
3197 
3198 	if (lzc_exists(name))
3199 		verify(nvlist_add_boolean(dd->nvl, name) == 0);
3200 
3201 	rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, dd);
3202 	zfs_close(zhp);
3203 	return (rv);
3204 }
3205 
3206 /*
3207  * Destroys all snapshots with the given name in zhp & descendants.
3208  */
3209 int
3210 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
3211 {
3212 	int ret;
3213 	struct destroydata dd = { 0 };
3214 
3215 	dd.snapname = snapname;
3216 	verify(nvlist_alloc(&dd.nvl, NV_UNIQUE_NAME, 0) == 0);
3217 	(void) zfs_check_snap_cb(zfs_handle_dup(zhp), &dd);
3218 
3219 	if (nvlist_empty(dd.nvl)) {
3220 		ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
3221 		    dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
3222 		    zhp->zfs_name, snapname);
3223 	} else {
3224 		ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer);
3225 	}
3226 	nvlist_free(dd.nvl);
3227 	return (ret);
3228 }
3229 
3230 /*
3231  * Destroys all the snapshots named in the nvlist.
3232  */
3233 int
3234 zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
3235 {
3236 	int ret;
3237 	nvlist_t *errlist;
3238 
3239 	ret = lzc_destroy_snaps(snaps, defer, &errlist);
3240 
3241 	if (ret == 0)
3242 		return (0);
3243 
3244 	if (nvlist_empty(errlist)) {
3245 		char errbuf[1024];
3246 		(void) snprintf(errbuf, sizeof (errbuf),
3247 		    dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
3248 
3249 		ret = zfs_standard_error(hdl, ret, errbuf);
3250 	}
3251 	for (nvpair_t *pair = nvlist_next_nvpair(errlist, NULL);
3252 	    pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
3253 		char errbuf[1024];
3254 		(void) snprintf(errbuf, sizeof (errbuf),
3255 		    dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
3256 		    nvpair_name(pair));
3257 
3258 		switch (fnvpair_value_int32(pair)) {
3259 		case EEXIST:
3260 			zfs_error_aux(hdl,
3261 			    dgettext(TEXT_DOMAIN, "snapshot is cloned"));
3262 			ret = zfs_error(hdl, EZFS_EXISTS, errbuf);
3263 			break;
3264 		default:
3265 			ret = zfs_standard_error(hdl, errno, errbuf);
3266 			break;
3267 		}
3268 	}
3269 
3270 	return (ret);
3271 }
3272 
3273 /*
3274  * Clones the given dataset.  The target must be of the same type as the source.
3275  */
3276 int
3277 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
3278 {
3279 	char parent[ZFS_MAXNAMELEN];
3280 	int ret;
3281 	char errbuf[1024];
3282 	libzfs_handle_t *hdl = zhp->zfs_hdl;
3283 	uint64_t zoned;
3284 
3285 	assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
3286 
3287 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3288 	    "cannot create '%s'"), target);
3289 
3290 	/* validate the target/clone name */
3291 	if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
3292 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3293 
3294 	/* validate parents exist */
3295 	if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
3296 		return (-1);
3297 
3298 	(void) parent_name(target, parent, sizeof (parent));
3299 
3300 	/* do the clone */
3301 
3302 	if (props) {
3303 		zfs_type_t type;
3304 		if (ZFS_IS_VOLUME(zhp)) {
3305 			type = ZFS_TYPE_VOLUME;
3306 		} else {
3307 			type = ZFS_TYPE_FILESYSTEM;
3308 		}
3309 		if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3310 		    zhp, errbuf)) == NULL)
3311 			return (-1);
3312 	}
3313 
3314 	ret = lzc_clone(target, zhp->zfs_name, props);
3315 	nvlist_free(props);
3316 
3317 	if (ret != 0) {
3318 		switch (errno) {
3319 
3320 		case ENOENT:
3321 			/*
3322 			 * The parent doesn't exist.  We should have caught this
3323 			 * above, but there may a race condition that has since
3324 			 * destroyed the parent.
3325 			 *
3326 			 * At this point, we don't know whether it's the source
3327 			 * that doesn't exist anymore, or whether the target
3328 			 * dataset doesn't exist.
3329 			 */
3330 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3331 			    "no such parent '%s'"), parent);
3332 			return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
3333 
3334 		case EXDEV:
3335 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3336 			    "source and target pools differ"));
3337 			return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
3338 			    errbuf));
3339 
3340 		default:
3341 			return (zfs_standard_error(zhp->zfs_hdl, errno,
3342 			    errbuf));
3343 		}
3344 	}
3345 
3346 	return (ret);
3347 }
3348 
3349 /*
3350  * Promotes the given clone fs to be the clone parent.
3351  */
3352 int
3353 zfs_promote(zfs_handle_t *zhp)
3354 {
3355 	libzfs_handle_t *hdl = zhp->zfs_hdl;
3356 	zfs_cmd_t zc = { 0 };
3357 	char parent[MAXPATHLEN];
3358 	int ret;
3359 	char errbuf[1024];
3360 
3361 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3362 	    "cannot promote '%s'"), zhp->zfs_name);
3363 
3364 	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3365 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3366 		    "snapshots can not be promoted"));
3367 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3368 	}
3369 
3370 	(void) strlcpy(parent, zhp->zfs_dmustats.dds_origin, sizeof (parent));
3371 	if (parent[0] == '\0') {
3372 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3373 		    "not a cloned filesystem"));
3374 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3375 	}
3376 
3377 	(void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_origin,
3378 	    sizeof (zc.zc_value));
3379 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3380 	ret = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
3381 
3382 	if (ret != 0) {
3383 		int save_errno = errno;
3384 
3385 		switch (save_errno) {
3386 		case EEXIST:
3387 			/* There is a conflicting snapshot name. */
3388 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3389 			    "conflicting snapshot '%s' from parent '%s'"),
3390 			    zc.zc_string, parent);
3391 			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3392 
3393 		default:
3394 			return (zfs_standard_error(hdl, save_errno, errbuf));
3395 		}
3396 	}
3397 	return (ret);
3398 }
3399 
3400 typedef struct snapdata {
3401 	nvlist_t *sd_nvl;
3402 	const char *sd_snapname;
3403 } snapdata_t;
3404 
3405 static int
3406 zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
3407 {
3408 	snapdata_t *sd = arg;
3409 	char name[ZFS_MAXNAMELEN];
3410 	int rv = 0;
3411 
3412 	if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
3413 		(void) snprintf(name, sizeof (name),
3414 		    "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
3415 
3416 		fnvlist_add_boolean(sd->sd_nvl, name);
3417 
3418 		rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
3419 	}
3420 	zfs_close(zhp);
3421 
3422 	return (rv);
3423 }
3424 
3425 /*
3426  * Creates snapshots.  The keys in the snaps nvlist are the snapshots to be
3427  * created.
3428  */
3429 int
3430 zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
3431 {
3432 	int ret;
3433 	char errbuf[1024];
3434 	nvpair_t *elem;
3435 	nvlist_t *errors;
3436 
3437 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3438 	    "cannot create snapshots "));
3439 
3440 	elem = NULL;
3441 	while ((elem = nvlist_next_nvpair(snaps, elem)) != NULL) {
3442 		const char *snapname = nvpair_name(elem);
3443 
3444 		/* validate the target name */
3445 		if (!zfs_validate_name(hdl, snapname, ZFS_TYPE_SNAPSHOT,
3446 		    B_TRUE)) {
3447 			(void) snprintf(errbuf, sizeof (errbuf),
3448 			    dgettext(TEXT_DOMAIN,
3449 			    "cannot create snapshot '%s'"), snapname);
3450 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3451 		}
3452 	}
3453 
3454 	if (props != NULL &&
3455 	    (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
3456 	    props, B_FALSE, NULL, errbuf)) == NULL) {
3457 		return (-1);
3458 	}
3459 
3460 	ret = lzc_snapshot(snaps, props, &errors);
3461 
3462 	if (ret != 0) {
3463 		boolean_t printed = B_FALSE;
3464 		for (elem = nvlist_next_nvpair(errors, NULL);
3465 		    elem != NULL;
3466 		    elem = nvlist_next_nvpair(errors, elem)) {
3467 			(void) snprintf(errbuf, sizeof (errbuf),
3468 			    dgettext(TEXT_DOMAIN,
3469 			    "cannot create snapshot '%s'"), nvpair_name(elem));
3470 			(void) zfs_standard_error(hdl,
3471 			    fnvpair_value_int32(elem), errbuf);
3472 			printed = B_TRUE;
3473 		}
3474 		if (!printed) {
3475 			switch (ret) {
3476 			case EXDEV:
3477 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3478 				    "multiple snapshots of same "
3479 				    "fs not allowed"));
3480 				(void) zfs_error(hdl, EZFS_EXISTS, errbuf);
3481 
3482 				break;
3483 			default:
3484 				(void) zfs_standard_error(hdl, ret, errbuf);
3485 			}
3486 		}
3487 	}
3488 
3489 	nvlist_free(props);
3490 	nvlist_free(errors);
3491 	return (ret);
3492 }
3493 
3494 int
3495 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
3496     nvlist_t *props)
3497 {
3498 	int ret;
3499 	snapdata_t sd = { 0 };
3500 	char fsname[ZFS_MAXNAMELEN];
3501 	char *cp;
3502 	zfs_handle_t *zhp;
3503 	char errbuf[1024];
3504 
3505 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3506 	    "cannot snapshot %s"), path);
3507 
3508 	if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
3509 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3510 
3511 	(void) strlcpy(fsname, path, sizeof (fsname));
3512 	cp = strchr(fsname, '@');
3513 	*cp = '\0';
3514 	sd.sd_snapname = cp + 1;
3515 
3516 	if ((zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM |
3517 	    ZFS_TYPE_VOLUME)) == NULL) {
3518 		return (-1);
3519 	}
3520 
3521 	verify(nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) == 0);
3522 	if (recursive) {
3523 		(void) zfs_snapshot_cb(zfs_handle_dup(zhp), &sd);
3524 	} else {
3525 		fnvlist_add_boolean(sd.sd_nvl, path);
3526 	}
3527 
3528 	ret = zfs_snapshot_nvl(hdl, sd.sd_nvl, props);
3529 	nvlist_free(sd.sd_nvl);
3530 	zfs_close(zhp);
3531 	return (ret);
3532 }
3533 
3534 /*
3535  * Destroy any more recent snapshots.  We invoke this callback on any dependents
3536  * of the snapshot first.  If the 'cb_dependent' member is non-zero, then this
3537  * is a dependent and we should just destroy it without checking the transaction
3538  * group.
3539  */
3540 typedef struct rollback_data {
3541 	const char	*cb_target;		/* the snapshot */
3542 	uint64_t	cb_create;		/* creation time reference */
3543 	boolean_t	cb_error;
3544 	boolean_t	cb_force;
3545 } rollback_data_t;
3546 
3547 static int
3548 rollback_destroy_dependent(zfs_handle_t *zhp, void *data)
3549 {
3550 	rollback_data_t *cbp = data;
3551 	prop_changelist_t *clp;
3552 
3553 	/* We must destroy this clone; first unmount it */
3554 	clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
3555 	    cbp->cb_force ? MS_FORCE: 0);
3556 	if (clp == NULL || changelist_prefix(clp) != 0) {
3557 		cbp->cb_error = B_TRUE;
3558 		zfs_close(zhp);
3559 		return (0);
3560 	}
3561 	if (zfs_destroy(zhp, B_FALSE) != 0)
3562 		cbp->cb_error = B_TRUE;
3563 	else
3564 		changelist_remove(clp, zhp->zfs_name);
3565 	(void) changelist_postfix(clp);
3566 	changelist_free(clp);
3567 
3568 	zfs_close(zhp);
3569 	return (0);
3570 }
3571 
3572 static int
3573 rollback_destroy(zfs_handle_t *zhp, void *data)
3574 {
3575 	rollback_data_t *cbp = data;
3576 
3577 	if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) {
3578 		cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
3579 		    rollback_destroy_dependent, cbp);
3580 
3581 		cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
3582 	}
3583 
3584 	zfs_close(zhp);
3585 	return (0);
3586 }
3587 
3588 /*
3589  * Given a dataset, rollback to a specific snapshot, discarding any
3590  * data changes since then and making it the active dataset.
3591  *
3592  * Any snapshots and bookmarks more recent than the target are
3593  * destroyed, along with their dependents (i.e. clones).
3594  */
3595 int
3596 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
3597 {
3598 	rollback_data_t cb = { 0 };
3599 	int err;
3600 	boolean_t restore_resv = 0;
3601 	uint64_t old_volsize, new_volsize;
3602 	zfs_prop_t resv_prop;
3603 
3604 	assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
3605 	    zhp->zfs_type == ZFS_TYPE_VOLUME);
3606 
3607 	/*
3608 	 * Destroy all recent snapshots and their dependents.
3609 	 */
3610 	cb.cb_force = force;
3611 	cb.cb_target = snap->zfs_name;
3612 	cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
3613 	(void) zfs_iter_snapshots(zhp, rollback_destroy, &cb);
3614 	(void) zfs_iter_bookmarks(zhp, rollback_destroy, &cb);
3615 
3616 	if (cb.cb_error)
3617 		return (-1);
3618 
3619 	/*
3620 	 * Now that we have verified that the snapshot is the latest,
3621 	 * rollback to the given snapshot.
3622 	 */
3623 
3624 	if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3625 		if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
3626 			return (-1);
3627 		old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
3628 		restore_resv =
3629 		    (old_volsize == zfs_prop_get_int(zhp, resv_prop));
3630 	}
3631 
3632 	/*
3633 	 * We rely on zfs_iter_children() to verify that there are no
3634 	 * newer snapshots for the given dataset.  Therefore, we can
3635 	 * simply pass the name on to the ioctl() call.  There is still
3636 	 * an unlikely race condition where the user has taken a
3637 	 * snapshot since we verified that this was the most recent.
3638 	 */
3639 	err = lzc_rollback(zhp->zfs_name, NULL, 0);
3640 	if (err != 0) {
3641 		(void) zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3642 		    dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
3643 		    zhp->zfs_name);
3644 		return (err);
3645 	}
3646 
3647 	/*
3648 	 * For volumes, if the pre-rollback volsize matched the pre-
3649 	 * rollback reservation and the volsize has changed then set
3650 	 * the reservation property to the post-rollback volsize.
3651 	 * Make a new handle since the rollback closed the dataset.
3652 	 */
3653 	if ((zhp->zfs_type == ZFS_TYPE_VOLUME) &&
3654 	    (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) {
3655 		if (restore_resv) {
3656 			new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
3657 			if (old_volsize != new_volsize)
3658 				err = zfs_prop_set_int(zhp, resv_prop,
3659 				    new_volsize);
3660 		}
3661 		zfs_close(zhp);
3662 	}
3663 	return (err);
3664 }
3665 
3666 /*
3667  * Renames the given dataset.
3668  */
3669 int
3670 zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
3671     boolean_t force_unmount)
3672 {
3673 	int ret;
3674 	zfs_cmd_t zc = { 0 };
3675 	char *delim;
3676 	prop_changelist_t *cl = NULL;
3677 	zfs_handle_t *zhrp = NULL;
3678 	char *parentname = NULL;
3679 	char parent[ZFS_MAXNAMELEN];
3680 	libzfs_handle_t *hdl = zhp->zfs_hdl;
3681 	char errbuf[1024];
3682 
3683 	/* if we have the same exact name, just return success */
3684 	if (strcmp(zhp->zfs_name, target) == 0)
3685 		return (0);
3686 
3687 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3688 	    "cannot rename to '%s'"), target);
3689 
3690 	/*
3691 	 * Make sure the target name is valid
3692 	 */
3693 	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3694 		if ((strchr(target, '@') == NULL) ||
3695 		    *target == '@') {
3696 			/*
3697 			 * Snapshot target name is abbreviated,
3698 			 * reconstruct full dataset name
3699 			 */
3700 			(void) strlcpy(parent, zhp->zfs_name,
3701 			    sizeof (parent));
3702 			delim = strchr(parent, '@');
3703 			if (strchr(target, '@') == NULL)
3704 				*(++delim) = '\0';
3705 			else
3706 				*delim = '\0';
3707 			(void) strlcat(parent, target, sizeof (parent));
3708 			target = parent;
3709 		} else {
3710 			/*
3711 			 * Make sure we're renaming within the same dataset.
3712 			 */
3713 			delim = strchr(target, '@');
3714 			if (strncmp(zhp->zfs_name, target, delim - target)
3715 			    != 0 || zhp->zfs_name[delim - target] != '@') {
3716 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3717 				    "snapshots must be part of same "
3718 				    "dataset"));
3719 				return (zfs_error(hdl, EZFS_CROSSTARGET,
3720 				    errbuf));
3721 			}
3722 		}
3723 		if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
3724 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3725 	} else {
3726 		if (recursive) {
3727 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3728 			    "recursive rename must be a snapshot"));
3729 			return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3730 		}
3731 
3732 		if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
3733 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3734 
3735 		/* validate parents */
3736 		if (check_parents(hdl, target, NULL, B_FALSE, NULL) != 0)
3737 			return (-1);
3738 
3739 		/* make sure we're in the same pool */
3740 		verify((delim = strchr(target, '/')) != NULL);
3741 		if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
3742 		    zhp->zfs_name[delim - target] != '/') {
3743 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3744 			    "datasets must be within same pool"));
3745 			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
3746 		}
3747 
3748 		/* new name cannot be a child of the current dataset name */
3749 		if (is_descendant(zhp->zfs_name, target)) {
3750 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3751 			    "New dataset name cannot be a descendant of "
3752 			    "current dataset name"));
3753 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3754 		}
3755 	}
3756 
3757 	(void) snprintf(errbuf, sizeof (errbuf),
3758 	    dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
3759 
3760 	if (getzoneid() == GLOBAL_ZONEID &&
3761 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
3762 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3763 		    "dataset is used in a non-global zone"));
3764 		return (zfs_error(hdl, EZFS_ZONED, errbuf));
3765 	}
3766 
3767 	if (recursive) {
3768 
3769 		parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
3770 		if (parentname == NULL) {
3771 			ret = -1;
3772 			goto error;
3773 		}
3774 		delim = strchr(parentname, '@');
3775 		*delim = '\0';
3776 		zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET);
3777 		if (zhrp == NULL) {
3778 			ret = -1;
3779 			goto error;
3780 		}
3781 
3782 	} else {
3783 		if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0,
3784 		    force_unmount ? MS_FORCE : 0)) == NULL)
3785 			return (-1);
3786 
3787 		if (changelist_haszonedchild(cl)) {
3788 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3789 			    "child dataset with inherited mountpoint is used "
3790 			    "in a non-global zone"));
3791 			(void) zfs_error(hdl, EZFS_ZONED, errbuf);
3792 			goto error;
3793 		}
3794 
3795 		if ((ret = changelist_prefix(cl)) != 0)
3796 			goto error;
3797 	}
3798 
3799 	if (ZFS_IS_VOLUME(zhp))
3800 		zc.zc_objset_type = DMU_OST_ZVOL;
3801 	else
3802 		zc.zc_objset_type = DMU_OST_ZFS;
3803 
3804 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3805 	(void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
3806 
3807 	zc.zc_cookie = recursive;
3808 
3809 	if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
3810 		/*
3811 		 * if it was recursive, the one that actually failed will
3812 		 * be in zc.zc_name
3813 		 */
3814 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3815 		    "cannot rename '%s'"), zc.zc_name);
3816 
3817 		if (recursive && errno == EEXIST) {
3818 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3819 			    "a child dataset already has a snapshot "
3820 			    "with the new name"));
3821 			(void) zfs_error(hdl, EZFS_EXISTS, errbuf);
3822 		} else {
3823 			(void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
3824 		}
3825 
3826 		/*
3827 		 * On failure, we still want to remount any filesystems that
3828 		 * were previously mounted, so we don't alter the system state.
3829 		 */
3830 		if (!recursive)
3831 			(void) changelist_postfix(cl);
3832 	} else {
3833 		if (!recursive) {
3834 			changelist_rename(cl, zfs_get_name(zhp), target);
3835 			ret = changelist_postfix(cl);
3836 		}
3837 	}
3838 
3839 error:
3840 	if (parentname) {
3841 		free(parentname);
3842 	}
3843 	if (zhrp) {
3844 		zfs_close(zhrp);
3845 	}
3846 	if (cl) {
3847 		changelist_free(cl);
3848 	}
3849 	return (ret);
3850 }
3851 
3852 nvlist_t *
3853 zfs_get_user_props(zfs_handle_t *zhp)
3854 {
3855 	return (zhp->zfs_user_props);
3856 }
3857 
3858 nvlist_t *
3859 zfs_get_recvd_props(zfs_handle_t *zhp)
3860 {
3861 	if (zhp->zfs_recvd_props == NULL)
3862 		if (get_recvd_props_ioctl(zhp) != 0)
3863 			return (NULL);
3864 	return (zhp->zfs_recvd_props);
3865 }
3866 
3867 /*
3868  * This function is used by 'zfs list' to determine the exact set of columns to
3869  * display, and their maximum widths.  This does two main things:
3870  *
3871  *      - If this is a list of all properties, then expand the list to include
3872  *        all native properties, and set a flag so that for each dataset we look
3873  *        for new unique user properties and add them to the list.
3874  *
3875  *      - For non fixed-width properties, keep track of the maximum width seen
3876  *        so that we can size the column appropriately. If the user has
3877  *        requested received property values, we also need to compute the width
3878  *        of the RECEIVED column.
3879  */
3880 int
3881 zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received,
3882     boolean_t literal)
3883 {
3884 	libzfs_handle_t *hdl = zhp->zfs_hdl;
3885 	zprop_list_t *entry;
3886 	zprop_list_t **last, **start;
3887 	nvlist_t *userprops, *propval;
3888 	nvpair_t *elem;
3889 	char *strval;
3890 	char buf[ZFS_MAXPROPLEN];
3891 
3892 	if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0)
3893 		return (-1);
3894 
3895 	userprops = zfs_get_user_props(zhp);
3896 
3897 	entry = *plp;
3898 	if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
3899 		/*
3900 		 * Go through and add any user properties as necessary.  We
3901 		 * start by incrementing our list pointer to the first
3902 		 * non-native property.
3903 		 */
3904 		start = plp;
3905 		while (*start != NULL) {
3906 			if ((*start)->pl_prop == ZPROP_INVAL)
3907 				break;
3908 			start = &(*start)->pl_next;
3909 		}
3910 
3911 		elem = NULL;
3912 		while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
3913 			/*
3914 			 * See if we've already found this property in our list.
3915 			 */
3916 			for (last = start; *last != NULL;
3917 			    last = &(*last)->pl_next) {
3918 				if (strcmp((*last)->pl_user_prop,
3919 				    nvpair_name(elem)) == 0)
3920 					break;
3921 			}
3922 
3923 			if (*last == NULL) {
3924 				if ((entry = zfs_alloc(hdl,
3925 				    sizeof (zprop_list_t))) == NULL ||
3926 				    ((entry->pl_user_prop = zfs_strdup(hdl,
3927 				    nvpair_name(elem)))) == NULL) {
3928 					free(entry);
3929 					return (-1);
3930 				}
3931 
3932 				entry->pl_prop = ZPROP_INVAL;
3933 				entry->pl_width = strlen(nvpair_name(elem));
3934 				entry->pl_all = B_TRUE;
3935 				*last = entry;
3936 			}
3937 		}
3938 	}
3939 
3940 	/*
3941 	 * Now go through and check the width of any non-fixed columns
3942 	 */
3943 	for (entry = *plp; entry != NULL; entry = entry->pl_next) {
3944 		if (entry->pl_fixed && !literal)
3945 			continue;
3946 
3947 		if (entry->pl_prop != ZPROP_INVAL) {
3948 			if (zfs_prop_get(zhp, entry->pl_prop,
3949 			    buf, sizeof (buf), NULL, NULL, 0, literal) == 0) {
3950 				if (strlen(buf) > entry->pl_width)
3951 					entry->pl_width = strlen(buf);
3952 			}
3953 			if (received && zfs_prop_get_recvd(zhp,
3954 			    zfs_prop_to_name(entry->pl_prop),
3955 			    buf, sizeof (buf), literal) == 0)
3956 				if (strlen(buf) > entry->pl_recvd_width)
3957 					entry->pl_recvd_width = strlen(buf);
3958 		} else {
3959 			if (nvlist_lookup_nvlist(userprops, entry->pl_user_prop,
3960 			    &propval) == 0) {
3961 				verify(nvlist_lookup_string(propval,
3962 				    ZPROP_VALUE, &strval) == 0);
3963 				if (strlen(strval) > entry->pl_width)
3964 					entry->pl_width = strlen(strval);
3965 			}
3966 			if (received && zfs_prop_get_recvd(zhp,
3967 			    entry->pl_user_prop,
3968 			    buf, sizeof (buf), literal) == 0)
3969 				if (strlen(buf) > entry->pl_recvd_width)
3970 					entry->pl_recvd_width = strlen(buf);
3971 		}
3972 	}
3973 
3974 	return (0);
3975 }
3976 
3977 int
3978 zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path,
3979     char *resource, void *export, void *sharetab,
3980     int sharemax, zfs_share_op_t operation)
3981 {
3982 	zfs_cmd_t zc = { 0 };
3983 	int error;
3984 
3985 	(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3986 	(void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
3987 	if (resource)
3988 		(void) strlcpy(zc.zc_string, resource, sizeof (zc.zc_string));
3989 	zc.zc_share.z_sharedata = (uint64_t)(uintptr_t)sharetab;
3990 	zc.zc_share.z_exportdata = (uint64_t)(uintptr_t)export;
3991 	zc.zc_share.z_sharetype = operation;
3992 	zc.zc_share.z_sharemax = sharemax;
3993 	error = ioctl(hdl->libzfs_fd, ZFS_IOC_SHARE, &zc);
3994 	return (error);
3995 }
3996 
3997 void
3998 zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
3999 {
4000 	nvpair_t *curr;
4001 
4002 	/*
4003 	 * Keep a reference to the props-table against which we prune the
4004 	 * properties.
4005 	 */
4006 	zhp->zfs_props_table = props;
4007 
4008 	curr = nvlist_next_nvpair(zhp->zfs_props, NULL);
4009 
4010 	while (curr) {
4011 		zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
4012 		nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr);
4013 
4014 		/*
4015 		 * User properties will result in ZPROP_INVAL, and since we
4016 		 * only know how to prune standard ZFS properties, we always
4017 		 * leave these in the list.  This can also happen if we
4018 		 * encounter an unknown DSL property (when running older
4019 		 * software, for example).
4020 		 */
4021 		if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE)
4022 			(void) nvlist_remove(zhp->zfs_props,
4023 			    nvpair_name(curr), nvpair_type(curr));
4024 		curr = next;
4025 	}
4026 }
4027 
4028 static int
4029 zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
4030     zfs_smb_acl_op_t cmd, char *resource1, char *resource2)
4031 {
4032 	zfs_cmd_t zc = { 0 };
4033 	nvlist_t *nvlist = NULL;
4034 	int error;
4035 
4036 	(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4037 	(void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
4038 	zc.zc_cookie = (uint64_t)cmd;
4039 
4040 	if (cmd == ZFS_SMB_ACL_RENAME) {
4041 		if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
4042 			(void) no_memory(hdl);
4043 			return (NULL);
4044 		}
4045 	}
4046 
4047 	switch (cmd) {
4048 	case ZFS_SMB_ACL_ADD:
4049 	case ZFS_SMB_ACL_REMOVE:
4050 		(void) strlcpy(zc.zc_string, resource1, sizeof (zc.zc_string));
4051 		break;
4052 	case ZFS_SMB_ACL_RENAME:
4053 		if (nvlist_add_string(nvlist, ZFS_SMB_ACL_SRC,
4054 		    resource1) != 0) {
4055 				(void) no_memory(hdl);
4056 				return (-1);
4057 		}
4058 		if (nvlist_add_string(nvlist, ZFS_SMB_ACL_TARGET,
4059 		    resource2) != 0) {
4060 				(void) no_memory(hdl);
4061 				return (-1);
4062 		}
4063 		if (zcmd_write_src_nvlist(hdl, &zc, nvlist) != 0) {
4064 			nvlist_free(nvlist);
4065 			return (-1);
4066 		}
4067 		break;
4068 	case ZFS_SMB_ACL_PURGE:
4069 		break;
4070 	default:
4071 		return (-1);
4072 	}
4073 	error = ioctl(hdl->libzfs_fd, ZFS_IOC_SMB_ACL, &zc);
4074 	if (nvlist)
4075 		nvlist_free(nvlist);
4076 	return (error);
4077 }
4078 
4079 int
4080 zfs_smb_acl_add(libzfs_handle_t *hdl, char *dataset,
4081     char *path, char *resource)
4082 {
4083 	return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_ADD,
4084 	    resource, NULL));
4085 }
4086 
4087 int
4088 zfs_smb_acl_remove(libzfs_handle_t *hdl, char *dataset,
4089     char *path, char *resource)
4090 {
4091 	return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_REMOVE,
4092 	    resource, NULL));
4093 }
4094 
4095 int
4096 zfs_smb_acl_purge(libzfs_handle_t *hdl, char *dataset, char *path)
4097 {
4098 	return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_PURGE,
4099 	    NULL, NULL));
4100 }
4101 
4102 int
4103 zfs_smb_acl_rename(libzfs_handle_t *hdl, char *dataset, char *path,
4104     char *oldname, char *newname)
4105 {
4106 	return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_RENAME,
4107 	    oldname, newname));
4108 }
4109 
4110 int
4111 zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
4112     zfs_userspace_cb_t func, void *arg)
4113 {
4114 	zfs_cmd_t zc = { 0 };
4115 	zfs_useracct_t buf[100];
4116 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4117 	int ret;
4118 
4119 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4120 
4121 	zc.zc_objset_type = type;
4122 	zc.zc_nvlist_dst = (uintptr_t)buf;
4123 
4124 	for (;;) {
4125 		zfs_useracct_t *zua = buf;
4126 
4127 		zc.zc_nvlist_dst_size = sizeof (buf);
4128 		if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) {
4129 			char errbuf[1024];
4130 
4131 			(void) snprintf(errbuf, sizeof (errbuf),
4132 			    dgettext(TEXT_DOMAIN,
4133 			    "cannot get used/quota for %s"), zc.zc_name);
4134 			return (zfs_standard_error_fmt(hdl, errno, errbuf));
4135 		}
4136 		if (zc.zc_nvlist_dst_size == 0)
4137 			break;
4138 
4139 		while (zc.zc_nvlist_dst_size > 0) {
4140 			if ((ret = func(arg, zua->zu_domain, zua->zu_rid,
4141 			    zua->zu_space)) != 0)
4142 				return (ret);
4143 			zua++;
4144 			zc.zc_nvlist_dst_size -= sizeof (zfs_useracct_t);
4145 		}
4146 	}
4147 
4148 	return (0);
4149 }
4150 
4151 struct holdarg {
4152 	nvlist_t *nvl;
4153 	const char *snapname;
4154 	const char *tag;
4155 	boolean_t recursive;
4156 	int error;
4157 };
4158 
4159 static int
4160 zfs_hold_one(zfs_handle_t *zhp, void *arg)
4161 {
4162 	struct holdarg *ha = arg;
4163 	char name[ZFS_MAXNAMELEN];
4164 	int rv = 0;
4165 
4166 	(void) snprintf(name, sizeof (name),
4167 	    "%s@%s", zhp->zfs_name, ha->snapname);
4168 
4169 	if (lzc_exists(name))
4170 		fnvlist_add_string(ha->nvl, name, ha->tag);
4171 
4172 	if (ha->recursive)
4173 		rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
4174 	zfs_close(zhp);
4175 	return (rv);
4176 }
4177 
4178 int
4179 zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
4180     boolean_t recursive, int cleanup_fd)
4181 {
4182 	int ret;
4183 	struct holdarg ha;
4184 
4185 	ha.nvl = fnvlist_alloc();
4186 	ha.snapname = snapname;
4187 	ha.tag = tag;
4188 	ha.recursive = recursive;
4189 	(void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
4190 
4191 	if (nvlist_empty(ha.nvl)) {
4192 		char errbuf[1024];
4193 
4194 		fnvlist_free(ha.nvl);
4195 		ret = ENOENT;
4196 		(void) snprintf(errbuf, sizeof (errbuf),
4197 		    dgettext(TEXT_DOMAIN,
4198 		    "cannot hold snapshot '%s@%s'"),
4199 		    zhp->zfs_name, snapname);
4200 		(void) zfs_standard_error(zhp->zfs_hdl, ret, errbuf);
4201 		return (ret);
4202 	}
4203 
4204 	ret = zfs_hold_nvl(zhp, cleanup_fd, ha.nvl);
4205 	fnvlist_free(ha.nvl);
4206 
4207 	return (ret);
4208 }
4209 
4210 int
4211 zfs_hold_nvl(zfs_handle_t *zhp, int cleanup_fd, nvlist_t *holds)
4212 {
4213 	int ret;
4214 	nvlist_t *errors;
4215 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4216 	char errbuf[1024];
4217 	nvpair_t *elem;
4218 
4219 	errors = NULL;
4220 	ret = lzc_hold(holds, cleanup_fd, &errors);
4221 
4222 	if (ret == 0) {
4223 		/* There may be errors even in the success case. */
4224 		fnvlist_free(errors);
4225 		return (0);
4226 	}
4227 
4228 	if (nvlist_empty(errors)) {
4229 		/* no hold-specific errors */
4230 		(void) snprintf(errbuf, sizeof (errbuf),
4231 		    dgettext(TEXT_DOMAIN, "cannot hold"));
4232 		switch (ret) {
4233 		case ENOTSUP:
4234 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4235 			    "pool must be upgraded"));
4236 			(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4237 			break;
4238 		case EINVAL:
4239 			(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4240 			break;
4241 		default:
4242 			(void) zfs_standard_error(hdl, ret, errbuf);
4243 		}
4244 	}
4245 
4246 	for (elem = nvlist_next_nvpair(errors, NULL);
4247 	    elem != NULL;
4248 	    elem = nvlist_next_nvpair(errors, elem)) {
4249 		(void) snprintf(errbuf, sizeof (errbuf),
4250 		    dgettext(TEXT_DOMAIN,
4251 		    "cannot hold snapshot '%s'"), nvpair_name(elem));
4252 		switch (fnvpair_value_int32(elem)) {
4253 		case E2BIG:
4254 			/*
4255 			 * Temporary tags wind up having the ds object id
4256 			 * prepended. So even if we passed the length check
4257 			 * above, it's still possible for the tag to wind
4258 			 * up being slightly too long.
4259 			 */
4260 			(void) zfs_error(hdl, EZFS_TAGTOOLONG, errbuf);
4261 			break;
4262 		case EINVAL:
4263 			(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4264 			break;
4265 		case EEXIST:
4266 			(void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf);
4267 			break;
4268 		default:
4269 			(void) zfs_standard_error(hdl,
4270 			    fnvpair_value_int32(elem), errbuf);
4271 		}
4272 	}
4273 
4274 	fnvlist_free(errors);
4275 	return (ret);
4276 }
4277 
4278 static int
4279 zfs_release_one(zfs_handle_t *zhp, void *arg)
4280 {
4281 	struct holdarg *ha = arg;
4282 	char name[ZFS_MAXNAMELEN];
4283 	int rv = 0;
4284 	nvlist_t *existing_holds;
4285 
4286 	(void) snprintf(name, sizeof (name),
4287 	    "%s@%s", zhp->zfs_name, ha->snapname);
4288 
4289 	if (lzc_get_holds(name, &existing_holds) != 0) {
4290 		ha->error = ENOENT;
4291 	} else if (!nvlist_exists(existing_holds, ha->tag)) {
4292 		ha->error = ESRCH;
4293 	} else {
4294 		nvlist_t *torelease = fnvlist_alloc();
4295 		fnvlist_add_boolean(torelease, ha->tag);
4296 		fnvlist_add_nvlist(ha->nvl, name, torelease);
4297 		fnvlist_free(torelease);
4298 	}
4299 
4300 	if (ha->recursive)
4301 		rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
4302 	zfs_close(zhp);
4303 	return (rv);
4304 }
4305 
4306 int
4307 zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
4308     boolean_t recursive)
4309 {
4310 	int ret;
4311 	struct holdarg ha;
4312 	nvlist_t *errors = NULL;
4313 	nvpair_t *elem;
4314 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4315 	char errbuf[1024];
4316 
4317 	ha.nvl = fnvlist_alloc();
4318 	ha.snapname = snapname;
4319 	ha.tag = tag;
4320 	ha.recursive = recursive;
4321 	ha.error = 0;
4322 	(void) zfs_release_one(zfs_handle_dup(zhp), &ha);
4323 
4324 	if (nvlist_empty(ha.nvl)) {
4325 		fnvlist_free(ha.nvl);
4326 		ret = ha.error;
4327 		(void) snprintf(errbuf, sizeof (errbuf),
4328 		    dgettext(TEXT_DOMAIN,
4329 		    "cannot release hold from snapshot '%s@%s'"),
4330 		    zhp->zfs_name, snapname);
4331 		if (ret == ESRCH) {
4332 			(void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
4333 		} else {
4334 			(void) zfs_standard_error(hdl, ret, errbuf);
4335 		}
4336 		return (ret);
4337 	}
4338 
4339 	ret = lzc_release(ha.nvl, &errors);
4340 	fnvlist_free(ha.nvl);
4341 
4342 	if (ret == 0) {
4343 		/* There may be errors even in the success case. */
4344 		fnvlist_free(errors);
4345 		return (0);
4346 	}
4347 
4348 	if (nvlist_empty(errors)) {
4349 		/* no hold-specific errors */
4350 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4351 		    "cannot release"));
4352 		switch (errno) {
4353 		case ENOTSUP:
4354 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4355 			    "pool must be upgraded"));
4356 			(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4357 			break;
4358 		default:
4359 			(void) zfs_standard_error_fmt(hdl, errno, errbuf);
4360 		}
4361 	}
4362 
4363 	for (elem = nvlist_next_nvpair(errors, NULL);
4364 	    elem != NULL;
4365 	    elem = nvlist_next_nvpair(errors, elem)) {
4366 		(void) snprintf(errbuf, sizeof (errbuf),
4367 		    dgettext(TEXT_DOMAIN,
4368 		    "cannot release hold from snapshot '%s'"),
4369 		    nvpair_name(elem));
4370 		switch (fnvpair_value_int32(elem)) {
4371 		case ESRCH:
4372 			(void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
4373 			break;
4374 		case EINVAL:
4375 			(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4376 			break;
4377 		default:
4378 			(void) zfs_standard_error_fmt(hdl,
4379 			    fnvpair_value_int32(elem), errbuf);
4380 		}
4381 	}
4382 
4383 	fnvlist_free(errors);
4384 	return (ret);
4385 }
4386 
4387 int
4388 zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl)
4389 {
4390 	zfs_cmd_t zc = { 0 };
4391 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4392 	int nvsz = 2048;
4393 	void *nvbuf;
4394 	int err = 0;
4395 	char errbuf[1024];
4396 
4397 	assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
4398 	    zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
4399 
4400 tryagain:
4401 
4402 	nvbuf = malloc(nvsz);
4403 	if (nvbuf == NULL) {
4404 		err = (zfs_error(hdl, EZFS_NOMEM, strerror(errno)));
4405 		goto out;
4406 	}
4407 
4408 	zc.zc_nvlist_dst_size = nvsz;
4409 	zc.zc_nvlist_dst = (uintptr_t)nvbuf;
4410 
4411 	(void) strlcpy(zc.zc_name, zhp->zfs_name, ZFS_MAXNAMELEN);
4412 
4413 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_GET_FSACL, &zc) != 0) {
4414 		(void) snprintf(errbuf, sizeof (errbuf),
4415 		    dgettext(TEXT_DOMAIN, "cannot get permissions on '%s'"),
4416 		    zc.zc_name);
4417 		switch (errno) {
4418 		case ENOMEM:
4419 			free(nvbuf);
4420 			nvsz = zc.zc_nvlist_dst_size;
4421 			goto tryagain;
4422 
4423 		case ENOTSUP:
4424 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4425 			    "pool must be upgraded"));
4426 			err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
4427 			break;
4428 		case EINVAL:
4429 			err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
4430 			break;
4431 		case ENOENT:
4432 			err = zfs_error(hdl, EZFS_NOENT, errbuf);
4433 			break;
4434 		default:
4435 			err = zfs_standard_error_fmt(hdl, errno, errbuf);
4436 			break;
4437 		}
4438 	} else {
4439 		/* success */
4440 		int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0);
4441 		if (rc) {
4442 			(void) snprintf(errbuf, sizeof (errbuf), dgettext(
4443 			    TEXT_DOMAIN, "cannot get permissions on '%s'"),
4444 			    zc.zc_name);
4445 			err = zfs_standard_error_fmt(hdl, rc, errbuf);
4446 		}
4447 	}
4448 
4449 	free(nvbuf);
4450 out:
4451 	return (err);
4452 }
4453 
4454 int
4455 zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
4456 {
4457 	zfs_cmd_t zc = { 0 };
4458 	libzfs_handle_t *hdl = zhp->zfs_hdl;
4459 	char *nvbuf;
4460 	char errbuf[1024];
4461 	size_t nvsz;
4462 	int err;
4463 
4464 	assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
4465 	    zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
4466 
4467 	err = nvlist_size(nvl, &nvsz, NV_ENCODE_NATIVE);
4468 	assert(err == 0);
4469 
4470 	nvbuf = malloc(nvsz);
4471 
4472 	err = nvlist_pack(nvl, &nvbuf, &nvsz, NV_ENCODE_NATIVE, 0);
4473 	assert(err == 0);
4474 
4475 	zc.zc_nvlist_src_size = nvsz;
4476 	zc.zc_nvlist_src = (uintptr_t)nvbuf;
4477 	zc.zc_perm_action = un;
4478 
4479 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4480 
4481 	if (zfs_ioctl(hdl, ZFS_IOC_SET_FSACL, &zc) != 0) {
4482 		(void) snprintf(errbuf, sizeof (errbuf),
4483 		    dgettext(TEXT_DOMAIN, "cannot set permissions on '%s'"),
4484 		    zc.zc_name);
4485 		switch (errno) {
4486 		case ENOTSUP:
4487 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4488 			    "pool must be upgraded"));
4489 			err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
4490 			break;
4491 		case EINVAL:
4492 			err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
4493 			break;
4494 		case ENOENT:
4495 			err = zfs_error(hdl, EZFS_NOENT, errbuf);
4496 			break;
4497 		default:
4498 			err = zfs_standard_error_fmt(hdl, errno, errbuf);
4499 			break;
4500 		}
4501 	}
4502 
4503 	free(nvbuf);
4504 
4505 	return (err);
4506 }
4507 
4508 int
4509 zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl)
4510 {
4511 	int err;
4512 	char errbuf[1024];
4513 
4514 	err = lzc_get_holds(zhp->zfs_name, nvl);
4515 
4516 	if (err != 0) {
4517 		libzfs_handle_t *hdl = zhp->zfs_hdl;
4518 
4519 		(void) snprintf(errbuf, sizeof (errbuf),
4520 		    dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
4521 		    zhp->zfs_name);
4522 		switch (err) {
4523 		case ENOTSUP:
4524 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4525 			    "pool must be upgraded"));
4526 			err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
4527 			break;
4528 		case EINVAL:
4529 			err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
4530 			break;
4531 		case ENOENT:
4532 			err = zfs_error(hdl, EZFS_NOENT, errbuf);
4533 			break;
4534 		default:
4535 			err = zfs_standard_error_fmt(hdl, errno, errbuf);
4536 			break;
4537 		}
4538 	}
4539 
4540 	return (err);
4541 }
4542 
4543 /*
4544  * Convert the zvol's volume size to an appropriate reservation.
4545  * Note: If this routine is updated, it is necessary to update the ZFS test
4546  * suite's shell version in reservation.kshlib.
4547  */
4548 uint64_t
4549 zvol_volsize_to_reservation(uint64_t volsize, nvlist_t *props)
4550 {
4551 	uint64_t numdb;
4552 	uint64_t nblocks, volblocksize;
4553 	int ncopies;
4554 	char *strval;
4555 
4556 	if (nvlist_lookup_string(props,
4557 	    zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)
4558 		ncopies = atoi(strval);
4559 	else
4560 		ncopies = 1;
4561 	if (nvlist_lookup_uint64(props,
4562 	    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
4563 	    &volblocksize) != 0)
4564 		volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
4565 	nblocks = volsize/volblocksize;
4566 	/* start with metadnode L0-L6 */
4567 	numdb = 7;
4568 	/* calculate number of indirects */
4569 	while (nblocks > 1) {
4570 		nblocks += DNODES_PER_LEVEL - 1;
4571 		nblocks /= DNODES_PER_LEVEL;
4572 		numdb += nblocks;
4573 	}
4574 	numdb *= MIN(SPA_DVAS_PER_BP, ncopies + 1);
4575 	volsize *= ncopies;
4576 	/*
4577 	 * this is exactly DN_MAX_INDBLKSHIFT when metadata isn't
4578 	 * compressed, but in practice they compress down to about
4579 	 * 1100 bytes
4580 	 */
4581 	numdb *= 1ULL << DN_MAX_INDBLKSHIFT;
4582 	volsize += numdb;
4583 	return (volsize);
4584 }
4585