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