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