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