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