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