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