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