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