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