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