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