]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libzfs/libzfs_dataset.c
OpenZFS 8418 - zfs_prop_get_table() call in zfs_validate_name() is a no-op
[FreeBSD/FreeBSD.git] / lib / libzfs / libzfs_dataset.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21
22 /*
23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24  * 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  * Copyright 2017 RackTop Systems.
33  */
34
35 #include <ctype.h>
36 #include <errno.h>
37 #include <libintl.h>
38 #include <math.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <strings.h>
42 #include <unistd.h>
43 #include <stddef.h>
44 #include <zone.h>
45 #include <fcntl.h>
46 #include <sys/mntent.h>
47 #include <sys/mount.h>
48 #include <pwd.h>
49 #include <grp.h>
50 #include <stddef.h>
51 #include <ucred.h>
52 #ifdef HAVE_IDMAP
53 #include <idmap.h>
54 #include <aclutils.h>
55 #include <directory.h>
56 #endif /* HAVE_IDMAP */
57
58 #include <sys/dnode.h>
59 #include <sys/spa.h>
60 #include <sys/zap.h>
61 #include <libzfs.h>
62
63 #include "zfs_namecheck.h"
64 #include "zfs_prop.h"
65 #include "libzfs_impl.h"
66 #include "zfs_deleg.h"
67
68 static int userquota_propname_decode(const char *propname, boolean_t zoned,
69     zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
70
71 /*
72  * Given a single type (not a mask of types), return the type in a human
73  * readable form.
74  */
75 const char *
76 zfs_type_to_name(zfs_type_t type)
77 {
78         switch (type) {
79         case ZFS_TYPE_FILESYSTEM:
80                 return (dgettext(TEXT_DOMAIN, "filesystem"));
81         case ZFS_TYPE_SNAPSHOT:
82                 return (dgettext(TEXT_DOMAIN, "snapshot"));
83         case ZFS_TYPE_VOLUME:
84                 return (dgettext(TEXT_DOMAIN, "volume"));
85         case ZFS_TYPE_POOL:
86                 return (dgettext(TEXT_DOMAIN, "pool"));
87         case ZFS_TYPE_BOOKMARK:
88                 return (dgettext(TEXT_DOMAIN, "bookmark"));
89         default:
90                 assert(!"unhandled zfs_type_t");
91         }
92
93         return (NULL);
94 }
95
96 /*
97  * Validate a ZFS path.  This is used even before trying to open the dataset, to
98  * provide a more meaningful error message.  We call zfs_error_aux() to
99  * explain exactly why the name was not valid.
100  */
101 int
102 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
103     boolean_t modifying)
104 {
105         namecheck_err_t why;
106         char what;
107
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         case ZFS_PROP_CREATETXG:
2699                 /*
2700                  * GUIDs are stored as numbers, but they are identifiers.
2701                  * We don't want them to be pretty printed, because pretty
2702                  * printing mangles the ID into a truncated and useless value.
2703                  */
2704                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2705                         return (-1);
2706                 (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val);
2707                 break;
2708
2709         case ZFS_PROP_REFERENCED:
2710         case ZFS_PROP_AVAILABLE:
2711         case ZFS_PROP_USED:
2712         case ZFS_PROP_USEDSNAP:
2713         case ZFS_PROP_USEDDS:
2714         case ZFS_PROP_USEDREFRESERV:
2715         case ZFS_PROP_USEDCHILD:
2716                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2717                         return (-1);
2718                 if (literal)
2719                         (void) snprintf(propbuf, proplen, "%llu",
2720                             (u_longlong_t)val);
2721                 else
2722                         zfs_nicebytes(val, propbuf, proplen);
2723                 break;
2724
2725         default:
2726                 switch (zfs_prop_get_type(prop)) {
2727                 case PROP_TYPE_NUMBER:
2728                         if (get_numeric_property(zhp, prop, src,
2729                             &source, &val) != 0)
2730                                 return (-1);
2731                         if (literal)
2732                                 (void) snprintf(propbuf, proplen, "%llu",
2733                                     (u_longlong_t)val);
2734                         else
2735                                 zfs_nicenum(val, propbuf, proplen);
2736                         break;
2737
2738                 case PROP_TYPE_STRING:
2739                         str = getprop_string(zhp, prop, &source);
2740                         if (str == NULL)
2741                                 return (-1);
2742                         (void) strlcpy(propbuf, str, proplen);
2743                         break;
2744
2745                 case PROP_TYPE_INDEX:
2746                         if (get_numeric_property(zhp, prop, src,
2747                             &source, &val) != 0)
2748                                 return (-1);
2749                         if (zfs_prop_index_to_string(prop, val, &strval) != 0)
2750                                 return (-1);
2751                         (void) strlcpy(propbuf, strval, proplen);
2752                         break;
2753
2754                 default:
2755                         abort();
2756                 }
2757         }
2758
2759         get_source(zhp, src, source, statbuf, statlen);
2760
2761         return (0);
2762 }
2763
2764 /*
2765  * Utility function to get the given numeric property.  Does no validation that
2766  * the given property is the appropriate type; should only be used with
2767  * hard-coded property types.
2768  */
2769 uint64_t
2770 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
2771 {
2772         char *source;
2773         uint64_t val = 0;
2774
2775         (void) get_numeric_property(zhp, prop, NULL, &source, &val);
2776
2777         return (val);
2778 }
2779
2780 int
2781 zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val)
2782 {
2783         char buf[64];
2784
2785         (void) snprintf(buf, sizeof (buf), "%llu", (longlong_t)val);
2786         return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf));
2787 }
2788
2789 /*
2790  * Similar to zfs_prop_get(), but returns the value as an integer.
2791  */
2792 int
2793 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
2794     zprop_source_t *src, char *statbuf, size_t statlen)
2795 {
2796         char *source;
2797
2798         /*
2799          * Check to see if this property applies to our object
2800          */
2801         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE)) {
2802                 return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
2803                     dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
2804                     zfs_prop_to_name(prop)));
2805         }
2806
2807         if (src)
2808                 *src = ZPROP_SRC_NONE;
2809
2810         if (get_numeric_property(zhp, prop, src, &source, value) != 0)
2811                 return (-1);
2812
2813         get_source(zhp, src, source, statbuf, statlen);
2814
2815         return (0);
2816 }
2817
2818 #ifdef HAVE_IDMAP
2819 static int
2820 idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
2821     char **domainp, idmap_rid_t *ridp)
2822 {
2823         idmap_get_handle_t *get_hdl = NULL;
2824         idmap_stat status;
2825         int err = EINVAL;
2826
2827         if (idmap_get_create(&get_hdl) != IDMAP_SUCCESS)
2828                 goto out;
2829
2830         if (isuser) {
2831                 err = idmap_get_sidbyuid(get_hdl, id,
2832                     IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
2833         } else {
2834                 err = idmap_get_sidbygid(get_hdl, id,
2835                     IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
2836         }
2837         if (err == IDMAP_SUCCESS &&
2838             idmap_get_mappings(get_hdl) == IDMAP_SUCCESS &&
2839             status == IDMAP_SUCCESS)
2840                 err = 0;
2841         else
2842                 err = EINVAL;
2843 out:
2844         if (get_hdl)
2845                 idmap_get_destroy(get_hdl);
2846         return (err);
2847 }
2848 #endif /* HAVE_IDMAP */
2849
2850 /*
2851  * convert the propname into parameters needed by kernel
2852  * Eg: userquota@ahrens -> ZFS_PROP_USERQUOTA, "", 126829
2853  * Eg: userused@matt@domain -> ZFS_PROP_USERUSED, "S-1-123-456", 789
2854  * Eg: groupquota@staff -> ZFS_PROP_GROUPQUOTA, "", 1234
2855  * Eg: groupused@staff -> ZFS_PROP_GROUPUSED, "", 1234
2856  */
2857 static int
2858 userquota_propname_decode(const char *propname, boolean_t zoned,
2859     zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp)
2860 {
2861         zfs_userquota_prop_t type;
2862         char *cp;
2863         boolean_t isuser;
2864         boolean_t isgroup;
2865         struct passwd *pw;
2866         struct group *gr;
2867
2868         domain[0] = '\0';
2869
2870         /* Figure out the property type ({user|group}{quota|space}) */
2871         for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
2872                 if (strncmp(propname, zfs_userquota_prop_prefixes[type],
2873                     strlen(zfs_userquota_prop_prefixes[type])) == 0)
2874                         break;
2875         }
2876         if (type == ZFS_NUM_USERQUOTA_PROPS)
2877                 return (EINVAL);
2878         *typep = type;
2879
2880         isuser = (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_USERUSED ||
2881             type == ZFS_PROP_USEROBJQUOTA ||
2882             type == ZFS_PROP_USEROBJUSED);
2883         isgroup = (type == ZFS_PROP_GROUPQUOTA || type == ZFS_PROP_GROUPUSED ||
2884             type == ZFS_PROP_GROUPOBJQUOTA ||
2885             type == ZFS_PROP_GROUPOBJUSED);
2886
2887         cp = strchr(propname, '@') + 1;
2888
2889         if (isuser && (pw = getpwnam(cp)) != NULL) {
2890                 if (zoned && getzoneid() == GLOBAL_ZONEID)
2891                         return (ENOENT);
2892                 *ridp = pw->pw_uid;
2893         } else if (isgroup && (gr = getgrnam(cp)) != NULL) {
2894                 if (zoned && getzoneid() == GLOBAL_ZONEID)
2895                         return (ENOENT);
2896                 *ridp = gr->gr_gid;
2897         } else if (strchr(cp, '@')) {
2898 #ifdef HAVE_IDMAP
2899                 /*
2900                  * It's a SID name (eg "user@domain") that needs to be
2901                  * turned into S-1-domainID-RID.
2902                  */
2903                 directory_error_t e;
2904                 char *numericsid = NULL;
2905                 char *end;
2906
2907                 if (zoned && getzoneid() == GLOBAL_ZONEID)
2908                         return (ENOENT);
2909                 if (isuser) {
2910                         e = directory_sid_from_user_name(NULL,
2911                             cp, &numericsid);
2912                 } else {
2913                         e = directory_sid_from_group_name(NULL,
2914                             cp, &numericsid);
2915                 }
2916                 if (e != NULL) {
2917                         directory_error_free(e);
2918                         return (ENOENT);
2919                 }
2920                 if (numericsid == NULL)
2921                         return (ENOENT);
2922                 cp = numericsid;
2923                 (void) strlcpy(domain, cp, domainlen);
2924                 cp = strrchr(domain, '-');
2925                 *cp = '\0';
2926                 cp++;
2927
2928                 errno = 0;
2929                 *ridp = strtoull(cp, &end, 10);
2930                 free(numericsid);
2931
2932                 if (errno != 0 || *end != '\0')
2933                         return (EINVAL);
2934 #else
2935                 return (ENOSYS);
2936 #endif /* HAVE_IDMAP */
2937         } else {
2938                 /* It's a user/group ID (eg "12345"). */
2939                 uid_t id;
2940                 char *end;
2941                 id = strtoul(cp, &end, 10);
2942                 if (*end != '\0')
2943                         return (EINVAL);
2944                 if (id > MAXUID) {
2945 #ifdef HAVE_IDMAP
2946                         /* It's an ephemeral ID. */
2947                         idmap_rid_t rid;
2948                         char *mapdomain;
2949
2950                         if (idmap_id_to_numeric_domain_rid(id, isuser,
2951                             &mapdomain, &rid) != 0)
2952                                 return (ENOENT);
2953                         (void) strlcpy(domain, mapdomain, domainlen);
2954                         *ridp = rid;
2955 #else
2956                         return (ENOSYS);
2957 #endif /* HAVE_IDMAP */
2958                 } else {
2959                         *ridp = id;
2960                 }
2961         }
2962
2963         return (0);
2964 }
2965
2966 static int
2967 zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname,
2968     uint64_t *propvalue, zfs_userquota_prop_t *typep)
2969 {
2970         int err;
2971         zfs_cmd_t zc = {"\0"};
2972
2973         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2974
2975         err = userquota_propname_decode(propname,
2976             zfs_prop_get_int(zhp, ZFS_PROP_ZONED),
2977             typep, zc.zc_value, sizeof (zc.zc_value), &zc.zc_guid);
2978         zc.zc_objset_type = *typep;
2979         if (err)
2980                 return (err);
2981
2982         err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_USERSPACE_ONE, &zc);
2983         if (err)
2984                 return (err);
2985
2986         *propvalue = zc.zc_cookie;
2987         return (0);
2988 }
2989
2990 int
2991 zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname,
2992     uint64_t *propvalue)
2993 {
2994         zfs_userquota_prop_t type;
2995
2996         return (zfs_prop_get_userquota_common(zhp, propname, propvalue,
2997             &type));
2998 }
2999
3000 int
3001 zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
3002     char *propbuf, int proplen, boolean_t literal)
3003 {
3004         int err;
3005         uint64_t propvalue;
3006         zfs_userquota_prop_t type;
3007
3008         err = zfs_prop_get_userquota_common(zhp, propname, &propvalue,
3009             &type);
3010
3011         if (err)
3012                 return (err);
3013
3014         if (literal) {
3015                 (void) snprintf(propbuf, proplen, "%llu",
3016                     (u_longlong_t)propvalue);
3017         } else if (propvalue == 0 &&
3018             (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA ||
3019             type == ZFS_PROP_USEROBJQUOTA || type == ZFS_PROP_GROUPOBJQUOTA)) {
3020                 (void) strlcpy(propbuf, "none", proplen);
3021         } else if (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA ||
3022             type == ZFS_PROP_USERUSED || type == ZFS_PROP_GROUPUSED) {
3023                 zfs_nicebytes(propvalue, propbuf, proplen);
3024         } else {
3025                 zfs_nicenum(propvalue, propbuf, proplen);
3026         }
3027         return (0);
3028 }
3029
3030 int
3031 zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
3032     uint64_t *propvalue)
3033 {
3034         int err;
3035         zfs_cmd_t zc = {"\0"};
3036         const char *snapname;
3037
3038         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3039
3040         snapname = strchr(propname, '@') + 1;
3041         if (strchr(snapname, '@')) {
3042                 (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
3043         } else {
3044                 /* snapname is the short name, append it to zhp's fsname */
3045                 char *cp;
3046
3047                 (void) strlcpy(zc.zc_value, zhp->zfs_name,
3048                     sizeof (zc.zc_value));
3049                 cp = strchr(zc.zc_value, '@');
3050                 if (cp != NULL)
3051                         *cp = '\0';
3052                 (void) strlcat(zc.zc_value, "@", sizeof (zc.zc_value));
3053                 (void) strlcat(zc.zc_value, snapname, sizeof (zc.zc_value));
3054         }
3055
3056         err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SPACE_WRITTEN, &zc);
3057         if (err)
3058                 return (err);
3059
3060         *propvalue = zc.zc_cookie;
3061         return (0);
3062 }
3063
3064 int
3065 zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
3066     char *propbuf, int proplen, boolean_t literal)
3067 {
3068         int err;
3069         uint64_t propvalue;
3070
3071         err = zfs_prop_get_written_int(zhp, propname, &propvalue);
3072
3073         if (err)
3074                 return (err);
3075
3076         if (literal) {
3077                 (void) snprintf(propbuf, proplen, "%llu",
3078                     (u_longlong_t)propvalue);
3079         } else {
3080                 zfs_nicebytes(propvalue, propbuf, proplen);
3081         }
3082
3083         return (0);
3084 }
3085
3086 /*
3087  * Returns the name of the given zfs handle.
3088  */
3089 const char *
3090 zfs_get_name(const zfs_handle_t *zhp)
3091 {
3092         return (zhp->zfs_name);
3093 }
3094
3095 /*
3096  * Returns the name of the parent pool for the given zfs handle.
3097  */
3098 const char *
3099 zfs_get_pool_name(const zfs_handle_t *zhp)
3100 {
3101         return (zhp->zpool_hdl->zpool_name);
3102 }
3103
3104 /*
3105  * Returns the type of the given zfs handle.
3106  */
3107 zfs_type_t
3108 zfs_get_type(const zfs_handle_t *zhp)
3109 {
3110         return (zhp->zfs_type);
3111 }
3112
3113 /*
3114  * Is one dataset name a child dataset of another?
3115  *
3116  * Needs to handle these cases:
3117  * Dataset 1    "a/foo"         "a/foo"         "a/foo"         "a/foo"
3118  * Dataset 2    "a/fo"          "a/foobar"      "a/bar/baz"     "a/foo/bar"
3119  * Descendant?  No.             No.             No.             Yes.
3120  */
3121 static boolean_t
3122 is_descendant(const char *ds1, const char *ds2)
3123 {
3124         size_t d1len = strlen(ds1);
3125
3126         /* ds2 can't be a descendant if it's smaller */
3127         if (strlen(ds2) < d1len)
3128                 return (B_FALSE);
3129
3130         /* otherwise, compare strings and verify that there's a '/' char */
3131         return (ds2[d1len] == '/' && (strncmp(ds1, ds2, d1len) == 0));
3132 }
3133
3134 /*
3135  * Given a complete name, return just the portion that refers to the parent.
3136  * Will return -1 if there is no parent (path is just the name of the
3137  * pool).
3138  */
3139 static int
3140 parent_name(const char *path, char *buf, size_t buflen)
3141 {
3142         char *slashp;
3143
3144         (void) strlcpy(buf, path, buflen);
3145
3146         if ((slashp = strrchr(buf, '/')) == NULL)
3147                 return (-1);
3148         *slashp = '\0';
3149
3150         return (0);
3151 }
3152
3153 /*
3154  * If accept_ancestor is false, then check to make sure that the given path has
3155  * a parent, and that it exists.  If accept_ancestor is true, then find the
3156  * closest existing ancestor for the given path.  In prefixlen return the
3157  * length of already existing prefix of the given path.  We also fetch the
3158  * 'zoned' property, which is used to validate property settings when creating
3159  * new datasets.
3160  */
3161 static int
3162 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
3163     boolean_t accept_ancestor, int *prefixlen)
3164 {
3165         zfs_cmd_t zc = {"\0"};
3166         char parent[ZFS_MAX_DATASET_NAME_LEN];
3167         char *slash;
3168         zfs_handle_t *zhp;
3169         char errbuf[1024];
3170         uint64_t is_zoned;
3171
3172         (void) snprintf(errbuf, sizeof (errbuf),
3173             dgettext(TEXT_DOMAIN, "cannot create '%s'"), path);
3174
3175         /* get parent, and check to see if this is just a pool */
3176         if (parent_name(path, parent, sizeof (parent)) != 0) {
3177                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3178                     "missing dataset name"));
3179                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3180         }
3181
3182         /* check to see if the pool exists */
3183         if ((slash = strchr(parent, '/')) == NULL)
3184                 slash = parent + strlen(parent);
3185         (void) strncpy(zc.zc_name, parent, slash - parent);
3186         zc.zc_name[slash - parent] = '\0';
3187         if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
3188             errno == ENOENT) {
3189                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3190                     "no such pool '%s'"), zc.zc_name);
3191                 return (zfs_error(hdl, EZFS_NOENT, errbuf));
3192         }
3193
3194         /* check to see if the parent dataset exists */
3195         while ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
3196                 if (errno == ENOENT && accept_ancestor) {
3197                         /*
3198                          * Go deeper to find an ancestor, give up on top level.
3199                          */
3200                         if (parent_name(parent, parent, sizeof (parent)) != 0) {
3201                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3202                                     "no such pool '%s'"), zc.zc_name);
3203                                 return (zfs_error(hdl, EZFS_NOENT, errbuf));
3204                         }
3205                 } else if (errno == ENOENT) {
3206                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3207                             "parent does not exist"));
3208                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
3209                 } else
3210                         return (zfs_standard_error(hdl, errno, errbuf));
3211         }
3212
3213         is_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
3214         if (zoned != NULL)
3215                 *zoned = is_zoned;
3216
3217         /* we are in a non-global zone, but parent is in the global zone */
3218         if (getzoneid() != GLOBAL_ZONEID && !is_zoned) {
3219                 (void) zfs_standard_error(hdl, EPERM, errbuf);
3220                 zfs_close(zhp);
3221                 return (-1);
3222         }
3223
3224         /* make sure parent is a filesystem */
3225         if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
3226                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3227                     "parent is not a filesystem"));
3228                 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
3229                 zfs_close(zhp);
3230                 return (-1);
3231         }
3232
3233         zfs_close(zhp);
3234         if (prefixlen != NULL)
3235                 *prefixlen = strlen(parent);
3236         return (0);
3237 }
3238
3239 /*
3240  * Finds whether the dataset of the given type(s) exists.
3241  */
3242 boolean_t
3243 zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types)
3244 {
3245         zfs_handle_t *zhp;
3246
3247         if (!zfs_validate_name(hdl, path, types, B_FALSE))
3248                 return (B_FALSE);
3249
3250         /*
3251          * Try to get stats for the dataset, which will tell us if it exists.
3252          */
3253         if ((zhp = make_dataset_handle(hdl, path)) != NULL) {
3254                 int ds_type = zhp->zfs_type;
3255
3256                 zfs_close(zhp);
3257                 if (types & ds_type)
3258                         return (B_TRUE);
3259         }
3260         return (B_FALSE);
3261 }
3262
3263 /*
3264  * Given a path to 'target', create all the ancestors between
3265  * the prefixlen portion of the path, and the target itself.
3266  * Fail if the initial prefixlen-ancestor does not already exist.
3267  */
3268 int
3269 create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
3270 {
3271         zfs_handle_t *h;
3272         char *cp;
3273         const char *opname;
3274
3275         /* make sure prefix exists */
3276         cp = target + prefixlen;
3277         if (*cp != '/') {
3278                 assert(strchr(cp, '/') == NULL);
3279                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
3280         } else {
3281                 *cp = '\0';
3282                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
3283                 *cp = '/';
3284         }
3285         if (h == NULL)
3286                 return (-1);
3287         zfs_close(h);
3288
3289         /*
3290          * Attempt to create, mount, and share any ancestor filesystems,
3291          * up to the prefixlen-long one.
3292          */
3293         for (cp = target + prefixlen + 1;
3294             (cp = strchr(cp, '/')) != NULL; *cp = '/', cp++) {
3295
3296                 *cp = '\0';
3297
3298                 h = make_dataset_handle(hdl, target);
3299                 if (h) {
3300                         /* it already exists, nothing to do here */
3301                         zfs_close(h);
3302                         continue;
3303                 }
3304
3305                 if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
3306                     NULL) != 0) {
3307                         opname = dgettext(TEXT_DOMAIN, "create");
3308                         goto ancestorerr;
3309                 }
3310
3311                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
3312                 if (h == NULL) {
3313                         opname = dgettext(TEXT_DOMAIN, "open");
3314                         goto ancestorerr;
3315                 }
3316
3317                 if (zfs_mount(h, NULL, 0) != 0) {
3318                         opname = dgettext(TEXT_DOMAIN, "mount");
3319                         goto ancestorerr;
3320                 }
3321
3322                 if (zfs_share(h) != 0) {
3323                         opname = dgettext(TEXT_DOMAIN, "share");
3324                         goto ancestorerr;
3325                 }
3326
3327                 zfs_close(h);
3328         }
3329
3330         return (0);
3331
3332 ancestorerr:
3333         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3334             "failed to %s ancestor '%s'"), opname, target);
3335         return (-1);
3336 }
3337
3338 /*
3339  * Creates non-existing ancestors of the given path.
3340  */
3341 int
3342 zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
3343 {
3344         int prefix;
3345         char *path_copy;
3346         int rc = 0;
3347
3348         if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
3349                 return (-1);
3350
3351         if ((path_copy = strdup(path)) != NULL) {
3352                 rc = create_parents(hdl, path_copy, prefix);
3353                 free(path_copy);
3354         }
3355         if (path_copy == NULL || rc != 0)
3356                 return (-1);
3357
3358         return (0);
3359 }
3360
3361 /*
3362  * Create a new filesystem or volume.
3363  */
3364 int
3365 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
3366     nvlist_t *props)
3367 {
3368         int ret;
3369         uint64_t size = 0;
3370         uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
3371         char errbuf[1024];
3372         uint64_t zoned;
3373         enum lzc_dataset_type ost;
3374         zpool_handle_t *zpool_handle;
3375
3376         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3377             "cannot create '%s'"), path);
3378
3379         /* validate the path, taking care to note the extended error message */
3380         if (!zfs_validate_name(hdl, path, type, B_TRUE))
3381                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3382
3383         /* validate parents exist */
3384         if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
3385                 return (-1);
3386
3387         /*
3388          * The failure modes when creating a dataset of a different type over
3389          * one that already exists is a little strange.  In particular, if you
3390          * try to create a dataset on top of an existing dataset, the ioctl()
3391          * will return ENOENT, not EEXIST.  To prevent this from happening, we
3392          * first try to see if the dataset exists.
3393          */
3394         if (zfs_dataset_exists(hdl, path, ZFS_TYPE_DATASET)) {
3395                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3396                     "dataset already exists"));
3397                 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3398         }
3399
3400         if (type == ZFS_TYPE_VOLUME)
3401                 ost = LZC_DATSET_TYPE_ZVOL;
3402         else
3403                 ost = LZC_DATSET_TYPE_ZFS;
3404
3405         /* open zpool handle for prop validation */
3406         char pool_path[ZFS_MAX_DATASET_NAME_LEN];
3407         (void) strlcpy(pool_path, path, sizeof (pool_path));
3408
3409         /* truncate pool_path at first slash */
3410         char *p = strchr(pool_path, '/');
3411         if (p != NULL)
3412                 *p = '\0';
3413
3414         if ((zpool_handle = zpool_open(hdl, pool_path)) == NULL)
3415                 return (-1);
3416
3417         if (props && (props = zfs_valid_proplist(hdl, type, props,
3418             zoned, NULL, zpool_handle, errbuf)) == 0) {
3419                 zpool_close(zpool_handle);
3420                 return (-1);
3421         }
3422         zpool_close(zpool_handle);
3423
3424         if (type == ZFS_TYPE_VOLUME) {
3425                 /*
3426                  * If we are creating a volume, the size and block size must
3427                  * satisfy a few restraints.  First, the blocksize must be a
3428                  * valid block size between SPA_{MIN,MAX}BLOCKSIZE.  Second, the
3429                  * volsize must be a multiple of the block size, and cannot be
3430                  * zero.
3431                  */
3432                 if (props == NULL || nvlist_lookup_uint64(props,
3433                     zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
3434                         nvlist_free(props);
3435                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3436                             "missing volume size"));
3437                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3438                 }
3439
3440                 if ((ret = nvlist_lookup_uint64(props,
3441                     zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
3442                     &blocksize)) != 0) {
3443                         if (ret == ENOENT) {
3444                                 blocksize = zfs_prop_default_numeric(
3445                                     ZFS_PROP_VOLBLOCKSIZE);
3446                         } else {
3447                                 nvlist_free(props);
3448                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3449                                     "missing volume block size"));
3450                                 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3451                         }
3452                 }
3453
3454                 if (size == 0) {
3455                         nvlist_free(props);
3456                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3457                             "volume size cannot be zero"));
3458                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3459                 }
3460
3461                 if (size % blocksize != 0) {
3462                         nvlist_free(props);
3463                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3464                             "volume size must be a multiple of volume block "
3465                             "size"));
3466                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3467                 }
3468         }
3469
3470         /* create the dataset */
3471         ret = lzc_create(path, ost, props);
3472         nvlist_free(props);
3473
3474         /* check for failure */
3475         if (ret != 0) {
3476                 char parent[ZFS_MAX_DATASET_NAME_LEN];
3477                 (void) parent_name(path, parent, sizeof (parent));
3478
3479                 switch (errno) {
3480                 case ENOENT:
3481                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3482                             "no such parent '%s'"), parent);
3483                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
3484
3485                 case EINVAL:
3486                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3487                             "parent '%s' is not a filesystem"), parent);
3488                         return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3489
3490                 case ENOTSUP:
3491                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3492                             "pool must be upgraded to set this "
3493                             "property or value"));
3494                         return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
3495 #ifdef _ILP32
3496                 case EOVERFLOW:
3497                         /*
3498                          * This platform can't address a volume this big.
3499                          */
3500                         if (type == ZFS_TYPE_VOLUME)
3501                                 return (zfs_error(hdl, EZFS_VOLTOOBIG,
3502                                     errbuf));
3503 #endif
3504                         /* FALLTHROUGH */
3505                 default:
3506                         return (zfs_standard_error(hdl, errno, errbuf));
3507                 }
3508         }
3509
3510         return (0);
3511 }
3512
3513 /*
3514  * Destroys the given dataset.  The caller must make sure that the filesystem
3515  * isn't mounted, and that there are no active dependents. If the file system
3516  * does not exist this function does nothing.
3517  */
3518 int
3519 zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
3520 {
3521         zfs_cmd_t zc = {"\0"};
3522
3523         if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
3524                 nvlist_t *nv = fnvlist_alloc();
3525                 fnvlist_add_boolean(nv, zhp->zfs_name);
3526                 int error = lzc_destroy_bookmarks(nv, NULL);
3527                 fnvlist_free(nv);
3528                 if (error != 0) {
3529                         return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3530                             dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3531                             zhp->zfs_name));
3532                 }
3533                 return (0);
3534         }
3535
3536         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3537
3538         if (ZFS_IS_VOLUME(zhp)) {
3539                 zc.zc_objset_type = DMU_OST_ZVOL;
3540         } else {
3541                 zc.zc_objset_type = DMU_OST_ZFS;
3542         }
3543
3544         zc.zc_defer_destroy = defer;
3545         if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY, &zc) != 0 &&
3546             errno != ENOENT) {
3547                 return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3548                     dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3549                     zhp->zfs_name));
3550         }
3551
3552         remove_mountpoint(zhp);
3553
3554         return (0);
3555 }
3556
3557 struct destroydata {
3558         nvlist_t *nvl;
3559         const char *snapname;
3560 };
3561
3562 static int
3563 zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
3564 {
3565         struct destroydata *dd = arg;
3566         char name[ZFS_MAX_DATASET_NAME_LEN];
3567         int rv = 0;
3568
3569         if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
3570             dd->snapname) >= sizeof (name))
3571                 return (EINVAL);
3572
3573         if (lzc_exists(name))
3574                 verify(nvlist_add_boolean(dd->nvl, name) == 0);
3575
3576         rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, dd);
3577         zfs_close(zhp);
3578         return (rv);
3579 }
3580
3581 /*
3582  * Destroys all snapshots with the given name in zhp & descendants.
3583  */
3584 int
3585 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
3586 {
3587         int ret;
3588         struct destroydata dd = { 0 };
3589
3590         dd.snapname = snapname;
3591         verify(nvlist_alloc(&dd.nvl, NV_UNIQUE_NAME, 0) == 0);
3592         (void) zfs_check_snap_cb(zfs_handle_dup(zhp), &dd);
3593
3594         if (nvlist_empty(dd.nvl)) {
3595                 ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
3596                     dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
3597                     zhp->zfs_name, snapname);
3598         } else {
3599                 ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer);
3600         }
3601         nvlist_free(dd.nvl);
3602         return (ret);
3603 }
3604
3605 /*
3606  * Destroys all the snapshots named in the nvlist.
3607  */
3608 int
3609 zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
3610 {
3611         int ret;
3612         nvlist_t *errlist = NULL;
3613         nvpair_t *pair;
3614
3615         ret = lzc_destroy_snaps(snaps, defer, &errlist);
3616
3617         if (ret == 0) {
3618                 nvlist_free(errlist);
3619                 return (0);
3620         }
3621
3622         if (nvlist_empty(errlist)) {
3623                 char errbuf[1024];
3624                 (void) snprintf(errbuf, sizeof (errbuf),
3625                     dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
3626
3627                 ret = zfs_standard_error(hdl, ret, errbuf);
3628         }
3629         for (pair = nvlist_next_nvpair(errlist, NULL);
3630             pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
3631                 char errbuf[1024];
3632                 (void) snprintf(errbuf, sizeof (errbuf),
3633                     dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
3634                     nvpair_name(pair));
3635
3636                 switch (fnvpair_value_int32(pair)) {
3637                 case EEXIST:
3638                         zfs_error_aux(hdl,
3639                             dgettext(TEXT_DOMAIN, "snapshot is cloned"));
3640                         ret = zfs_error(hdl, EZFS_EXISTS, errbuf);
3641                         break;
3642                 default:
3643                         ret = zfs_standard_error(hdl, errno, errbuf);
3644                         break;
3645                 }
3646         }
3647
3648         nvlist_free(errlist);
3649         return (ret);
3650 }
3651
3652 /*
3653  * Clones the given dataset.  The target must be of the same type as the source.
3654  */
3655 int
3656 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
3657 {
3658         char parent[ZFS_MAX_DATASET_NAME_LEN];
3659         int ret;
3660         char errbuf[1024];
3661         libzfs_handle_t *hdl = zhp->zfs_hdl;
3662         uint64_t zoned;
3663
3664         assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
3665
3666         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3667             "cannot create '%s'"), target);
3668
3669         /* validate the target/clone name */
3670         if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
3671                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3672
3673         /* validate parents exist */
3674         if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
3675                 return (-1);
3676
3677         (void) parent_name(target, parent, sizeof (parent));
3678
3679         /* do the clone */
3680
3681         if (props) {
3682                 zfs_type_t type;
3683                 if (ZFS_IS_VOLUME(zhp)) {
3684                         type = ZFS_TYPE_VOLUME;
3685                 } else {
3686                         type = ZFS_TYPE_FILESYSTEM;
3687                 }
3688                 if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3689                     zhp, zhp->zpool_hdl, errbuf)) == NULL)
3690                         return (-1);
3691         }
3692
3693         ret = lzc_clone(target, zhp->zfs_name, props);
3694         nvlist_free(props);
3695
3696         if (ret != 0) {
3697                 switch (errno) {
3698
3699                 case ENOENT:
3700                         /*
3701                          * The parent doesn't exist.  We should have caught this
3702                          * above, but there may a race condition that has since
3703                          * destroyed the parent.
3704                          *
3705                          * At this point, we don't know whether it's the source
3706                          * that doesn't exist anymore, or whether the target
3707                          * dataset doesn't exist.
3708                          */
3709                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3710                             "no such parent '%s'"), parent);
3711                         return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
3712
3713                 case EXDEV:
3714                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3715                             "source and target pools differ"));
3716                         return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
3717                             errbuf));
3718
3719                 default:
3720                         return (zfs_standard_error(zhp->zfs_hdl, errno,
3721                             errbuf));
3722                 }
3723         }
3724
3725         return (ret);
3726 }
3727
3728 /*
3729  * Promotes the given clone fs to be the clone parent.
3730  */
3731 int
3732 zfs_promote(zfs_handle_t *zhp)
3733 {
3734         libzfs_handle_t *hdl = zhp->zfs_hdl;
3735         char snapname[ZFS_MAX_DATASET_NAME_LEN];
3736         int ret;
3737         char errbuf[1024];
3738
3739         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3740             "cannot promote '%s'"), zhp->zfs_name);
3741
3742         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3743                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3744                     "snapshots can not be promoted"));
3745                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3746         }
3747
3748         if (zhp->zfs_dmustats.dds_origin[0] == '\0') {
3749                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3750                     "not a cloned filesystem"));
3751                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3752         }
3753
3754         ret = lzc_promote(zhp->zfs_name, snapname, sizeof (snapname));
3755
3756         if (ret != 0) {
3757                 switch (ret) {
3758                 case EEXIST:
3759                         /* There is a conflicting snapshot name. */
3760                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3761                             "conflicting snapshot '%s' from parent '%s'"),
3762                             snapname, zhp->zfs_dmustats.dds_origin);
3763                         return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3764
3765                 default:
3766                         return (zfs_standard_error(hdl, ret, errbuf));
3767                 }
3768         }
3769         return (ret);
3770 }
3771
3772 typedef struct snapdata {
3773         nvlist_t *sd_nvl;
3774         const char *sd_snapname;
3775 } snapdata_t;
3776
3777 static int
3778 zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
3779 {
3780         snapdata_t *sd = arg;
3781         char name[ZFS_MAX_DATASET_NAME_LEN];
3782         int rv = 0;
3783
3784         if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
3785                 if (snprintf(name, sizeof (name), "%s@%s", zfs_get_name(zhp),
3786                     sd->sd_snapname) >= sizeof (name))
3787                         return (EINVAL);
3788
3789                 fnvlist_add_boolean(sd->sd_nvl, name);
3790
3791                 rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
3792         }
3793         zfs_close(zhp);
3794
3795         return (rv);
3796 }
3797
3798 /*
3799  * Creates snapshots.  The keys in the snaps nvlist are the snapshots to be
3800  * created.
3801  */
3802 int
3803 zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
3804 {
3805         int ret;
3806         char errbuf[1024];
3807         nvpair_t *elem;
3808         nvlist_t *errors;
3809         zpool_handle_t *zpool_hdl;
3810         char pool[ZFS_MAX_DATASET_NAME_LEN];
3811
3812         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3813             "cannot create snapshots "));
3814
3815         elem = NULL;
3816         while ((elem = nvlist_next_nvpair(snaps, elem)) != NULL) {
3817                 const char *snapname = nvpair_name(elem);
3818
3819                 /* validate the target name */
3820                 if (!zfs_validate_name(hdl, snapname, ZFS_TYPE_SNAPSHOT,
3821                     B_TRUE)) {
3822                         (void) snprintf(errbuf, sizeof (errbuf),
3823                             dgettext(TEXT_DOMAIN,
3824                             "cannot create snapshot '%s'"), snapname);
3825                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3826                 }
3827         }
3828
3829         /*
3830          * get pool handle for prop validation. assumes all snaps are in the
3831          * same pool, as does lzc_snapshot (below).
3832          */
3833         elem = nvlist_next_nvpair(snaps, NULL);
3834         (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
3835         pool[strcspn(pool, "/@")] = '\0';
3836         zpool_hdl = zpool_open(hdl, pool);
3837         if (zpool_hdl == NULL)
3838                 return (-1);
3839
3840         if (props != NULL &&
3841             (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
3842             props, B_FALSE, NULL, zpool_hdl, errbuf)) == NULL) {
3843                 zpool_close(zpool_hdl);
3844                 return (-1);
3845         }
3846         zpool_close(zpool_hdl);
3847
3848         ret = lzc_snapshot(snaps, props, &errors);
3849
3850         if (ret != 0) {
3851                 boolean_t printed = B_FALSE;
3852                 for (elem = nvlist_next_nvpair(errors, NULL);
3853                     elem != NULL;
3854                     elem = nvlist_next_nvpair(errors, elem)) {
3855                         (void) snprintf(errbuf, sizeof (errbuf),
3856                             dgettext(TEXT_DOMAIN,
3857                             "cannot create snapshot '%s'"), nvpair_name(elem));
3858                         (void) zfs_standard_error(hdl,
3859                             fnvpair_value_int32(elem), errbuf);
3860                         printed = B_TRUE;
3861                 }
3862                 if (!printed) {
3863                         switch (ret) {
3864                         case EXDEV:
3865                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3866                                     "multiple snapshots of same "
3867                                     "fs not allowed"));
3868                                 (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
3869
3870                                 break;
3871                         default:
3872                                 (void) zfs_standard_error(hdl, ret, errbuf);
3873                         }
3874                 }
3875         }
3876
3877         nvlist_free(props);
3878         nvlist_free(errors);
3879         return (ret);
3880 }
3881
3882 int
3883 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
3884     nvlist_t *props)
3885 {
3886         int ret;
3887         snapdata_t sd = { 0 };
3888         char fsname[ZFS_MAX_DATASET_NAME_LEN];
3889         char *cp;
3890         zfs_handle_t *zhp;
3891         char errbuf[1024];
3892
3893         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3894             "cannot snapshot %s"), path);
3895
3896         if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
3897                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3898
3899         (void) strlcpy(fsname, path, sizeof (fsname));
3900         cp = strchr(fsname, '@');
3901         *cp = '\0';
3902         sd.sd_snapname = cp + 1;
3903
3904         if ((zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM |
3905             ZFS_TYPE_VOLUME)) == NULL) {
3906                 return (-1);
3907         }
3908
3909         verify(nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) == 0);
3910         if (recursive) {
3911                 (void) zfs_snapshot_cb(zfs_handle_dup(zhp), &sd);
3912         } else {
3913                 fnvlist_add_boolean(sd.sd_nvl, path);
3914         }
3915
3916         ret = zfs_snapshot_nvl(hdl, sd.sd_nvl, props);
3917         nvlist_free(sd.sd_nvl);
3918         zfs_close(zhp);
3919         return (ret);
3920 }
3921
3922 /*
3923  * Destroy any more recent snapshots.  We invoke this callback on any dependents
3924  * of the snapshot first.  If the 'cb_dependent' member is non-zero, then this
3925  * is a dependent and we should just destroy it without checking the transaction
3926  * group.
3927  */
3928 typedef struct rollback_data {
3929         const char      *cb_target;             /* the snapshot */
3930         uint64_t        cb_create;              /* creation time reference */
3931         boolean_t       cb_error;
3932         boolean_t       cb_force;
3933 } rollback_data_t;
3934
3935 static int
3936 rollback_destroy_dependent(zfs_handle_t *zhp, void *data)
3937 {
3938         rollback_data_t *cbp = data;
3939         prop_changelist_t *clp;
3940
3941         /* We must destroy this clone; first unmount it */
3942         clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
3943             cbp->cb_force ? MS_FORCE: 0);
3944         if (clp == NULL || changelist_prefix(clp) != 0) {
3945                 cbp->cb_error = B_TRUE;
3946                 zfs_close(zhp);
3947                 return (0);
3948         }
3949         if (zfs_destroy(zhp, B_FALSE) != 0)
3950                 cbp->cb_error = B_TRUE;
3951         else
3952                 changelist_remove(clp, zhp->zfs_name);
3953         (void) changelist_postfix(clp);
3954         changelist_free(clp);
3955
3956         zfs_close(zhp);
3957         return (0);
3958 }
3959
3960 static int
3961 rollback_destroy(zfs_handle_t *zhp, void *data)
3962 {
3963         rollback_data_t *cbp = data;
3964
3965         if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) {
3966                 cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
3967                     rollback_destroy_dependent, cbp);
3968
3969                 cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
3970         }
3971
3972         zfs_close(zhp);
3973         return (0);
3974 }
3975
3976 /*
3977  * Given a dataset, rollback to a specific snapshot, discarding any
3978  * data changes since then and making it the active dataset.
3979  *
3980  * Any snapshots and bookmarks more recent than the target are
3981  * destroyed, along with their dependents (i.e. clones).
3982  */
3983 int
3984 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
3985 {
3986         rollback_data_t cb = { 0 };
3987         int err;
3988         boolean_t restore_resv = 0;
3989         uint64_t old_volsize = 0, new_volsize;
3990         zfs_prop_t resv_prop = { 0 };
3991
3992         assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
3993             zhp->zfs_type == ZFS_TYPE_VOLUME);
3994
3995         /*
3996          * Destroy all recent snapshots and their dependents.
3997          */
3998         cb.cb_force = force;
3999         cb.cb_target = snap->zfs_name;
4000         cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
4001         (void) zfs_iter_snapshots(zhp, B_FALSE, rollback_destroy, &cb);
4002         (void) zfs_iter_bookmarks(zhp, rollback_destroy, &cb);
4003
4004         if (cb.cb_error)
4005                 return (-1);
4006
4007         /*
4008          * Now that we have verified that the snapshot is the latest,
4009          * rollback to the given snapshot.
4010          */
4011
4012         if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
4013                 if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
4014                         return (-1);
4015                 old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
4016                 restore_resv =
4017                     (old_volsize == zfs_prop_get_int(zhp, resv_prop));
4018         }
4019
4020         /*
4021          * We rely on zfs_iter_children() to verify that there are no
4022          * newer snapshots for the given dataset.  Therefore, we can
4023          * simply pass the name on to the ioctl() call.  There is still
4024          * an unlikely race condition where the user has taken a
4025          * snapshot since we verified that this was the most recent.
4026          */
4027         err = lzc_rollback(zhp->zfs_name, NULL, 0);
4028         if (err != 0) {
4029                 (void) zfs_standard_error_fmt(zhp->zfs_hdl, errno,
4030                     dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
4031                     zhp->zfs_name);
4032                 return (err);
4033         }
4034
4035         /*
4036          * For volumes, if the pre-rollback volsize matched the pre-
4037          * rollback reservation and the volsize has changed then set
4038          * the reservation property to the post-rollback volsize.
4039          * Make a new handle since the rollback closed the dataset.
4040          */
4041         if ((zhp->zfs_type == ZFS_TYPE_VOLUME) &&
4042             (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) {
4043                 if (restore_resv) {
4044                         new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
4045                         if (old_volsize != new_volsize)
4046                                 err = zfs_prop_set_int(zhp, resv_prop,
4047                                     new_volsize);
4048                 }
4049                 zfs_close(zhp);
4050         }
4051         return (err);
4052 }
4053
4054 /*
4055  * Renames the given dataset.
4056  */
4057 int
4058 zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
4059     boolean_t force_unmount)
4060 {
4061         int ret = 0;
4062         zfs_cmd_t zc = {"\0"};
4063         char *delim;
4064         prop_changelist_t *cl = NULL;
4065         zfs_handle_t *zhrp = NULL;
4066         char *parentname = NULL;
4067         char parent[ZFS_MAX_DATASET_NAME_LEN];
4068         libzfs_handle_t *hdl = zhp->zfs_hdl;
4069         char errbuf[1024];
4070
4071         /* if we have the same exact name, just return success */
4072         if (strcmp(zhp->zfs_name, target) == 0)
4073                 return (0);
4074
4075         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4076             "cannot rename to '%s'"), target);
4077
4078         /*
4079          * Make sure the target name is valid
4080          */
4081         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
4082                 if ((strchr(target, '@') == NULL) ||
4083                     *target == '@') {
4084                         /*
4085                          * Snapshot target name is abbreviated,
4086                          * reconstruct full dataset name
4087                          */
4088                         (void) strlcpy(parent, zhp->zfs_name,
4089                             sizeof (parent));
4090                         delim = strchr(parent, '@');
4091                         if (strchr(target, '@') == NULL)
4092                                 *(++delim) = '\0';
4093                         else
4094                                 *delim = '\0';
4095                         (void) strlcat(parent, target, sizeof (parent));
4096                         target = parent;
4097                 } else {
4098                         /*
4099                          * Make sure we're renaming within the same dataset.
4100                          */
4101                         delim = strchr(target, '@');
4102                         if (strncmp(zhp->zfs_name, target, delim - target)
4103                             != 0 || zhp->zfs_name[delim - target] != '@') {
4104                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4105                                     "snapshots must be part of same "
4106                                     "dataset"));
4107                                 return (zfs_error(hdl, EZFS_CROSSTARGET,
4108                                     errbuf));
4109                         }
4110                 }
4111                 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
4112                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4113         } else {
4114                 if (recursive) {
4115                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4116                             "recursive rename must be a snapshot"));
4117                         return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4118                 }
4119
4120                 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
4121                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4122
4123                 /* validate parents */
4124                 if (check_parents(hdl, target, NULL, B_FALSE, NULL) != 0)
4125                         return (-1);
4126
4127                 /* make sure we're in the same pool */
4128                 verify((delim = strchr(target, '/')) != NULL);
4129                 if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
4130                     zhp->zfs_name[delim - target] != '/') {
4131                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4132                             "datasets must be within same pool"));
4133                         return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
4134                 }
4135
4136                 /* new name cannot be a child of the current dataset name */
4137                 if (is_descendant(zhp->zfs_name, target)) {
4138                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4139                             "New dataset name cannot be a descendant of "
4140                             "current dataset name"));
4141                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4142                 }
4143         }
4144
4145         (void) snprintf(errbuf, sizeof (errbuf),
4146             dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
4147
4148         if (getzoneid() == GLOBAL_ZONEID &&
4149             zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
4150                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4151                     "dataset is used in a non-global zone"));
4152                 return (zfs_error(hdl, EZFS_ZONED, errbuf));
4153         }
4154
4155         if (recursive) {
4156                 parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
4157                 if (parentname == NULL) {
4158                         ret = -1;
4159                         goto error;
4160                 }
4161                 delim = strchr(parentname, '@');
4162                 *delim = '\0';
4163                 zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET);
4164                 if (zhrp == NULL) {
4165                         ret = -1;
4166                         goto error;
4167                 }
4168         } else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
4169                 if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0,
4170                     force_unmount ? MS_FORCE : 0)) == NULL)
4171                         return (-1);
4172
4173                 if (changelist_haszonedchild(cl)) {
4174                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4175                             "child dataset with inherited mountpoint is used "
4176                             "in a non-global zone"));
4177                         (void) zfs_error(hdl, EZFS_ZONED, errbuf);
4178                         ret = -1;
4179                         goto error;
4180                 }
4181
4182                 if ((ret = changelist_prefix(cl)) != 0)
4183                         goto error;
4184         }
4185
4186         if (ZFS_IS_VOLUME(zhp))
4187                 zc.zc_objset_type = DMU_OST_ZVOL;
4188         else
4189                 zc.zc_objset_type = DMU_OST_ZFS;
4190
4191         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4192         (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
4193
4194         zc.zc_cookie = recursive;
4195
4196         if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
4197                 /*
4198                  * if it was recursive, the one that actually failed will
4199                  * be in zc.zc_name
4200                  */
4201                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4202                     "cannot rename '%s'"), zc.zc_name);
4203
4204                 if (recursive && errno == EEXIST) {
4205                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4206                             "a child dataset already has a snapshot "
4207                             "with the new name"));
4208                         (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
4209                 } else {
4210                         (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
4211                 }
4212
4213                 /*
4214                  * On failure, we still want to remount any filesystems that
4215                  * were previously mounted, so we don't alter the system state.
4216                  */
4217                 if (cl != NULL)
4218                         (void) changelist_postfix(cl);
4219         } else {
4220                 if (cl != NULL) {
4221                         changelist_rename(cl, zfs_get_name(zhp), target);
4222                         ret = changelist_postfix(cl);
4223                 }
4224         }
4225
4226 error:
4227         if (parentname != NULL) {
4228                 free(parentname);
4229         }
4230         if (zhrp != NULL) {
4231                 zfs_close(zhrp);
4232         }
4233         if (cl != NULL) {
4234                 changelist_free(cl);
4235         }
4236         return (ret);
4237 }
4238
4239 nvlist_t *
4240 zfs_get_user_props(zfs_handle_t *zhp)
4241 {
4242         return (zhp->zfs_user_props);
4243 }
4244
4245 /*
4246  * This function is used by 'zfs list' to determine the exact set of columns to
4247  * display, and their maximum widths.  This does two main things:
4248  *
4249  *      - If this is a list of all properties, then expand the list to include
4250  *        all native properties, and set a flag so that for each dataset we look
4251  *        for new unique user properties and add them to the list.
4252  *
4253  *      - For non fixed-width properties, keep track of the maximum width seen
4254  *        so that we can size the column appropriately. If the user has
4255  *        requested received property values, we also need to compute the width
4256  *        of the RECEIVED column.
4257  */
4258 int
4259 zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received,
4260     boolean_t literal)
4261 {
4262         libzfs_handle_t *hdl = zhp->zfs_hdl;
4263         zprop_list_t *entry;
4264         zprop_list_t **last, **start;
4265         nvlist_t *userprops, *propval;
4266         nvpair_t *elem;
4267         char *strval;
4268         char buf[ZFS_MAXPROPLEN];
4269
4270         if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0)
4271                 return (-1);
4272
4273         userprops = zfs_get_user_props(zhp);
4274
4275         entry = *plp;
4276         if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
4277                 /*
4278                  * Go through and add any user properties as necessary.  We
4279                  * start by incrementing our list pointer to the first
4280                  * non-native property.
4281                  */
4282                 start = plp;
4283                 while (*start != NULL) {
4284                         if ((*start)->pl_prop == ZPROP_INVAL)
4285                                 break;
4286                         start = &(*start)->pl_next;
4287                 }
4288
4289                 elem = NULL;
4290                 while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
4291                         /*
4292                          * See if we've already found this property in our list.
4293                          */
4294                         for (last = start; *last != NULL;
4295                             last = &(*last)->pl_next) {
4296                                 if (strcmp((*last)->pl_user_prop,
4297                                     nvpair_name(elem)) == 0)
4298                                         break;
4299                         }
4300
4301                         if (*last == NULL) {
4302                                 if ((entry = zfs_alloc(hdl,
4303                                     sizeof (zprop_list_t))) == NULL ||
4304                                     ((entry->pl_user_prop = zfs_strdup(hdl,
4305                                     nvpair_name(elem)))) == NULL) {
4306                                         free(entry);
4307                                         return (-1);
4308                                 }
4309
4310                                 entry->pl_prop = ZPROP_INVAL;
4311                                 entry->pl_width = strlen(nvpair_name(elem));
4312                                 entry->pl_all = B_TRUE;
4313                                 *last = entry;
4314                         }
4315                 }
4316         }
4317
4318         /*
4319          * Now go through and check the width of any non-fixed columns
4320          */
4321         for (entry = *plp; entry != NULL; entry = entry->pl_next) {
4322                 if (entry->pl_fixed && !literal)
4323                         continue;
4324
4325                 if (entry->pl_prop != ZPROP_INVAL) {
4326                         if (zfs_prop_get(zhp, entry->pl_prop,
4327                             buf, sizeof (buf), NULL, NULL, 0, literal) == 0) {
4328                                 if (strlen(buf) > entry->pl_width)
4329                                         entry->pl_width = strlen(buf);
4330                         }
4331                         if (received && zfs_prop_get_recvd(zhp,
4332                             zfs_prop_to_name(entry->pl_prop),
4333                             buf, sizeof (buf), literal) == 0)
4334                                 if (strlen(buf) > entry->pl_recvd_width)
4335                                         entry->pl_recvd_width = strlen(buf);
4336                 } else {
4337                         if (nvlist_lookup_nvlist(userprops, entry->pl_user_prop,
4338                             &propval) == 0) {
4339                                 verify(nvlist_lookup_string(propval,
4340                                     ZPROP_VALUE, &strval) == 0);
4341                                 if (strlen(strval) > entry->pl_width)
4342                                         entry->pl_width = strlen(strval);
4343                         }
4344                         if (received && zfs_prop_get_recvd(zhp,
4345                             entry->pl_user_prop,
4346                             buf, sizeof (buf), literal) == 0)
4347                                 if (strlen(buf) > entry->pl_recvd_width)
4348                                         entry->pl_recvd_width = strlen(buf);
4349                 }
4350         }
4351
4352         return (0);
4353 }
4354
4355 void
4356 zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
4357 {
4358         nvpair_t *curr;
4359         nvpair_t *next;
4360
4361         /*
4362          * Keep a reference to the props-table against which we prune the
4363          * properties.
4364          */
4365         zhp->zfs_props_table = props;
4366
4367         curr = nvlist_next_nvpair(zhp->zfs_props, NULL);
4368
4369         while (curr) {
4370                 zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
4371                 next = nvlist_next_nvpair(zhp->zfs_props, curr);
4372
4373                 /*
4374                  * User properties will result in ZPROP_INVAL, and since we
4375                  * only know how to prune standard ZFS properties, we always
4376                  * leave these in the list.  This can also happen if we
4377                  * encounter an unknown DSL property (when running older
4378                  * software, for example).
4379                  */
4380                 if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE)
4381                         (void) nvlist_remove(zhp->zfs_props,
4382                             nvpair_name(curr), nvpair_type(curr));
4383                 curr = next;
4384         }
4385 }
4386
4387 static int
4388 zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
4389     zfs_smb_acl_op_t cmd, char *resource1, char *resource2)
4390 {
4391         zfs_cmd_t zc = {"\0"};
4392         nvlist_t *nvlist = NULL;
4393         int error;
4394
4395         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4396         (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
4397         zc.zc_cookie = (uint64_t)cmd;
4398
4399         if (cmd == ZFS_SMB_ACL_RENAME) {
4400                 if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
4401                         (void) no_memory(hdl);
4402                         return (0);
4403                 }
4404         }
4405
4406         switch (cmd) {
4407         case ZFS_SMB_ACL_ADD:
4408         case ZFS_SMB_ACL_REMOVE:
4409                 (void) strlcpy(zc.zc_string, resource1, sizeof (zc.zc_string));
4410                 break;
4411         case ZFS_SMB_ACL_RENAME:
4412                 if (nvlist_add_string(nvlist, ZFS_SMB_ACL_SRC,
4413                     resource1) != 0) {
4414                                 (void) no_memory(hdl);
4415                                 return (-1);
4416                 }
4417                 if (nvlist_add_string(nvlist, ZFS_SMB_ACL_TARGET,
4418                     resource2) != 0) {
4419                                 (void) no_memory(hdl);
4420                                 return (-1);
4421                 }
4422                 if (zcmd_write_src_nvlist(hdl, &zc, nvlist) != 0) {
4423                         nvlist_free(nvlist);
4424                         return (-1);
4425                 }
4426                 break;
4427         case ZFS_SMB_ACL_PURGE:
4428                 break;
4429         default:
4430                 return (-1);
4431         }
4432         error = ioctl(hdl->libzfs_fd, ZFS_IOC_SMB_ACL, &zc);
4433         nvlist_free(nvlist);
4434         return (error);
4435 }
4436
4437 int
4438 zfs_smb_acl_add(libzfs_handle_t *hdl, char *dataset,
4439     char *path, char *resource)
4440 {
4441         return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_ADD,
4442             resource, NULL));
4443 }
4444
4445 int
4446 zfs_smb_acl_remove(libzfs_handle_t *hdl, char *dataset,
4447     char *path, char *resource)
4448 {
4449         return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_REMOVE,
4450             resource, NULL));
4451 }
4452
4453 int
4454 zfs_smb_acl_purge(libzfs_handle_t *hdl, char *dataset, char *path)
4455 {
4456         return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_PURGE,
4457             NULL, NULL));
4458 }
4459
4460 int
4461 zfs_smb_acl_rename(libzfs_handle_t *hdl, char *dataset, char *path,
4462     char *oldname, char *newname)
4463 {
4464         return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_RENAME,
4465             oldname, newname));
4466 }
4467
4468 int
4469 zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
4470     zfs_userspace_cb_t func, void *arg)
4471 {
4472         zfs_cmd_t zc = {"\0"};
4473         zfs_useracct_t buf[100];
4474         libzfs_handle_t *hdl = zhp->zfs_hdl;
4475         int ret;
4476
4477         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4478
4479         zc.zc_objset_type = type;
4480         zc.zc_nvlist_dst = (uintptr_t)buf;
4481
4482         for (;;) {
4483                 zfs_useracct_t *zua = buf;
4484
4485                 zc.zc_nvlist_dst_size = sizeof (buf);
4486                 if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) {
4487                         char errbuf[1024];
4488
4489                         if ((errno == ENOTSUP &&
4490                             (type == ZFS_PROP_USEROBJUSED ||
4491                             type == ZFS_PROP_GROUPOBJUSED ||
4492                             type == ZFS_PROP_USEROBJQUOTA ||
4493                             type == ZFS_PROP_GROUPOBJQUOTA)))
4494                                 break;
4495
4496                         (void) snprintf(errbuf, sizeof (errbuf),
4497                             dgettext(TEXT_DOMAIN,
4498                             "cannot get used/quota for %s"), zc.zc_name);
4499                         return (zfs_standard_error_fmt(hdl, errno, errbuf));
4500                 }
4501                 if (zc.zc_nvlist_dst_size == 0)
4502                         break;
4503
4504                 while (zc.zc_nvlist_dst_size > 0) {
4505                         if ((ret = func(arg, zua->zu_domain, zua->zu_rid,
4506                             zua->zu_space)) != 0)
4507                                 return (ret);
4508                         zua++;
4509                         zc.zc_nvlist_dst_size -= sizeof (zfs_useracct_t);
4510                 }
4511         }
4512
4513         return (0);
4514 }
4515
4516 struct holdarg {
4517         nvlist_t *nvl;
4518         const char *snapname;
4519         const char *tag;
4520         boolean_t recursive;
4521         int error;
4522 };
4523
4524 static int
4525 zfs_hold_one(zfs_handle_t *zhp, void *arg)
4526 {
4527         struct holdarg *ha = arg;
4528         char name[ZFS_MAX_DATASET_NAME_LEN];
4529         int rv = 0;
4530
4531         if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
4532             ha->snapname) >= sizeof (name))
4533                 return (EINVAL);
4534
4535         if (lzc_exists(name))
4536                 fnvlist_add_string(ha->nvl, name, ha->tag);
4537
4538         if (ha->recursive)
4539                 rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
4540         zfs_close(zhp);
4541         return (rv);
4542 }
4543
4544 int
4545 zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
4546     boolean_t recursive, int cleanup_fd)
4547 {
4548         int ret;
4549         struct holdarg ha;
4550
4551         ha.nvl = fnvlist_alloc();
4552         ha.snapname = snapname;
4553         ha.tag = tag;
4554         ha.recursive = recursive;
4555         (void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
4556
4557         if (nvlist_empty(ha.nvl)) {
4558                 char errbuf[1024];
4559
4560                 fnvlist_free(ha.nvl);
4561                 ret = ENOENT;
4562                 (void) snprintf(errbuf, sizeof (errbuf),
4563                     dgettext(TEXT_DOMAIN,
4564                     "cannot hold snapshot '%s@%s'"),
4565                     zhp->zfs_name, snapname);
4566                 (void) zfs_standard_error(zhp->zfs_hdl, ret, errbuf);
4567                 return (ret);
4568         }
4569
4570         ret = zfs_hold_nvl(zhp, cleanup_fd, ha.nvl);
4571         fnvlist_free(ha.nvl);
4572
4573         return (ret);
4574 }
4575
4576 int
4577 zfs_hold_nvl(zfs_handle_t *zhp, int cleanup_fd, nvlist_t *holds)
4578 {
4579         int ret;
4580         nvlist_t *errors;
4581         libzfs_handle_t *hdl = zhp->zfs_hdl;
4582         char errbuf[1024];
4583         nvpair_t *elem;
4584
4585         errors = NULL;
4586         ret = lzc_hold(holds, cleanup_fd, &errors);
4587
4588         if (ret == 0) {
4589                 /* There may be errors even in the success case. */
4590                 fnvlist_free(errors);
4591                 return (0);
4592         }
4593
4594         if (nvlist_empty(errors)) {
4595                 /* no hold-specific errors */
4596                 (void) snprintf(errbuf, sizeof (errbuf),
4597                     dgettext(TEXT_DOMAIN, "cannot hold"));
4598                 switch (ret) {
4599                 case ENOTSUP:
4600                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4601                             "pool must be upgraded"));
4602                         (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4603                         break;
4604                 case EINVAL:
4605                         (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4606                         break;
4607                 default:
4608                         (void) zfs_standard_error(hdl, ret, errbuf);
4609                 }
4610         }
4611
4612         for (elem = nvlist_next_nvpair(errors, NULL);
4613             elem != NULL;
4614             elem = nvlist_next_nvpair(errors, elem)) {
4615                 (void) snprintf(errbuf, sizeof (errbuf),
4616                     dgettext(TEXT_DOMAIN,
4617                     "cannot hold snapshot '%s'"), nvpair_name(elem));
4618                 switch (fnvpair_value_int32(elem)) {
4619                 case E2BIG:
4620                         /*
4621                          * Temporary tags wind up having the ds object id
4622                          * prepended. So even if we passed the length check
4623                          * above, it's still possible for the tag to wind
4624                          * up being slightly too long.
4625                          */
4626                         (void) zfs_error(hdl, EZFS_TAGTOOLONG, errbuf);
4627                         break;
4628                 case EINVAL:
4629                         (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4630                         break;
4631                 case EEXIST:
4632                         (void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf);
4633                         break;
4634                 default:
4635                         (void) zfs_standard_error(hdl,
4636                             fnvpair_value_int32(elem), errbuf);
4637                 }
4638         }
4639
4640         fnvlist_free(errors);
4641         return (ret);
4642 }
4643
4644 static int
4645 zfs_release_one(zfs_handle_t *zhp, void *arg)
4646 {
4647         struct holdarg *ha = arg;
4648         char name[ZFS_MAX_DATASET_NAME_LEN];
4649         int rv = 0;
4650         nvlist_t *existing_holds;
4651
4652         if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
4653             ha->snapname) >= sizeof (name)) {
4654                 ha->error = EINVAL;
4655                 rv = EINVAL;
4656         }
4657
4658         if (lzc_get_holds(name, &existing_holds) != 0) {
4659                 ha->error = ENOENT;
4660         } else if (!nvlist_exists(existing_holds, ha->tag)) {
4661                 ha->error = ESRCH;
4662         } else {
4663                 nvlist_t *torelease = fnvlist_alloc();
4664                 fnvlist_add_boolean(torelease, ha->tag);
4665                 fnvlist_add_nvlist(ha->nvl, name, torelease);
4666                 fnvlist_free(torelease);
4667         }
4668
4669         if (ha->recursive)
4670                 rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
4671         zfs_close(zhp);
4672         return (rv);
4673 }
4674
4675 int
4676 zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
4677     boolean_t recursive)
4678 {
4679         int ret;
4680         struct holdarg ha;
4681         nvlist_t *errors = NULL;
4682         nvpair_t *elem;
4683         libzfs_handle_t *hdl = zhp->zfs_hdl;
4684         char errbuf[1024];
4685
4686         ha.nvl = fnvlist_alloc();
4687         ha.snapname = snapname;
4688         ha.tag = tag;
4689         ha.recursive = recursive;
4690         ha.error = 0;
4691         (void) zfs_release_one(zfs_handle_dup(zhp), &ha);
4692
4693         if (nvlist_empty(ha.nvl)) {
4694                 fnvlist_free(ha.nvl);
4695                 ret = ha.error;
4696                 (void) snprintf(errbuf, sizeof (errbuf),
4697                     dgettext(TEXT_DOMAIN,
4698                     "cannot release hold from snapshot '%s@%s'"),
4699                     zhp->zfs_name, snapname);
4700                 if (ret == ESRCH) {
4701                         (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
4702                 } else {
4703                         (void) zfs_standard_error(hdl, ret, errbuf);
4704                 }
4705                 return (ret);
4706         }
4707
4708         ret = lzc_release(ha.nvl, &errors);
4709         fnvlist_free(ha.nvl);
4710
4711         if (ret == 0) {
4712                 /* There may be errors even in the success case. */
4713                 fnvlist_free(errors);
4714                 return (0);
4715         }
4716
4717         if (nvlist_empty(errors)) {
4718                 /* no hold-specific errors */
4719                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4720                     "cannot release"));
4721                 switch (errno) {
4722                 case ENOTSUP:
4723                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4724                             "pool must be upgraded"));
4725                         (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4726                         break;
4727                 default:
4728                         (void) zfs_standard_error_fmt(hdl, errno, errbuf);
4729                 }
4730         }
4731
4732         for (elem = nvlist_next_nvpair(errors, NULL);
4733             elem != NULL;
4734             elem = nvlist_next_nvpair(errors, elem)) {
4735                 (void) snprintf(errbuf, sizeof (errbuf),
4736                     dgettext(TEXT_DOMAIN,
4737                     "cannot release hold from snapshot '%s'"),
4738                     nvpair_name(elem));
4739                 switch (fnvpair_value_int32(elem)) {
4740                 case ESRCH:
4741                         (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
4742                         break;
4743                 case EINVAL:
4744                         (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4745                         break;
4746                 default:
4747                         (void) zfs_standard_error_fmt(hdl,
4748                             fnvpair_value_int32(elem), errbuf);
4749                 }
4750         }
4751
4752         fnvlist_free(errors);
4753         return (ret);
4754 }
4755
4756 int
4757 zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl)
4758 {
4759         zfs_cmd_t zc = {"\0"};
4760         libzfs_handle_t *hdl = zhp->zfs_hdl;
4761         int nvsz = 2048;
4762         void *nvbuf;
4763         int err = 0;
4764         char errbuf[1024];
4765
4766         assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
4767             zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
4768
4769 tryagain:
4770
4771         nvbuf = malloc(nvsz);
4772         if (nvbuf == NULL) {
4773                 err = (zfs_error(hdl, EZFS_NOMEM, strerror(errno)));
4774                 goto out;
4775         }
4776
4777         zc.zc_nvlist_dst_size = nvsz;
4778         zc.zc_nvlist_dst = (uintptr_t)nvbuf;
4779
4780         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4781
4782         if (ioctl(hdl->libzfs_fd, ZFS_IOC_GET_FSACL, &zc) != 0) {
4783                 (void) snprintf(errbuf, sizeof (errbuf),
4784                     dgettext(TEXT_DOMAIN, "cannot get permissions on '%s'"),
4785                     zc.zc_name);
4786                 switch (errno) {
4787                 case ENOMEM:
4788                         free(nvbuf);
4789                         nvsz = zc.zc_nvlist_dst_size;
4790                         goto tryagain;
4791
4792                 case ENOTSUP:
4793                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4794                             "pool must be upgraded"));
4795                         err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
4796                         break;
4797                 case EINVAL:
4798                         err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
4799                         break;
4800                 case ENOENT:
4801                         err = zfs_error(hdl, EZFS_NOENT, errbuf);
4802                         break;
4803                 default:
4804                         err = zfs_standard_error_fmt(hdl, errno, errbuf);
4805                         break;
4806                 }
4807         } else {
4808                 /* success */
4809                 int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0);
4810                 if (rc) {
4811                         (void) snprintf(errbuf, sizeof (errbuf), dgettext(
4812                             TEXT_DOMAIN, "cannot get permissions on '%s'"),
4813                             zc.zc_name);
4814                         err = zfs_standard_error_fmt(hdl, rc, errbuf);
4815                 }
4816         }
4817
4818         free(nvbuf);
4819 out:
4820         return (err);
4821 }
4822
4823 int
4824 zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
4825 {
4826         zfs_cmd_t zc = {"\0"};
4827         libzfs_handle_t *hdl = zhp->zfs_hdl;
4828         char *nvbuf;
4829         char errbuf[1024];
4830         size_t nvsz;
4831         int err;
4832
4833         assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
4834             zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
4835
4836         err = nvlist_size(nvl, &nvsz, NV_ENCODE_NATIVE);
4837         assert(err == 0);
4838
4839         nvbuf = malloc(nvsz);
4840
4841         err = nvlist_pack(nvl, &nvbuf, &nvsz, NV_ENCODE_NATIVE, 0);
4842         assert(err == 0);
4843
4844         zc.zc_nvlist_src_size = nvsz;
4845         zc.zc_nvlist_src = (uintptr_t)nvbuf;
4846         zc.zc_perm_action = un;
4847
4848         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4849
4850         if (zfs_ioctl(hdl, ZFS_IOC_SET_FSACL, &zc) != 0) {
4851                 (void) snprintf(errbuf, sizeof (errbuf),
4852                     dgettext(TEXT_DOMAIN, "cannot set permissions on '%s'"),
4853                     zc.zc_name);
4854                 switch (errno) {
4855                 case ENOTSUP:
4856                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4857                             "pool must be upgraded"));
4858                         err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
4859                         break;
4860                 case EINVAL:
4861                         err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
4862                         break;
4863                 case ENOENT:
4864                         err = zfs_error(hdl, EZFS_NOENT, errbuf);
4865                         break;
4866                 default:
4867                         err = zfs_standard_error_fmt(hdl, errno, errbuf);
4868                         break;
4869                 }
4870         }
4871
4872         free(nvbuf);
4873
4874         return (err);
4875 }
4876
4877 int
4878 zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl)
4879 {
4880         int err;
4881         char errbuf[1024];
4882
4883         err = lzc_get_holds(zhp->zfs_name, nvl);
4884
4885         if (err != 0) {
4886                 libzfs_handle_t *hdl = zhp->zfs_hdl;
4887
4888                 (void) snprintf(errbuf, sizeof (errbuf),
4889                     dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
4890                     zhp->zfs_name);
4891                 switch (err) {
4892                 case ENOTSUP:
4893                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4894                             "pool must be upgraded"));
4895                         err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
4896                         break;
4897                 case EINVAL:
4898                         err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
4899                         break;
4900                 case ENOENT:
4901                         err = zfs_error(hdl, EZFS_NOENT, errbuf);
4902                         break;
4903                 default:
4904                         err = zfs_standard_error_fmt(hdl, errno, errbuf);
4905                         break;
4906                 }
4907         }
4908
4909         return (err);
4910 }
4911
4912 /*
4913  * Convert the zvol's volume size to an appropriate reservation.
4914  * Note: If this routine is updated, it is necessary to update the ZFS test
4915  * suite's shell version in reservation.kshlib.
4916  */
4917 uint64_t
4918 zvol_volsize_to_reservation(uint64_t volsize, nvlist_t *props)
4919 {
4920         uint64_t numdb;
4921         uint64_t nblocks, volblocksize;
4922         int ncopies;
4923         char *strval;
4924
4925         if (nvlist_lookup_string(props,
4926             zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)
4927                 ncopies = atoi(strval);
4928         else
4929                 ncopies = 1;
4930         if (nvlist_lookup_uint64(props,
4931             zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
4932             &volblocksize) != 0)
4933                 volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
4934         nblocks = volsize/volblocksize;
4935         /* start with metadnode L0-L6 */
4936         numdb = 7;
4937         /* calculate number of indirects */
4938         while (nblocks > 1) {
4939                 nblocks += DNODES_PER_LEVEL - 1;
4940                 nblocks /= DNODES_PER_LEVEL;
4941                 numdb += nblocks;
4942         }
4943         numdb *= MIN(SPA_DVAS_PER_BP, ncopies + 1);
4944         volsize *= ncopies;
4945         /*
4946          * this is exactly DN_MAX_INDBLKSHIFT when metadata isn't
4947          * compressed, but in practice they compress down to about
4948          * 1100 bytes
4949          */
4950         numdb *= 1ULL << DN_MAX_INDBLKSHIFT;
4951         volsize += numdb;
4952         return (volsize);
4953 }