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