Home | History | Annotate | Line # | Download | only in zfs
      1   1.1      haad /*
      2   1.1      haad  * CDDL HEADER START
      3   1.1      haad  *
      4   1.1      haad  * The contents of this file are subject to the terms of the
      5   1.1      haad  * Common Development and Distribution License (the "License").
      6   1.1      haad  * You may not use this file except in compliance with the License.
      7   1.1      haad  *
      8   1.1      haad  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9   1.1      haad  * or http://www.opensolaris.org/os/licensing.
     10   1.1      haad  * See the License for the specific language governing permissions
     11   1.1      haad  * and limitations under the License.
     12   1.1      haad  *
     13   1.1      haad  * When distributing Covered Code, include this CDDL HEADER in each
     14   1.1      haad  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15   1.1      haad  * If applicable, add the following below this CDDL HEADER, with the
     16   1.1      haad  * fields enclosed by brackets "[]" replaced with your own identifying
     17   1.1      haad  * information: Portions Copyright [yyyy] [name of copyright owner]
     18   1.1      haad  *
     19   1.1      haad  * CDDL HEADER END
     20   1.1      haad  */
     21  1.11       chs 
     22  1.11       chs /*
     23  1.11       chs  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     24  1.11       chs  * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
     25  1.11       chs  * Copyright 2013 Martin Matuska <mm (at) FreeBSD.org>. All rights reserved.
     26  1.11       chs  * Copyright 2014 Xin Li <delphij (at) FreeBSD.org>. All rights reserved.
     27  1.11       chs  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
     28  1.11       chs  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
     29  1.11       chs  * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved.
     30  1.11       chs  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
     31  1.11       chs  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
     32  1.11       chs  * Copyright (c) 2013 Steven Hartland. All rights reserved.
     33  1.11       chs  * Copyright (c) 2014 Integros [integros.com]
     34  1.11       chs  * Copyright 2016 Toomas Soome <tsoome (at) me.com>
     35  1.11       chs  */
     36  1.11       chs 
     37   1.1      haad /*
     38  1.11       chs  * ZFS ioctls.
     39  1.11       chs  *
     40  1.11       chs  * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
     41  1.11       chs  * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
     42  1.11       chs  *
     43  1.11       chs  * There are two ways that we handle ioctls: the legacy way where almost
     44  1.11       chs  * all of the logic is in the ioctl callback, and the new way where most
     45  1.11       chs  * of the marshalling is handled in the common entry point, zfsdev_ioctl().
     46  1.11       chs  *
     47  1.11       chs  * Non-legacy ioctls should be registered by calling
     48  1.11       chs  * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
     49  1.11       chs  * from userland by lzc_ioctl().
     50  1.11       chs  *
     51  1.11       chs  * The registration arguments are as follows:
     52  1.11       chs  *
     53  1.11       chs  * const char *name
     54  1.11       chs  *   The name of the ioctl.  This is used for history logging.  If the
     55  1.11       chs  *   ioctl returns successfully (the callback returns 0), and allow_log
     56  1.11       chs  *   is true, then a history log entry will be recorded with the input &
     57  1.11       chs  *   output nvlists.  The log entry can be printed with "zpool history -i".
     58  1.11       chs  *
     59  1.11       chs  * zfs_ioc_t ioc
     60  1.11       chs  *   The ioctl request number, which userland will pass to ioctl(2).
     61  1.11       chs  *   The ioctl numbers can change from release to release, because
     62  1.11       chs  *   the caller (libzfs) must be matched to the kernel.
     63  1.11       chs  *
     64  1.11       chs  * zfs_secpolicy_func_t *secpolicy
     65  1.11       chs  *   This function will be called before the zfs_ioc_func_t, to
     66  1.11       chs  *   determine if this operation is permitted.  It should return EPERM
     67  1.11       chs  *   on failure, and 0 on success.  Checks include determining if the
     68  1.11       chs  *   dataset is visible in this zone, and if the user has either all
     69  1.11       chs  *   zfs privileges in the zone (SYS_MOUNT), or has been granted permission
     70  1.11       chs  *   to do this operation on this dataset with "zfs allow".
     71  1.11       chs  *
     72  1.11       chs  * zfs_ioc_namecheck_t namecheck
     73  1.11       chs  *   This specifies what to expect in the zfs_cmd_t:zc_name -- a pool
     74  1.11       chs  *   name, a dataset name, or nothing.  If the name is not well-formed,
     75  1.11       chs  *   the ioctl will fail and the callback will not be called.
     76  1.11       chs  *   Therefore, the callback can assume that the name is well-formed
     77  1.11       chs  *   (e.g. is null-terminated, doesn't have more than one '@' character,
     78  1.11       chs  *   doesn't have invalid characters).
     79  1.11       chs  *
     80  1.11       chs  * zfs_ioc_poolcheck_t pool_check
     81  1.11       chs  *   This specifies requirements on the pool state.  If the pool does
     82  1.11       chs  *   not meet them (is suspended or is readonly), the ioctl will fail
     83  1.11       chs  *   and the callback will not be called.  If any checks are specified
     84  1.11       chs  *   (i.e. it is not POOL_CHECK_NONE), namecheck must not be NO_NAME.
     85  1.11       chs  *   Multiple checks can be or-ed together (e.g. POOL_CHECK_SUSPENDED |
     86  1.11       chs  *   POOL_CHECK_READONLY).
     87  1.11       chs  *
     88  1.11       chs  * boolean_t smush_outnvlist
     89  1.11       chs  *   If smush_outnvlist is true, then the output is presumed to be a
     90  1.11       chs  *   list of errors, and it will be "smushed" down to fit into the
     91  1.11       chs  *   caller's buffer, by removing some entries and replacing them with a
     92  1.11       chs  *   single "N_MORE_ERRORS" entry indicating how many were removed.  See
     93  1.11       chs  *   nvlist_smush() for details.  If smush_outnvlist is false, and the
     94  1.11       chs  *   outnvlist does not fit into the userland-provided buffer, then the
     95  1.11       chs  *   ioctl will fail with ENOMEM.
     96  1.11       chs  *
     97  1.11       chs  * zfs_ioc_func_t *func
     98  1.11       chs  *   The callback function that will perform the operation.
     99  1.11       chs  *
    100  1.11       chs  *   The callback should return 0 on success, or an error number on
    101  1.11       chs  *   failure.  If the function fails, the userland ioctl will return -1,
    102  1.11       chs  *   and errno will be set to the callback's return value.  The callback
    103  1.11       chs  *   will be called with the following arguments:
    104  1.11       chs  *
    105  1.11       chs  *   const char *name
    106  1.11       chs  *     The name of the pool or dataset to operate on, from
    107  1.11       chs  *     zfs_cmd_t:zc_name.  The 'namecheck' argument specifies the
    108  1.11       chs  *     expected type (pool, dataset, or none).
    109  1.11       chs  *
    110  1.11       chs  *   nvlist_t *innvl
    111  1.11       chs  *     The input nvlist, deserialized from zfs_cmd_t:zc_nvlist_src.  Or
    112  1.11       chs  *     NULL if no input nvlist was provided.  Changes to this nvlist are
    113  1.11       chs  *     ignored.  If the input nvlist could not be deserialized, the
    114  1.11       chs  *     ioctl will fail and the callback will not be called.
    115  1.11       chs  *
    116  1.11       chs  *   nvlist_t *outnvl
    117  1.11       chs  *     The output nvlist, initially empty.  The callback can fill it in,
    118  1.11       chs  *     and it will be returned to userland by serializing it into
    119  1.11       chs  *     zfs_cmd_t:zc_nvlist_dst.  If it is non-empty, and serialization
    120  1.11       chs  *     fails (e.g. because the caller didn't supply a large enough
    121  1.11       chs  *     buffer), then the overall ioctl will fail.  See the
    122  1.11       chs  *     'smush_nvlist' argument above for additional behaviors.
    123  1.11       chs  *
    124  1.11       chs  *     There are two typical uses of the output nvlist:
    125  1.11       chs  *       - To return state, e.g. property values.  In this case,
    126  1.11       chs  *         smush_outnvlist should be false.  If the buffer was not large
    127  1.11       chs  *         enough, the caller will reallocate a larger buffer and try
    128  1.11       chs  *         the ioctl again.
    129  1.11       chs  *
    130  1.11       chs  *       - To return multiple errors from an ioctl which makes on-disk
    131  1.11       chs  *         changes.  In this case, smush_outnvlist should be true.
    132  1.11       chs  *         Ioctls which make on-disk modifications should generally not
    133  1.11       chs  *         use the outnvl if they succeed, because the caller can not
    134  1.11       chs  *         distinguish between the operation failing, and
    135  1.11       chs  *         deserialization failing.
    136   1.1      haad  */
    137  1.11       chs #ifdef __FreeBSD__
    138  1.11       chs #include "opt_kstack_pages.h"
    139  1.11       chs #endif
    140   1.1      haad 
    141   1.1      haad #include <sys/types.h>
    142   1.1      haad #include <sys/param.h>
    143  1.11       chs #include <sys/systm.h>
    144  1.11       chs #include <sys/open.h>
    145  1.11       chs #include <sys/conf.h>
    146  1.11       chs #include <sys/kernel.h>
    147  1.11       chs #include <sys/lock.h>
    148  1.11       chs #include <sys/malloc.h>
    149  1.11       chs #include <sys/mutex.h>
    150  1.11       chs #include <sys/proc.h>
    151   1.1      haad #include <sys/errno.h>
    152   1.1      haad #include <sys/uio.h>
    153   1.1      haad #include <sys/buf.h>
    154   1.1      haad #include <sys/file.h>
    155   1.1      haad #include <sys/kmem.h>
    156   1.1      haad #include <sys/conf.h>
    157   1.1      haad #include <sys/cmn_err.h>
    158   1.1      haad #include <sys/stat.h>
    159   1.1      haad #include <sys/zfs_ioctl.h>
    160   1.4      haad #include <sys/zfs_vfsops.h>
    161   1.1      haad #include <sys/zfs_znode.h>
    162   1.1      haad #include <sys/zap.h>
    163   1.1      haad #include <sys/spa.h>
    164   1.1      haad #include <sys/spa_impl.h>
    165   1.1      haad #include <sys/vdev.h>
    166   1.1      haad #include <sys/dmu.h>
    167   1.1      haad #include <sys/dsl_dir.h>
    168   1.1      haad #include <sys/dsl_dataset.h>
    169   1.1      haad #include <sys/dsl_prop.h>
    170   1.1      haad #include <sys/dsl_deleg.h>
    171   1.1      haad #include <sys/dmu_objset.h>
    172  1.11       chs #include <sys/dmu_impl.h>
    173  1.11       chs #include <sys/dmu_tx.h>
    174   1.1      haad #include <sys/sunddi.h>
    175   1.1      haad #include <sys/policy.h>
    176   1.1      haad #include <sys/zone.h>
    177   1.1      haad #include <sys/nvpair.h>
    178   1.1      haad #include <sys/mount.h>
    179  1.11       chs #ifdef __FreeBSD__
    180  1.11       chs #include <sys/taskqueue.h>
    181  1.11       chs #endif
    182  1.11       chs #ifdef __NetBSD__
    183  1.11       chs #include <sys/callb.h>
    184  1.11       chs #include <sys/taskq.h>
    185  1.11       chs #endif
    186   1.1      haad #include <sys/sdt.h>
    187  1.11       chs #include <sys/varargs.h>
    188   1.1      haad #include <sys/fs/zfs.h>
    189   1.1      haad #include <sys/zfs_ctldir.h>
    190   1.1      haad #include <sys/zfs_dir.h>
    191  1.11       chs #include <sys/zfs_onexit.h>
    192   1.1      haad #include <sys/zvol.h>
    193  1.11       chs #include <sys/dsl_scan.h>
    194   1.1      haad #include <sys/dmu_objset.h>
    195  1.11       chs #include <sys/dmu_send.h>
    196  1.11       chs #include <sys/dsl_destroy.h>
    197  1.11       chs #include <sys/dsl_bookmark.h>
    198  1.11       chs #include <sys/dsl_userhold.h>
    199  1.11       chs #include <sys/zfeature.h>
    200  1.11       chs #include <sys/zio_checksum.h>
    201   1.1      haad 
    202   1.1      haad #include "zfs_namecheck.h"
    203   1.1      haad #include "zfs_prop.h"
    204   1.1      haad #include "zfs_deleg.h"
    205  1.11       chs #include "zfs_comutil.h"
    206  1.11       chs #include "zfs_ioctl_compat.h"
    207  1.11       chs 
    208  1.11       chs #ifdef __FreeBSD__
    209  1.11       chs CTASSERT(sizeof(zfs_cmd_t) < IOCPARM_MAX);
    210  1.11       chs static struct cdev *zfsdev;
    211  1.11       chs #endif
    212   1.1      haad 
    213   1.2      haad #ifdef __NetBSD__
    214  1.18   hannken static dev_info_t __zfs_devinfo = { -1, -1 };
    215  1.18   hannken dev_info_t *zfs_dip = &__zfs_devinfo;
    216   1.2      haad 
    217  1.11       chs #define zfs_init() /* nothing */
    218  1.11       chs #define zfs_fini() /* nothing */
    219   1.1      haad 
    220  1.11       chs #define vfs_busy(x, y)	vfs_busy(x)
    221  1.11       chs #define vfs_rel(x)	vfs_rele(x)
    222  1.11       chs #endif
    223   1.1      haad 
    224  1.11       chs extern uint_t rrw_tsd_key;
    225  1.11       chs static uint_t zfs_allow_log_key;
    226  1.11       chs extern uint_t zfs_geom_probe_vdev_key;
    227   1.1      haad 
    228  1.11       chs typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *);
    229  1.11       chs typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *);
    230  1.11       chs typedef int zfs_secpolicy_func_t(zfs_cmd_t *, nvlist_t *, cred_t *);
    231   1.1      haad 
    232   1.4      haad typedef enum {
    233   1.4      haad 	NO_NAME,
    234   1.4      haad 	POOL_NAME,
    235   1.4      haad 	DATASET_NAME
    236   1.4      haad } zfs_ioc_namecheck_t;
    237   1.4      haad 
    238  1.11       chs typedef enum {
    239  1.11       chs 	POOL_CHECK_NONE		= 1 << 0,
    240  1.11       chs 	POOL_CHECK_SUSPENDED	= 1 << 1,
    241  1.11       chs 	POOL_CHECK_READONLY	= 1 << 2,
    242  1.11       chs } zfs_ioc_poolcheck_t;
    243  1.11       chs 
    244   1.1      haad typedef struct zfs_ioc_vec {
    245  1.11       chs 	zfs_ioc_legacy_func_t	*zvec_legacy_func;
    246   1.1      haad 	zfs_ioc_func_t		*zvec_func;
    247   1.1      haad 	zfs_secpolicy_func_t	*zvec_secpolicy;
    248   1.4      haad 	zfs_ioc_namecheck_t	zvec_namecheck;
    249  1.11       chs 	boolean_t		zvec_allow_log;
    250  1.11       chs 	zfs_ioc_poolcheck_t	zvec_pool_check;
    251  1.11       chs 	boolean_t		zvec_smush_outnvlist;
    252  1.11       chs 	const char		*zvec_name;
    253   1.1      haad } zfs_ioc_vec_t;
    254   1.1      haad 
    255   1.4      haad /* This array is indexed by zfs_userquota_prop_t */
    256   1.4      haad static const char *userquota_perms[] = {
    257   1.4      haad 	ZFS_DELEG_PERM_USERUSED,
    258   1.4      haad 	ZFS_DELEG_PERM_USERQUOTA,
    259   1.4      haad 	ZFS_DELEG_PERM_GROUPUSED,
    260   1.4      haad 	ZFS_DELEG_PERM_GROUPQUOTA,
    261   1.4      haad };
    262   1.4      haad 
    263   1.4      haad static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
    264   1.4      haad static int zfs_check_settable(const char *name, nvpair_t *property,
    265   1.4      haad     cred_t *cr);
    266   1.4      haad static int zfs_check_clearable(char *dataset, nvlist_t *props,
    267   1.4      haad     nvlist_t **errors);
    268   1.1      haad static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
    269   1.1      haad     boolean_t *);
    270  1.11       chs int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t *);
    271  1.11       chs static int get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp);
    272  1.11       chs 
    273  1.11       chs #ifdef __FreeBSD__
    274  1.11       chs static void zfsdev_close(void *data);
    275  1.11       chs #endif
    276  1.11       chs 
    277  1.11       chs static int zfs_prop_activate_feature(spa_t *spa, spa_feature_t feature);
    278   1.1      haad 
    279   1.1      haad /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
    280   1.1      haad void
    281   1.1      haad __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
    282   1.1      haad {
    283   1.1      haad 	const char *newfile;
    284  1.11       chs 	char buf[512];
    285   1.1      haad 	va_list adx;
    286   1.1      haad 
    287   1.1      haad 	/*
    288   1.1      haad 	 * Get rid of annoying "../common/" prefix to filename.
    289   1.1      haad 	 */
    290   1.1      haad 	newfile = strrchr(file, '/');
    291   1.1      haad 	if (newfile != NULL) {
    292   1.1      haad 		newfile = newfile + 1; /* Get rid of leading / */
    293   1.1      haad 	} else {
    294   1.1      haad 		newfile = file;
    295   1.1      haad 	}
    296   1.1      haad 
    297   1.1      haad 	va_start(adx, fmt);
    298   1.1      haad 	(void) vsnprintf(buf, sizeof (buf), fmt, adx);
    299   1.1      haad 	va_end(adx);
    300   1.1      haad 
    301   1.1      haad 	/*
    302   1.1      haad 	 * To get this data, use the zfs-dprintf probe as so:
    303   1.1      haad 	 * dtrace -q -n 'zfs-dprintf \
    304   1.1      haad 	 *	/stringof(arg0) == "dbuf.c"/ \
    305   1.1      haad 	 *	{printf("%s: %s", stringof(arg1), stringof(arg3))}'
    306   1.1      haad 	 * arg0 = file name
    307   1.1      haad 	 * arg1 = function name
    308   1.1      haad 	 * arg2 = line number
    309   1.1      haad 	 * arg3 = message
    310   1.1      haad 	 */
    311   1.1      haad 	DTRACE_PROBE4(zfs__dprintf,
    312   1.1      haad 	    char *, newfile, char *, func, int, line, char *, buf);
    313   1.1      haad }
    314   1.1      haad 
    315   1.1      haad static void
    316   1.1      haad history_str_free(char *buf)
    317   1.1      haad {
    318   1.1      haad 	kmem_free(buf, HIS_MAX_RECORD_LEN);
    319   1.1      haad }
    320   1.1      haad 
    321   1.1      haad static char *
    322   1.1      haad history_str_get(zfs_cmd_t *zc)
    323   1.1      haad {
    324   1.1      haad 	char *buf;
    325   1.1      haad 
    326   1.8  christos 	if (zc->zc_history == 0)
    327   1.1      haad 		return (NULL);
    328   1.1      haad 
    329   1.1      haad 	buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP);
    330   1.1      haad 	if (copyinstr((void *)(uintptr_t)zc->zc_history,
    331   1.1      haad 	    buf, HIS_MAX_RECORD_LEN, NULL) != 0) {
    332   1.1      haad 		history_str_free(buf);
    333   1.1      haad 		return (NULL);
    334   1.1      haad 	}
    335   1.1      haad 
    336   1.1      haad 	buf[HIS_MAX_RECORD_LEN -1] = '\0';
    337   1.1      haad 
    338   1.1      haad 	return (buf);
    339   1.1      haad }
    340   1.1      haad 
    341   1.1      haad /*
    342   1.1      haad  * Check to see if the named dataset is currently defined as bootable
    343   1.1      haad  */
    344   1.1      haad static boolean_t
    345   1.1      haad zfs_is_bootfs(const char *name)
    346   1.1      haad {
    347   1.4      haad 	objset_t *os;
    348   1.1      haad 
    349   1.4      haad 	if (dmu_objset_hold(name, FTAG, &os) == 0) {
    350   1.4      haad 		boolean_t ret;
    351   1.4      haad 		ret = (dmu_objset_id(os) == spa_bootfs(dmu_objset_spa(os)));
    352   1.4      haad 		dmu_objset_rele(os, FTAG);
    353   1.4      haad 		return (ret);
    354   1.1      haad 	}
    355   1.4      haad 	return (B_FALSE);
    356   1.1      haad }
    357   1.1      haad 
    358   1.1      haad /*
    359  1.11       chs  * Return non-zero if the spa version is less than requested version.
    360   1.1      haad  */
    361   1.1      haad static int
    362   1.1      haad zfs_earlier_version(const char *name, int version)
    363   1.1      haad {
    364   1.1      haad 	spa_t *spa;
    365   1.1      haad 
    366   1.1      haad 	if (spa_open(name, &spa, FTAG) == 0) {
    367   1.1      haad 		if (spa_version(spa) < version) {
    368   1.1      haad 			spa_close(spa, FTAG);
    369   1.1      haad 			return (1);
    370   1.1      haad 		}
    371   1.1      haad 		spa_close(spa, FTAG);
    372   1.1      haad 	}
    373   1.1      haad 	return (0);
    374   1.1      haad }
    375   1.1      haad 
    376   1.1      haad /*
    377   1.1      haad  * Return TRUE if the ZPL version is less than requested version.
    378   1.1      haad  */
    379   1.1      haad static boolean_t
    380   1.1      haad zpl_earlier_version(const char *name, int version)
    381   1.1      haad {
    382   1.1      haad 	objset_t *os;
    383   1.1      haad 	boolean_t rc = B_TRUE;
    384   1.1      haad 
    385   1.4      haad 	if (dmu_objset_hold(name, FTAG, &os) == 0) {
    386   1.1      haad 		uint64_t zplversion;
    387   1.1      haad 
    388   1.4      haad 		if (dmu_objset_type(os) != DMU_OST_ZFS) {
    389   1.4      haad 			dmu_objset_rele(os, FTAG);
    390   1.4      haad 			return (B_TRUE);
    391   1.4      haad 		}
    392   1.4      haad 		/* XXX reading from non-owned objset */
    393   1.1      haad 		if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0)
    394   1.1      haad 			rc = zplversion < version;
    395   1.4      haad 		dmu_objset_rele(os, FTAG);
    396   1.1      haad 	}
    397   1.1      haad 	return (rc);
    398   1.1      haad }
    399   1.1      haad 
    400   1.1      haad static void
    401   1.1      haad zfs_log_history(zfs_cmd_t *zc)
    402   1.1      haad {
    403   1.1      haad 	spa_t *spa;
    404   1.1      haad 	char *buf;
    405   1.1      haad 
    406   1.1      haad 	if ((buf = history_str_get(zc)) == NULL)
    407   1.1      haad 		return;
    408   1.1      haad 
    409   1.1      haad 	if (spa_open(zc->zc_name, &spa, FTAG) == 0) {
    410   1.1      haad 		if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
    411  1.11       chs 			(void) spa_history_log(spa, buf);
    412   1.1      haad 		spa_close(spa, FTAG);
    413   1.1      haad 	}
    414   1.1      haad 	history_str_free(buf);
    415   1.1      haad }
    416   1.1      haad 
    417   1.1      haad /*
    418   1.1      haad  * Policy for top-level read operations (list pools).  Requires no privileges,
    419   1.1      haad  * and can be used in the local zone, as there is no associated dataset.
    420   1.1      haad  */
    421   1.1      haad /* ARGSUSED */
    422   1.1      haad static int
    423  1.11       chs zfs_secpolicy_none(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    424   1.1      haad {
    425   1.1      haad 	return (0);
    426   1.1      haad }
    427   1.1      haad 
    428   1.1      haad /*
    429   1.1      haad  * Policy for dataset read operations (list children, get statistics).  Requires
    430   1.1      haad  * no privileges, but must be visible in the local zone.
    431   1.1      haad  */
    432   1.1      haad /* ARGSUSED */
    433   1.1      haad static int
    434  1.11       chs zfs_secpolicy_read(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    435   1.1      haad {
    436  1.11       chs 	if (INGLOBALZONE(curthread) ||
    437   1.1      haad 	    zone_dataset_visible(zc->zc_name, NULL))
    438   1.1      haad 		return (0);
    439   1.1      haad 
    440  1.11       chs 	return (SET_ERROR(ENOENT));
    441   1.1      haad }
    442   1.1      haad 
    443   1.1      haad static int
    444  1.11       chs zfs_dozonecheck_impl(const char *dataset, uint64_t zoned, cred_t *cr)
    445   1.1      haad {
    446   1.1      haad 	int writable = 1;
    447   1.1      haad 
    448   1.1      haad 	/*
    449   1.1      haad 	 * The dataset must be visible by this zone -- check this first
    450   1.1      haad 	 * so they don't see EPERM on something they shouldn't know about.
    451   1.1      haad 	 */
    452  1.11       chs 	if (!INGLOBALZONE(curthread) &&
    453   1.1      haad 	    !zone_dataset_visible(dataset, &writable))
    454  1.11       chs 		return (SET_ERROR(ENOENT));
    455   1.1      haad 
    456  1.11       chs 	if (INGLOBALZONE(curthread)) {
    457   1.1      haad 		/*
    458   1.1      haad 		 * If the fs is zoned, only root can access it from the
    459   1.1      haad 		 * global zone.
    460   1.1      haad 		 */
    461   1.1      haad 		if (secpolicy_zfs(cr) && zoned)
    462  1.11       chs 			return (SET_ERROR(EPERM));
    463   1.1      haad 	} else {
    464   1.1      haad 		/*
    465   1.1      haad 		 * If we are in a local zone, the 'zoned' property must be set.
    466   1.1      haad 		 */
    467   1.1      haad 		if (!zoned)
    468  1.11       chs 			return (SET_ERROR(EPERM));
    469   1.1      haad 
    470   1.1      haad 		/* must be writable by this zone */
    471   1.1      haad 		if (!writable)
    472  1.11       chs 			return (SET_ERROR(EPERM));
    473   1.1      haad 	}
    474   1.1      haad 	return (0);
    475   1.1      haad }
    476   1.1      haad 
    477  1.11       chs static int
    478  1.11       chs zfs_dozonecheck(const char *dataset, cred_t *cr)
    479  1.11       chs {
    480  1.11       chs 	uint64_t zoned;
    481  1.11       chs 
    482  1.11       chs #ifdef __NetBSD__
    483  1.11       chs 	zoned = 0;
    484  1.11       chs #else
    485  1.11       chs 	if (dsl_prop_get_integer(dataset, "jailed", &zoned, NULL))
    486  1.11       chs 		return (SET_ERROR(ENOENT));
    487  1.11       chs #endif
    488  1.11       chs 
    489  1.11       chs 	return (zfs_dozonecheck_impl(dataset, zoned, cr));
    490  1.11       chs }
    491  1.11       chs 
    492  1.11       chs static int
    493  1.11       chs zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr)
    494  1.11       chs {
    495  1.11       chs 	uint64_t zoned;
    496  1.11       chs 
    497  1.11       chs #ifdef __NetBSD__
    498  1.11       chs 	zoned = 0;
    499  1.11       chs #else
    500  1.11       chs 	if (dsl_prop_get_int_ds(ds, "jailed", &zoned))
    501  1.11       chs 		return (SET_ERROR(ENOENT));
    502  1.11       chs #endif
    503  1.11       chs 
    504  1.11       chs 	return (zfs_dozonecheck_impl(dataset, zoned, cr));
    505  1.11       chs }
    506  1.11       chs 
    507  1.11       chs static int
    508  1.11       chs zfs_secpolicy_write_perms_ds(const char *name, dsl_dataset_t *ds,
    509  1.11       chs     const char *perm, cred_t *cr)
    510   1.1      haad {
    511   1.1      haad 	int error;
    512   1.1      haad 
    513  1.11       chs 	error = zfs_dozonecheck_ds(name, ds, cr);
    514   1.1      haad 	if (error == 0) {
    515   1.1      haad 		error = secpolicy_zfs(cr);
    516  1.11       chs 		if (error != 0)
    517  1.11       chs 			error = dsl_deleg_access_impl(ds, perm, cr);
    518  1.11       chs 	}
    519  1.11       chs 	return (error);
    520  1.11       chs }
    521  1.11       chs 
    522  1.11       chs static int
    523  1.11       chs zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr)
    524  1.11       chs {
    525  1.11       chs 	int error;
    526  1.11       chs 	dsl_dataset_t *ds;
    527  1.11       chs 	dsl_pool_t *dp;
    528  1.11       chs 
    529  1.11       chs 	/*
    530  1.11       chs 	 * First do a quick check for root in the global zone, which
    531  1.11       chs 	 * is allowed to do all write_perms.  This ensures that zfs_ioc_*
    532  1.11       chs 	 * will get to handle nonexistent datasets.
    533  1.11       chs 	 */
    534  1.11       chs 	if (INGLOBALZONE(curthread) && secpolicy_zfs(cr) == 0)
    535  1.11       chs 		return (0);
    536  1.11       chs 
    537  1.11       chs 	error = dsl_pool_hold(name, FTAG, &dp);
    538  1.11       chs 	if (error != 0)
    539  1.11       chs 		return (error);
    540  1.11       chs 
    541  1.11       chs 	error = dsl_dataset_hold(dp, name, FTAG, &ds);
    542  1.11       chs 	if (error != 0) {
    543  1.11       chs 		dsl_pool_rele(dp, FTAG);
    544  1.11       chs 		return (error);
    545   1.1      haad 	}
    546  1.11       chs 
    547  1.11       chs 	error = zfs_secpolicy_write_perms_ds(name, ds, perm, cr);
    548  1.11       chs 
    549  1.11       chs 	dsl_dataset_rele(ds, FTAG);
    550  1.11       chs 	dsl_pool_rele(dp, FTAG);
    551   1.1      haad 	return (error);
    552   1.1      haad }
    553   1.1      haad 
    554  1.11       chs #ifdef SECLABEL
    555   1.4      haad /*
    556   1.4      haad  * Policy for setting the security label property.
    557   1.4      haad  *
    558   1.4      haad  * Returns 0 for success, non-zero for access and other errors.
    559   1.4      haad  */
    560   1.4      haad static int
    561   1.4      haad zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr)
    562   1.4      haad {
    563   1.4      haad 	char		ds_hexsl[MAXNAMELEN];
    564   1.4      haad 	bslabel_t	ds_sl, new_sl;
    565   1.4      haad 	boolean_t	new_default = FALSE;
    566   1.4      haad 	uint64_t	zoned;
    567   1.4      haad 	int		needed_priv = -1;
    568   1.4      haad 	int		error;
    569   1.4      haad 
    570   1.4      haad 	/* First get the existing dataset label. */
    571   1.4      haad 	error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
    572   1.4      haad 	    1, sizeof (ds_hexsl), &ds_hexsl, NULL);
    573  1.11       chs 	if (error != 0)
    574  1.11       chs 		return (SET_ERROR(EPERM));
    575   1.4      haad 
    576   1.4      haad 	if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
    577   1.4      haad 		new_default = TRUE;
    578   1.4      haad 
    579   1.4      haad 	/* The label must be translatable */
    580   1.4      haad 	if (!new_default && (hexstr_to_label(strval, &new_sl) != 0))
    581  1.11       chs 		return (SET_ERROR(EINVAL));
    582   1.4      haad 
    583   1.4      haad 	/*
    584   1.4      haad 	 * In a non-global zone, disallow attempts to set a label that
    585   1.4      haad 	 * doesn't match that of the zone; otherwise no other checks
    586   1.4      haad 	 * are needed.
    587   1.4      haad 	 */
    588   1.4      haad 	if (!INGLOBALZONE(curproc)) {
    589   1.4      haad 		if (new_default || !blequal(&new_sl, CR_SL(CRED())))
    590  1.11       chs 			return (SET_ERROR(EPERM));
    591   1.4      haad 		return (0);
    592   1.4      haad 	}
    593   1.4      haad 
    594   1.4      haad 	/*
    595   1.4      haad 	 * For global-zone datasets (i.e., those whose zoned property is
    596   1.4      haad 	 * "off", verify that the specified new label is valid for the
    597   1.4      haad 	 * global zone.
    598   1.4      haad 	 */
    599   1.4      haad 	if (dsl_prop_get_integer(name,
    600   1.4      haad 	    zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
    601  1.11       chs 		return (SET_ERROR(EPERM));
    602   1.4      haad 	if (!zoned) {
    603   1.4      haad 		if (zfs_check_global_label(name, strval) != 0)
    604  1.11       chs 			return (SET_ERROR(EPERM));
    605   1.4      haad 	}
    606   1.4      haad 
    607   1.4      haad 	/*
    608   1.4      haad 	 * If the existing dataset label is nondefault, check if the
    609   1.4      haad 	 * dataset is mounted (label cannot be changed while mounted).
    610   1.4      haad 	 * Get the zfsvfs; if there isn't one, then the dataset isn't
    611   1.4      haad 	 * mounted (or isn't a dataset, doesn't exist, ...).
    612   1.4      haad 	 */
    613   1.4      haad 	if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) {
    614   1.4      haad 		objset_t *os;
    615   1.4      haad 		static char *setsl_tag = "setsl_tag";
    616   1.4      haad 
    617   1.4      haad 		/*
    618   1.4      haad 		 * Try to own the dataset; abort if there is any error,
    619   1.4      haad 		 * (e.g., already mounted, in use, or other error).
    620   1.4      haad 		 */
    621   1.4      haad 		error = dmu_objset_own(name, DMU_OST_ZFS, B_TRUE,
    622   1.4      haad 		    setsl_tag, &os);
    623  1.11       chs 		if (error != 0)
    624  1.11       chs 			return (SET_ERROR(EPERM));
    625   1.4      haad 
    626   1.4      haad 		dmu_objset_disown(os, setsl_tag);
    627   1.4      haad 
    628   1.4      haad 		if (new_default) {
    629   1.4      haad 			needed_priv = PRIV_FILE_DOWNGRADE_SL;
    630   1.4      haad 			goto out_check;
    631   1.4      haad 		}
    632   1.4      haad 
    633   1.4      haad 		if (hexstr_to_label(strval, &new_sl) != 0)
    634  1.11       chs 			return (SET_ERROR(EPERM));
    635   1.4      haad 
    636   1.4      haad 		if (blstrictdom(&ds_sl, &new_sl))
    637   1.4      haad 			needed_priv = PRIV_FILE_DOWNGRADE_SL;
    638   1.4      haad 		else if (blstrictdom(&new_sl, &ds_sl))
    639   1.4      haad 			needed_priv = PRIV_FILE_UPGRADE_SL;
    640   1.4      haad 	} else {
    641   1.4      haad 		/* dataset currently has a default label */
    642   1.4      haad 		if (!new_default)
    643   1.4      haad 			needed_priv = PRIV_FILE_UPGRADE_SL;
    644   1.4      haad 	}
    645   1.4      haad 
    646   1.4      haad out_check:
    647   1.4      haad 	if (needed_priv != -1)
    648   1.4      haad 		return (PRIV_POLICY(cr, needed_priv, B_FALSE, EPERM, NULL));
    649   1.4      haad 	return (0);
    650   1.4      haad }
    651  1.11       chs #endif	/* SECLABEL */
    652   1.4      haad 
    653   1.1      haad static int
    654   1.4      haad zfs_secpolicy_setprop(const char *dsname, zfs_prop_t prop, nvpair_t *propval,
    655   1.4      haad     cred_t *cr)
    656   1.1      haad {
    657   1.4      haad 	char *strval;
    658   1.4      haad 
    659   1.1      haad 	/*
    660   1.1      haad 	 * Check permissions for special properties.
    661   1.1      haad 	 */
    662   1.1      haad 	switch (prop) {
    663   1.1      haad 	case ZFS_PROP_ZONED:
    664   1.1      haad 		/*
    665   1.1      haad 		 * Disallow setting of 'zoned' from within a local zone.
    666   1.1      haad 		 */
    667  1.11       chs 		if (!INGLOBALZONE(curthread))
    668  1.11       chs 			return (SET_ERROR(EPERM));
    669   1.1      haad 		break;
    670   1.1      haad 
    671   1.1      haad 	case ZFS_PROP_QUOTA:
    672  1.11       chs 	case ZFS_PROP_FILESYSTEM_LIMIT:
    673  1.11       chs 	case ZFS_PROP_SNAPSHOT_LIMIT:
    674  1.11       chs 		if (!INGLOBALZONE(curthread)) {
    675   1.1      haad 			uint64_t zoned;
    676  1.11       chs 			char setpoint[ZFS_MAX_DATASET_NAME_LEN];
    677   1.1      haad 			/*
    678   1.1      haad 			 * Unprivileged users are allowed to modify the
    679  1.11       chs 			 * limit on things *under* (ie. contained by)
    680   1.1      haad 			 * the thing they own.
    681   1.1      haad 			 */
    682  1.11       chs 			if (dsl_prop_get_integer(dsname, "jailed", &zoned,
    683   1.1      haad 			    setpoint))
    684  1.11       chs 				return (SET_ERROR(EPERM));
    685   1.4      haad 			if (!zoned || strlen(dsname) <= strlen(setpoint))
    686  1.11       chs 				return (SET_ERROR(EPERM));
    687   1.1      haad 		}
    688   1.1      haad 		break;
    689   1.4      haad 
    690   1.4      haad 	case ZFS_PROP_MLSLABEL:
    691  1.11       chs #ifdef SECLABEL
    692   1.4      haad 		if (!is_system_labeled())
    693  1.11       chs 			return (SET_ERROR(EPERM));
    694   1.4      haad 
    695   1.4      haad 		if (nvpair_value_string(propval, &strval) == 0) {
    696   1.4      haad 			int err;
    697   1.4      haad 
    698   1.4      haad 			err = zfs_set_slabel_policy(dsname, strval, CRED());
    699   1.4      haad 			if (err != 0)
    700   1.4      haad 				return (err);
    701   1.4      haad 		}
    702  1.11       chs #else
    703  1.11       chs 		return (EOPNOTSUPP);
    704  1.11       chs #endif
    705   1.4      haad 		break;
    706   1.1      haad 	}
    707   1.1      haad 
    708   1.4      haad 	return (zfs_secpolicy_write_perms(dsname, zfs_prop_to_name(prop), cr));
    709   1.1      haad }
    710   1.1      haad 
    711  1.11       chs /* ARGSUSED */
    712  1.11       chs static int
    713  1.11       chs zfs_secpolicy_set_fsacl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    714   1.1      haad {
    715   1.1      haad 	int error;
    716   1.1      haad 
    717   1.1      haad 	error = zfs_dozonecheck(zc->zc_name, cr);
    718  1.11       chs 	if (error != 0)
    719   1.1      haad 		return (error);
    720   1.1      haad 
    721   1.1      haad 	/*
    722   1.1      haad 	 * permission to set permissions will be evaluated later in
    723   1.1      haad 	 * dsl_deleg_can_allow()
    724   1.1      haad 	 */
    725   1.1      haad 	return (0);
    726   1.1      haad }
    727   1.1      haad 
    728  1.11       chs /* ARGSUSED */
    729  1.11       chs static int
    730  1.11       chs zfs_secpolicy_rollback(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    731   1.1      haad {
    732   1.4      haad 	return (zfs_secpolicy_write_perms(zc->zc_name,
    733   1.4      haad 	    ZFS_DELEG_PERM_ROLLBACK, cr));
    734   1.1      haad }
    735   1.1      haad 
    736  1.11       chs /* ARGSUSED */
    737  1.11       chs static int
    738  1.11       chs zfs_secpolicy_send(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    739  1.11       chs {
    740  1.11       chs 	dsl_pool_t *dp;
    741  1.11       chs 	dsl_dataset_t *ds;
    742  1.11       chs 	char *cp;
    743  1.11       chs 	int error;
    744  1.11       chs 
    745  1.11       chs 	/*
    746  1.11       chs 	 * Generate the current snapshot name from the given objsetid, then
    747  1.11       chs 	 * use that name for the secpolicy/zone checks.
    748  1.11       chs 	 */
    749  1.11       chs 	cp = strchr(zc->zc_name, '@');
    750  1.11       chs 	if (cp == NULL)
    751  1.11       chs 		return (SET_ERROR(EINVAL));
    752  1.11       chs 	error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
    753  1.11       chs 	if (error != 0)
    754  1.11       chs 		return (error);
    755  1.11       chs 
    756  1.11       chs 	error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
    757  1.11       chs 	if (error != 0) {
    758  1.11       chs 		dsl_pool_rele(dp, FTAG);
    759  1.11       chs 		return (error);
    760  1.11       chs 	}
    761  1.11       chs 
    762  1.11       chs 	dsl_dataset_name(ds, zc->zc_name);
    763  1.11       chs 
    764  1.11       chs 	error = zfs_secpolicy_write_perms_ds(zc->zc_name, ds,
    765  1.11       chs 	    ZFS_DELEG_PERM_SEND, cr);
    766  1.11       chs 	dsl_dataset_rele(ds, FTAG);
    767  1.11       chs 	dsl_pool_rele(dp, FTAG);
    768  1.11       chs 
    769  1.11       chs 	return (error);
    770  1.11       chs }
    771  1.11       chs 
    772  1.11       chs /* ARGSUSED */
    773  1.11       chs static int
    774  1.11       chs zfs_secpolicy_send_new(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    775   1.1      haad {
    776   1.1      haad 	return (zfs_secpolicy_write_perms(zc->zc_name,
    777   1.1      haad 	    ZFS_DELEG_PERM_SEND, cr));
    778   1.1      haad }
    779   1.1      haad 
    780  1.11       chs /* ARGSUSED */
    781   1.4      haad static int
    782  1.11       chs zfs_secpolicy_deleg_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    783   1.4      haad {
    784   1.4      haad 	vnode_t *vp;
    785   1.4      haad 	int error;
    786   1.4      haad 
    787   1.4      haad 	if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
    788  1.11       chs 	    NO_FOLLOW, NULL, &vp)) != 0)
    789   1.4      haad 		return (error);
    790   1.4      haad 
    791   1.4      haad 	/* Now make sure mntpnt and dataset are ZFS */
    792  1.11       chs 
    793  1.11       chs 	if (strcmp(vp->v_vfsp->mnt_stat.f_fstypename, "zfs") != 0 ||
    794   1.4      haad 	    (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
    795   1.4      haad 	    zc->zc_name) != 0)) {
    796   1.4      haad 		VN_RELE(vp);
    797  1.11       chs 		return (SET_ERROR(EPERM));
    798   1.4      haad 	}
    799  1.11       chs 
    800   1.4      haad 	VN_RELE(vp);
    801   1.4      haad 	return (dsl_deleg_access(zc->zc_name,
    802   1.4      haad 	    ZFS_DELEG_PERM_SHARE, cr));
    803   1.4      haad }
    804   1.4      haad 
    805   1.1      haad int
    806  1.11       chs zfs_secpolicy_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    807   1.1      haad {
    808  1.11       chs 	if (!INGLOBALZONE(curthread))
    809  1.11       chs 		return (SET_ERROR(EPERM));
    810   1.1      haad 
    811   1.1      haad 	if (secpolicy_nfs(cr) == 0) {
    812   1.1      haad 		return (0);
    813   1.1      haad 	} else {
    814  1.11       chs 		return (zfs_secpolicy_deleg_share(zc, innvl, cr));
    815   1.4      haad 	}
    816   1.4      haad }
    817   1.1      haad 
    818   1.4      haad int
    819  1.11       chs zfs_secpolicy_smb_acl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    820   1.4      haad {
    821  1.11       chs 	if (!INGLOBALZONE(curthread))
    822  1.11       chs 		return (SET_ERROR(EPERM));
    823   1.1      haad 
    824   1.4      haad 	if (secpolicy_smb(cr) == 0) {
    825   1.4      haad 		return (0);
    826   1.4      haad 	} else {
    827  1.11       chs 		return (zfs_secpolicy_deleg_share(zc, innvl, cr));
    828   1.1      haad 	}
    829   1.1      haad }
    830   1.1      haad 
    831   1.1      haad static int
    832   1.1      haad zfs_get_parent(const char *datasetname, char *parent, int parentsize)
    833   1.1      haad {
    834   1.1      haad 	char *cp;
    835   1.1      haad 
    836   1.1      haad 	/*
    837   1.1      haad 	 * Remove the @bla or /bla from the end of the name to get the parent.
    838   1.1      haad 	 */
    839   1.1      haad 	(void) strncpy(parent, datasetname, parentsize);
    840   1.1      haad 	cp = strrchr(parent, '@');
    841   1.1      haad 	if (cp != NULL) {
    842   1.1      haad 		cp[0] = '\0';
    843   1.1      haad 	} else {
    844   1.1      haad 		cp = strrchr(parent, '/');
    845   1.1      haad 		if (cp == NULL)
    846  1.11       chs 			return (SET_ERROR(ENOENT));
    847   1.1      haad 		cp[0] = '\0';
    848   1.1      haad 	}
    849   1.1      haad 
    850   1.1      haad 	return (0);
    851   1.1      haad }
    852   1.1      haad 
    853   1.1      haad int
    854   1.1      haad zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
    855   1.1      haad {
    856   1.1      haad 	int error;
    857   1.1      haad 
    858   1.1      haad 	if ((error = zfs_secpolicy_write_perms(name,
    859   1.1      haad 	    ZFS_DELEG_PERM_MOUNT, cr)) != 0)
    860   1.1      haad 		return (error);
    861   1.1      haad 
    862   1.1      haad 	return (zfs_secpolicy_write_perms(name, ZFS_DELEG_PERM_DESTROY, cr));
    863   1.1      haad }
    864   1.1      haad 
    865  1.11       chs /* ARGSUSED */
    866   1.1      haad static int
    867  1.11       chs zfs_secpolicy_destroy(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    868   1.1      haad {
    869   1.1      haad 	return (zfs_secpolicy_destroy_perms(zc->zc_name, cr));
    870   1.1      haad }
    871   1.1      haad 
    872   1.1      haad /*
    873   1.4      haad  * Destroying snapshots with delegated permissions requires
    874  1.11       chs  * descendant mount and destroy permissions.
    875   1.4      haad  */
    876  1.11       chs /* ARGSUSED */
    877   1.4      haad static int
    878  1.11       chs zfs_secpolicy_destroy_snaps(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    879   1.4      haad {
    880  1.11       chs 	nvlist_t *snaps;
    881  1.11       chs 	nvpair_t *pair, *nextpair;
    882  1.11       chs 	int error = 0;
    883   1.4      haad 
    884  1.11       chs 	if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
    885  1.11       chs 		return (SET_ERROR(EINVAL));
    886  1.11       chs 	for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
    887  1.11       chs 	    pair = nextpair) {
    888  1.11       chs 		nextpair = nvlist_next_nvpair(snaps, pair);
    889  1.11       chs 		error = zfs_secpolicy_destroy_perms(nvpair_name(pair), cr);
    890  1.11       chs 		if (error == ENOENT) {
    891  1.11       chs 			/*
    892  1.11       chs 			 * Ignore any snapshots that don't exist (we consider
    893  1.11       chs 			 * them "already destroyed").  Remove the name from the
    894  1.11       chs 			 * nvl here in case the snapshot is created between
    895  1.11       chs 			 * now and when we try to destroy it (in which case
    896  1.11       chs 			 * we don't want to destroy it since we haven't
    897  1.11       chs 			 * checked for permission).
    898  1.11       chs 			 */
    899  1.11       chs 			fnvlist_remove_nvpair(snaps, pair);
    900  1.11       chs 			error = 0;
    901  1.11       chs 		}
    902  1.11       chs 		if (error != 0)
    903  1.11       chs 			break;
    904  1.11       chs 	}
    905   1.4      haad 
    906   1.4      haad 	return (error);
    907   1.4      haad }
    908   1.4      haad 
    909   1.1      haad int
    910   1.1      haad zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
    911   1.1      haad {
    912  1.11       chs 	char	parentname[ZFS_MAX_DATASET_NAME_LEN];
    913   1.1      haad 	int	error;
    914   1.1      haad 
    915   1.1      haad 	if ((error = zfs_secpolicy_write_perms(from,
    916   1.1      haad 	    ZFS_DELEG_PERM_RENAME, cr)) != 0)
    917   1.1      haad 		return (error);
    918   1.1      haad 
    919   1.1      haad 	if ((error = zfs_secpolicy_write_perms(from,
    920   1.1      haad 	    ZFS_DELEG_PERM_MOUNT, cr)) != 0)
    921   1.1      haad 		return (error);
    922   1.1      haad 
    923   1.1      haad 	if ((error = zfs_get_parent(to, parentname,
    924   1.1      haad 	    sizeof (parentname))) != 0)
    925   1.1      haad 		return (error);
    926   1.1      haad 
    927   1.1      haad 	if ((error = zfs_secpolicy_write_perms(parentname,
    928   1.1      haad 	    ZFS_DELEG_PERM_CREATE, cr)) != 0)
    929   1.1      haad 		return (error);
    930   1.1      haad 
    931   1.1      haad 	if ((error = zfs_secpolicy_write_perms(parentname,
    932   1.1      haad 	    ZFS_DELEG_PERM_MOUNT, cr)) != 0)
    933   1.1      haad 		return (error);
    934   1.1      haad 
    935   1.1      haad 	return (error);
    936   1.1      haad }
    937   1.1      haad 
    938  1.11       chs /* ARGSUSED */
    939   1.1      haad static int
    940  1.11       chs zfs_secpolicy_rename(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    941   1.1      haad {
    942  1.11       chs 	char *at = NULL;
    943  1.11       chs 	int error;
    944  1.11       chs 
    945  1.11       chs 	if ((zc->zc_cookie & 1) != 0) {
    946  1.11       chs 		/*
    947  1.11       chs 		 * This is recursive rename, so the starting snapshot might
    948  1.11       chs 		 * not exist. Check file system or volume permission instead.
    949  1.11       chs 		 */
    950  1.11       chs 		at = strchr(zc->zc_name, '@');
    951  1.11       chs 		if (at == NULL)
    952  1.11       chs 			return (EINVAL);
    953  1.11       chs 		*at = '\0';
    954  1.11       chs 	}
    955  1.11       chs 
    956  1.11       chs 	error = zfs_secpolicy_rename_perms(zc->zc_name, zc->zc_value, cr);
    957  1.11       chs 
    958  1.11       chs 	if (at != NULL)
    959  1.11       chs 		*at = '@';
    960  1.11       chs 
    961  1.11       chs 	return (error);
    962   1.1      haad }
    963   1.1      haad 
    964  1.11       chs /* ARGSUSED */
    965   1.1      haad static int
    966  1.11       chs zfs_secpolicy_promote(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
    967   1.1      haad {
    968  1.11       chs 	dsl_pool_t *dp;
    969  1.11       chs 	dsl_dataset_t *clone;
    970   1.1      haad 	int error;
    971   1.1      haad 
    972   1.1      haad 	error = zfs_secpolicy_write_perms(zc->zc_name,
    973   1.1      haad 	    ZFS_DELEG_PERM_PROMOTE, cr);
    974  1.11       chs 	if (error != 0)
    975  1.11       chs 		return (error);
    976  1.11       chs 
    977  1.11       chs 	error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
    978  1.11       chs 	if (error != 0)
    979   1.1      haad 		return (error);
    980   1.1      haad 
    981  1.11       chs 	error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &clone);
    982   1.1      haad 
    983   1.1      haad 	if (error == 0) {
    984  1.11       chs 		char parentname[ZFS_MAX_DATASET_NAME_LEN];
    985  1.11       chs 		dsl_dataset_t *origin = NULL;
    986   1.1      haad 		dsl_dir_t *dd;
    987  1.11       chs 		dd = clone->ds_dir;
    988   1.1      haad 
    989   1.1      haad 		error = dsl_dataset_hold_obj(dd->dd_pool,
    990  1.11       chs 		    dsl_dir_phys(dd)->dd_origin_obj, FTAG, &origin);
    991  1.11       chs 		if (error != 0) {
    992  1.11       chs 			dsl_dataset_rele(clone, FTAG);
    993  1.11       chs 			dsl_pool_rele(dp, FTAG);
    994   1.1      haad 			return (error);
    995   1.1      haad 		}
    996   1.1      haad 
    997  1.11       chs 		error = zfs_secpolicy_write_perms_ds(zc->zc_name, clone,
    998   1.1      haad 		    ZFS_DELEG_PERM_MOUNT, cr);
    999   1.1      haad 
   1000  1.11       chs 		dsl_dataset_name(origin, parentname);
   1001  1.11       chs 		if (error == 0) {
   1002  1.11       chs 			error = zfs_secpolicy_write_perms_ds(parentname, origin,
   1003   1.1      haad 			    ZFS_DELEG_PERM_PROMOTE, cr);
   1004  1.11       chs 		}
   1005  1.11       chs 		dsl_dataset_rele(clone, FTAG);
   1006  1.11       chs 		dsl_dataset_rele(origin, FTAG);
   1007   1.1      haad 	}
   1008  1.11       chs 	dsl_pool_rele(dp, FTAG);
   1009   1.1      haad 	return (error);
   1010   1.1      haad }
   1011   1.1      haad 
   1012  1.11       chs /* ARGSUSED */
   1013   1.1      haad static int
   1014  1.11       chs zfs_secpolicy_recv(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1015   1.1      haad {
   1016   1.1      haad 	int error;
   1017   1.1      haad 
   1018   1.1      haad 	if ((error = zfs_secpolicy_write_perms(zc->zc_name,
   1019   1.1      haad 	    ZFS_DELEG_PERM_RECEIVE, cr)) != 0)
   1020   1.1      haad 		return (error);
   1021   1.1      haad 
   1022   1.1      haad 	if ((error = zfs_secpolicy_write_perms(zc->zc_name,
   1023   1.1      haad 	    ZFS_DELEG_PERM_MOUNT, cr)) != 0)
   1024   1.1      haad 		return (error);
   1025   1.1      haad 
   1026   1.1      haad 	return (zfs_secpolicy_write_perms(zc->zc_name,
   1027   1.1      haad 	    ZFS_DELEG_PERM_CREATE, cr));
   1028   1.1      haad }
   1029   1.1      haad 
   1030   1.1      haad int
   1031   1.1      haad zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
   1032   1.1      haad {
   1033   1.4      haad 	return (zfs_secpolicy_write_perms(name,
   1034   1.4      haad 	    ZFS_DELEG_PERM_SNAPSHOT, cr));
   1035   1.1      haad }
   1036   1.1      haad 
   1037  1.11       chs /*
   1038  1.11       chs  * Check for permission to create each snapshot in the nvlist.
   1039  1.11       chs  */
   1040  1.11       chs /* ARGSUSED */
   1041   1.1      haad static int
   1042  1.11       chs zfs_secpolicy_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1043   1.1      haad {
   1044  1.11       chs 	nvlist_t *snaps;
   1045  1.11       chs 	int error;
   1046  1.11       chs 	nvpair_t *pair;
   1047   1.1      haad 
   1048  1.11       chs 	if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
   1049  1.11       chs 		return (SET_ERROR(EINVAL));
   1050  1.11       chs 	for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
   1051  1.11       chs 	    pair = nvlist_next_nvpair(snaps, pair)) {
   1052  1.11       chs 		char *name = nvpair_name(pair);
   1053  1.11       chs 		char *atp = strchr(name, '@');
   1054  1.11       chs 
   1055  1.11       chs 		if (atp == NULL) {
   1056  1.11       chs 			error = SET_ERROR(EINVAL);
   1057  1.11       chs 			break;
   1058  1.11       chs 		}
   1059  1.11       chs 		*atp = '\0';
   1060  1.11       chs 		error = zfs_secpolicy_snapshot_perms(name, cr);
   1061  1.11       chs 		*atp = '@';
   1062  1.11       chs 		if (error != 0)
   1063  1.11       chs 			break;
   1064  1.11       chs 	}
   1065  1.11       chs 	return (error);
   1066   1.1      haad }
   1067   1.1      haad 
   1068  1.11       chs /*
   1069  1.11       chs  * Check for permission to create each snapshot in the nvlist.
   1070  1.11       chs  */
   1071  1.11       chs /* ARGSUSED */
   1072   1.1      haad static int
   1073  1.11       chs zfs_secpolicy_bookmark(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1074   1.1      haad {
   1075  1.11       chs 	int error = 0;
   1076   1.1      haad 
   1077  1.11       chs 	for (nvpair_t *pair = nvlist_next_nvpair(innvl, NULL);
   1078  1.11       chs 	    pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
   1079  1.11       chs 		char *name = nvpair_name(pair);
   1080  1.11       chs 		char *hashp = strchr(name, '#');
   1081   1.1      haad 
   1082  1.11       chs 		if (hashp == NULL) {
   1083  1.11       chs 			error = SET_ERROR(EINVAL);
   1084  1.11       chs 			break;
   1085  1.11       chs 		}
   1086  1.11       chs 		*hashp = '\0';
   1087  1.11       chs 		error = zfs_secpolicy_write_perms(name,
   1088  1.11       chs 		    ZFS_DELEG_PERM_BOOKMARK, cr);
   1089  1.11       chs 		*hashp = '#';
   1090  1.11       chs 		if (error != 0)
   1091  1.11       chs 			break;
   1092   1.1      haad 	}
   1093  1.11       chs 	return (error);
   1094  1.11       chs }
   1095  1.11       chs 
   1096  1.11       chs /* ARGSUSED */
   1097  1.11       chs static int
   1098  1.11       chs zfs_secpolicy_destroy_bookmarks(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1099  1.11       chs {
   1100  1.11       chs 	nvpair_t *pair, *nextpair;
   1101  1.11       chs 	int error = 0;
   1102  1.11       chs 
   1103  1.11       chs 	for (pair = nvlist_next_nvpair(innvl, NULL); pair != NULL;
   1104  1.11       chs 	    pair = nextpair) {
   1105  1.11       chs 		char *name = nvpair_name(pair);
   1106  1.11       chs 		char *hashp = strchr(name, '#');
   1107  1.11       chs 		nextpair = nvlist_next_nvpair(innvl, pair);
   1108   1.1      haad 
   1109  1.11       chs 		if (hashp == NULL) {
   1110  1.11       chs 			error = SET_ERROR(EINVAL);
   1111  1.11       chs 			break;
   1112  1.11       chs 		}
   1113   1.1      haad 
   1114  1.11       chs 		*hashp = '\0';
   1115  1.11       chs 		error = zfs_secpolicy_write_perms(name,
   1116  1.11       chs 		    ZFS_DELEG_PERM_DESTROY, cr);
   1117  1.11       chs 		*hashp = '#';
   1118  1.11       chs 		if (error == ENOENT) {
   1119  1.11       chs 			/*
   1120  1.11       chs 			 * Ignore any filesystems that don't exist (we consider
   1121  1.11       chs 			 * their bookmarks "already destroyed").  Remove
   1122  1.11       chs 			 * the name from the nvl here in case the filesystem
   1123  1.11       chs 			 * is created between now and when we try to destroy
   1124  1.11       chs 			 * the bookmark (in which case we don't want to
   1125  1.11       chs 			 * destroy it since we haven't checked for permission).
   1126  1.11       chs 			 */
   1127  1.11       chs 			fnvlist_remove_nvpair(innvl, pair);
   1128  1.11       chs 			error = 0;
   1129  1.11       chs 		}
   1130  1.11       chs 		if (error != 0)
   1131  1.11       chs 			break;
   1132  1.11       chs 	}
   1133   1.1      haad 
   1134   1.1      haad 	return (error);
   1135   1.1      haad }
   1136   1.1      haad 
   1137  1.11       chs /* ARGSUSED */
   1138  1.11       chs static int
   1139  1.11       chs zfs_secpolicy_log_history(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1140  1.11       chs {
   1141  1.11       chs 	/*
   1142  1.11       chs 	 * Even root must have a proper TSD so that we know what pool
   1143  1.11       chs 	 * to log to.
   1144  1.11       chs 	 */
   1145  1.11       chs 	if (tsd_get(zfs_allow_log_key) == NULL)
   1146  1.11       chs 		return (SET_ERROR(EPERM));
   1147  1.11       chs 	return (0);
   1148  1.11       chs }
   1149  1.11       chs 
   1150   1.1      haad static int
   1151  1.11       chs zfs_secpolicy_create_clone(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1152   1.1      haad {
   1153  1.11       chs 	char	parentname[ZFS_MAX_DATASET_NAME_LEN];
   1154  1.11       chs 	int	error;
   1155  1.11       chs 	char	*origin;
   1156  1.11       chs 
   1157  1.11       chs 	if ((error = zfs_get_parent(zc->zc_name, parentname,
   1158  1.11       chs 	    sizeof (parentname))) != 0)
   1159  1.11       chs 		return (error);
   1160  1.11       chs 
   1161  1.11       chs 	if (nvlist_lookup_string(innvl, "origin", &origin) == 0 &&
   1162  1.11       chs 	    (error = zfs_secpolicy_write_perms(origin,
   1163  1.11       chs 	    ZFS_DELEG_PERM_CLONE, cr)) != 0)
   1164  1.11       chs 		return (error);
   1165  1.11       chs 
   1166  1.11       chs 	if ((error = zfs_secpolicy_write_perms(parentname,
   1167  1.11       chs 	    ZFS_DELEG_PERM_CREATE, cr)) != 0)
   1168  1.11       chs 		return (error);
   1169   1.1      haad 
   1170  1.11       chs 	return (zfs_secpolicy_write_perms(parentname,
   1171  1.11       chs 	    ZFS_DELEG_PERM_MOUNT, cr));
   1172   1.1      haad }
   1173   1.1      haad 
   1174   1.1      haad /*
   1175   1.1      haad  * Policy for pool operations - create/destroy pools, add vdevs, etc.  Requires
   1176   1.1      haad  * SYS_CONFIG privilege, which is not available in a local zone.
   1177   1.1      haad  */
   1178   1.1      haad /* ARGSUSED */
   1179   1.1      haad static int
   1180  1.11       chs zfs_secpolicy_config(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1181   1.1      haad {
   1182   1.1      haad 	if (secpolicy_sys_config(cr, B_FALSE) != 0)
   1183  1.11       chs 		return (SET_ERROR(EPERM));
   1184   1.1      haad 
   1185   1.1      haad 	return (0);
   1186   1.1      haad }
   1187   1.1      haad 
   1188   1.1      haad /*
   1189  1.11       chs  * Policy for object to name lookups.
   1190   1.1      haad  */
   1191   1.1      haad /* ARGSUSED */
   1192   1.1      haad static int
   1193  1.11       chs zfs_secpolicy_diff(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1194  1.11       chs {
   1195  1.11       chs 	int error;
   1196  1.11       chs 
   1197  1.11       chs 	if ((error = secpolicy_sys_config(cr, B_FALSE)) == 0)
   1198  1.11       chs 		return (0);
   1199  1.11       chs 
   1200  1.11       chs 	error = zfs_secpolicy_write_perms(zc->zc_name, ZFS_DELEG_PERM_DIFF, cr);
   1201  1.11       chs 	return (error);
   1202  1.11       chs }
   1203  1.11       chs 
   1204  1.11       chs /*
   1205  1.11       chs  * Policy for fault injection.  Requires all privileges.
   1206  1.11       chs  */
   1207  1.11       chs /* ARGSUSED */
   1208  1.11       chs static int
   1209  1.11       chs zfs_secpolicy_inject(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1210   1.1      haad {
   1211   1.1      haad 	return (secpolicy_zinject(cr));
   1212   1.1      haad }
   1213   1.1      haad 
   1214  1.11       chs /* ARGSUSED */
   1215   1.1      haad static int
   1216  1.11       chs zfs_secpolicy_inherit_prop(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1217   1.1      haad {
   1218   1.1      haad 	zfs_prop_t prop = zfs_name_to_prop(zc->zc_value);
   1219   1.1      haad 
   1220   1.1      haad 	if (prop == ZPROP_INVAL) {
   1221   1.1      haad 		if (!zfs_prop_user(zc->zc_value))
   1222  1.11       chs 			return (SET_ERROR(EINVAL));
   1223   1.1      haad 		return (zfs_secpolicy_write_perms(zc->zc_name,
   1224   1.1      haad 		    ZFS_DELEG_PERM_USERPROP, cr));
   1225   1.1      haad 	} else {
   1226   1.4      haad 		return (zfs_secpolicy_setprop(zc->zc_name, prop,
   1227   1.4      haad 		    NULL, cr));
   1228   1.4      haad 	}
   1229   1.4      haad }
   1230   1.4      haad 
   1231   1.4      haad static int
   1232  1.11       chs zfs_secpolicy_userspace_one(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1233   1.4      haad {
   1234  1.11       chs 	int err = zfs_secpolicy_read(zc, innvl, cr);
   1235   1.4      haad 	if (err)
   1236   1.4      haad 		return (err);
   1237   1.4      haad 
   1238   1.4      haad 	if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
   1239  1.11       chs 		return (SET_ERROR(EINVAL));
   1240   1.4      haad 
   1241   1.4      haad 	if (zc->zc_value[0] == 0) {
   1242   1.4      haad 		/*
   1243   1.4      haad 		 * They are asking about a posix uid/gid.  If it's
   1244   1.4      haad 		 * themself, allow it.
   1245   1.4      haad 		 */
   1246   1.4      haad 		if (zc->zc_objset_type == ZFS_PROP_USERUSED ||
   1247   1.4      haad 		    zc->zc_objset_type == ZFS_PROP_USERQUOTA) {
   1248   1.4      haad 			if (zc->zc_guid == crgetuid(cr))
   1249   1.4      haad 				return (0);
   1250   1.4      haad 		} else {
   1251   1.4      haad 			if (groupmember(zc->zc_guid, cr))
   1252   1.4      haad 				return (0);
   1253   1.4      haad 		}
   1254   1.1      haad 	}
   1255   1.4      haad 
   1256   1.4      haad 	return (zfs_secpolicy_write_perms(zc->zc_name,
   1257   1.4      haad 	    userquota_perms[zc->zc_objset_type], cr));
   1258   1.4      haad }
   1259   1.4      haad 
   1260   1.4      haad static int
   1261  1.11       chs zfs_secpolicy_userspace_many(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1262   1.4      haad {
   1263  1.11       chs 	int err = zfs_secpolicy_read(zc, innvl, cr);
   1264   1.4      haad 	if (err)
   1265   1.4      haad 		return (err);
   1266   1.4      haad 
   1267   1.4      haad 	if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
   1268  1.11       chs 		return (SET_ERROR(EINVAL));
   1269   1.4      haad 
   1270   1.4      haad 	return (zfs_secpolicy_write_perms(zc->zc_name,
   1271   1.4      haad 	    userquota_perms[zc->zc_objset_type], cr));
   1272   1.4      haad }
   1273   1.4      haad 
   1274  1.11       chs /* ARGSUSED */
   1275   1.4      haad static int
   1276  1.11       chs zfs_secpolicy_userspace_upgrade(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1277   1.4      haad {
   1278   1.4      haad 	return (zfs_secpolicy_setprop(zc->zc_name, ZFS_PROP_VERSION,
   1279   1.4      haad 	    NULL, cr));
   1280   1.4      haad }
   1281   1.4      haad 
   1282  1.11       chs /* ARGSUSED */
   1283  1.11       chs static int
   1284  1.11       chs zfs_secpolicy_hold(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1285  1.11       chs {
   1286  1.11       chs 	nvpair_t *pair;
   1287  1.11       chs 	nvlist_t *holds;
   1288  1.11       chs 	int error;
   1289  1.11       chs 
   1290  1.11       chs 	error = nvlist_lookup_nvlist(innvl, "holds", &holds);
   1291  1.11       chs 	if (error != 0)
   1292  1.11       chs 		return (SET_ERROR(EINVAL));
   1293  1.11       chs 
   1294  1.11       chs 	for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
   1295  1.11       chs 	    pair = nvlist_next_nvpair(holds, pair)) {
   1296  1.11       chs 		char fsname[ZFS_MAX_DATASET_NAME_LEN];
   1297  1.11       chs 		error = dmu_fsname(nvpair_name(pair), fsname);
   1298  1.11       chs 		if (error != 0)
   1299  1.11       chs 			return (error);
   1300  1.11       chs 		error = zfs_secpolicy_write_perms(fsname,
   1301  1.11       chs 		    ZFS_DELEG_PERM_HOLD, cr);
   1302  1.11       chs 		if (error != 0)
   1303  1.11       chs 			return (error);
   1304  1.11       chs 	}
   1305  1.11       chs 	return (0);
   1306  1.11       chs }
   1307  1.11       chs 
   1308  1.11       chs /* ARGSUSED */
   1309   1.4      haad static int
   1310  1.11       chs zfs_secpolicy_release(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1311   1.4      haad {
   1312  1.11       chs 	nvpair_t *pair;
   1313  1.11       chs 	int error;
   1314  1.11       chs 
   1315  1.11       chs 	for (pair = nvlist_next_nvpair(innvl, NULL); pair != NULL;
   1316  1.11       chs 	    pair = nvlist_next_nvpair(innvl, pair)) {
   1317  1.11       chs 		char fsname[ZFS_MAX_DATASET_NAME_LEN];
   1318  1.11       chs 		error = dmu_fsname(nvpair_name(pair), fsname);
   1319  1.11       chs 		if (error != 0)
   1320  1.11       chs 			return (error);
   1321  1.11       chs 		error = zfs_secpolicy_write_perms(fsname,
   1322  1.11       chs 		    ZFS_DELEG_PERM_RELEASE, cr);
   1323  1.11       chs 		if (error != 0)
   1324  1.11       chs 			return (error);
   1325  1.11       chs 	}
   1326  1.11       chs 	return (0);
   1327   1.4      haad }
   1328   1.4      haad 
   1329  1.11       chs /*
   1330  1.11       chs  * Policy for allowing temporary snapshots to be taken or released
   1331  1.11       chs  */
   1332   1.4      haad static int
   1333  1.11       chs zfs_secpolicy_tmp_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
   1334   1.4      haad {
   1335  1.11       chs 	/*
   1336  1.11       chs 	 * A temporary snapshot is the same as a snapshot,
   1337  1.11       chs 	 * hold, destroy and release all rolled into one.
   1338  1.11       chs 	 * Delegated diff alone is sufficient that we allow this.
   1339  1.11       chs 	 */
   1340  1.11       chs 	int error;
   1341  1.11       chs 
   1342  1.11       chs 	if ((error = zfs_secpolicy_write_perms(zc->zc_name,
   1343  1.11       chs 	    ZFS_DELEG_PERM_DIFF, cr)) == 0)
   1344  1.11       chs 		return (0);
   1345  1.11       chs 
   1346  1.11       chs 	error = zfs_secpolicy_snapshot_perms(zc->zc_name, cr);
   1347  1.11       chs 	if (error == 0)
   1348  1.11       chs 		error = zfs_secpolicy_hold(zc, innvl, cr);
   1349  1.11       chs 	if (error == 0)
   1350  1.11       chs 		error = zfs_secpolicy_release(zc, innvl, cr);
   1351  1.11       chs 	if (error == 0)
   1352  1.11       chs 		error = zfs_secpolicy_destroy(zc, innvl, cr);
   1353  1.11       chs 	return (error);
   1354   1.1      haad }
   1355   1.1      haad 
   1356   1.1      haad /*
   1357   1.1      haad  * Returns the nvlist as specified by the user in the zfs_cmd_t.
   1358   1.1      haad  */
   1359   1.1      haad static int
   1360   1.4      haad get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp)
   1361   1.1      haad {
   1362   1.1      haad 	char *packed;
   1363   1.1      haad 	int error;
   1364   1.1      haad 	nvlist_t *list = NULL;
   1365   1.1      haad 
   1366   1.1      haad 	/*
   1367   1.1      haad 	 * Read in and unpack the user-supplied nvlist.
   1368   1.1      haad 	 */
   1369   1.1      haad 	if (size == 0)
   1370  1.11       chs 		return (SET_ERROR(EINVAL));
   1371   1.1      haad 
   1372   1.1      haad 	packed = kmem_alloc(size, KM_SLEEP);
   1373   1.1      haad 
   1374   1.4      haad 	if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
   1375   1.4      haad 	    iflag)) != 0) {
   1376   1.1      haad 		kmem_free(packed, size);
   1377  1.11       chs 		return (SET_ERROR(EFAULT));
   1378   1.1      haad 	}
   1379   1.1      haad 
   1380   1.1      haad 	if ((error = nvlist_unpack(packed, size, &list, 0)) != 0) {
   1381   1.1      haad 		kmem_free(packed, size);
   1382   1.1      haad 		return (error);
   1383   1.1      haad 	}
   1384   1.1      haad 
   1385   1.1      haad 	kmem_free(packed, size);
   1386   1.1      haad 
   1387   1.1      haad 	*nvp = list;
   1388   1.1      haad 	return (0);
   1389   1.1      haad }
   1390   1.1      haad 
   1391  1.11       chs /*
   1392  1.11       chs  * Reduce the size of this nvlist until it can be serialized in 'max' bytes.
   1393  1.11       chs  * Entries will be removed from the end of the nvlist, and one int32 entry
   1394  1.11       chs  * named "N_MORE_ERRORS" will be added indicating how many entries were
   1395  1.11       chs  * removed.
   1396  1.11       chs  */
   1397   1.1      haad static int
   1398  1.11       chs nvlist_smush(nvlist_t *errors, size_t max)
   1399   1.4      haad {
   1400   1.4      haad 	size_t size;
   1401   1.4      haad 
   1402  1.11       chs 	size = fnvlist_size(errors);
   1403   1.4      haad 
   1404  1.11       chs 	if (size > max) {
   1405   1.4      haad 		nvpair_t *more_errors;
   1406   1.4      haad 		int n = 0;
   1407   1.4      haad 
   1408  1.11       chs 		if (max < 1024)
   1409  1.11       chs 			return (SET_ERROR(ENOMEM));
   1410   1.4      haad 
   1411  1.11       chs 		fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, 0);
   1412  1.11       chs 		more_errors = nvlist_prev_nvpair(errors, NULL);
   1413   1.4      haad 
   1414   1.4      haad 		do {
   1415  1.11       chs 			nvpair_t *pair = nvlist_prev_nvpair(errors,
   1416   1.4      haad 			    more_errors);
   1417  1.11       chs 			fnvlist_remove_nvpair(errors, pair);
   1418   1.4      haad 			n++;
   1419  1.11       chs 			size = fnvlist_size(errors);
   1420  1.11       chs 		} while (size > max);
   1421  1.11       chs 
   1422  1.11       chs 		fnvlist_remove_nvpair(errors, more_errors);
   1423  1.11       chs 		fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, n);
   1424  1.11       chs 		ASSERT3U(fnvlist_size(errors), <=, max);
   1425   1.4      haad 	}
   1426   1.4      haad 
   1427   1.4      haad 	return (0);
   1428   1.4      haad }
   1429   1.4      haad 
   1430   1.4      haad static int
   1431   1.1      haad put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
   1432   1.1      haad {
   1433   1.1      haad 	char *packed = NULL;
   1434  1.11       chs 	int error = 0;
   1435   1.1      haad 	size_t size;
   1436   1.1      haad 
   1437  1.11       chs 	size = fnvlist_size(nvl);
   1438   1.1      haad 
   1439   1.1      haad 	if (size > zc->zc_nvlist_dst_size) {
   1440  1.11       chs 		/*
   1441  1.11       chs 		 * Solaris returns ENOMEM here, because even if an error is
   1442  1.11       chs 		 * returned from an ioctl(2), new zc_nvlist_dst_size will be
   1443  1.11       chs 		 * passed to the userland. This is not the case for FreeBSD.
   1444  1.11       chs 		 * We need to return 0, so the kernel will copy the
   1445  1.11       chs 		 * zc_nvlist_dst_size back and the userland can discover that a
   1446  1.11       chs 		 * bigger buffer is needed.
   1447  1.11       chs 		 */
   1448  1.11       chs 		error = 0;
   1449   1.1      haad 	} else {
   1450  1.11       chs 		packed = fnvlist_pack(nvl, &size);
   1451  1.11       chs 		if (ddi_copyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst,
   1452  1.11       chs 		    size, zc->zc_iflags) != 0)
   1453  1.11       chs 			error = SET_ERROR(EFAULT);
   1454  1.11       chs 		fnvlist_pack_free(packed, size);
   1455   1.1      haad 	}
   1456   1.1      haad 
   1457   1.1      haad 	zc->zc_nvlist_dst_size = size;
   1458  1.11       chs 	zc->zc_nvlist_dst_filled = B_TRUE;
   1459   1.1      haad 	return (error);
   1460   1.1      haad }
   1461   1.1      haad 
   1462   1.1      haad static int
   1463   1.4      haad getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
   1464   1.4      haad {
   1465   1.4      haad 	objset_t *os;
   1466  1.11       chs 	vfs_t *vfsp;
   1467   1.4      haad 	int error;
   1468   1.4      haad 
   1469   1.4      haad 	error = dmu_objset_hold(dsname, FTAG, &os);
   1470  1.11       chs 	if (error != 0)
   1471   1.4      haad 		return (error);
   1472   1.4      haad 	if (dmu_objset_type(os) != DMU_OST_ZFS) {
   1473   1.4      haad 		dmu_objset_rele(os, FTAG);
   1474  1.11       chs 		return (SET_ERROR(EINVAL));
   1475   1.4      haad 	}
   1476   1.4      haad 
   1477   1.4      haad 	mutex_enter(&os->os_user_ptr_lock);
   1478   1.4      haad 	*zfvp = dmu_objset_get_user(os);
   1479   1.4      haad 	if (*zfvp) {
   1480  1.11       chs 		vfsp = (*zfvp)->z_vfs;
   1481  1.11       chs 		vfs_ref(vfsp);
   1482   1.4      haad 	} else {
   1483  1.11       chs 		error = SET_ERROR(ESRCH);
   1484   1.4      haad 	}
   1485   1.4      haad 	mutex_exit(&os->os_user_ptr_lock);
   1486   1.4      haad 	dmu_objset_rele(os, FTAG);
   1487  1.11       chs 	if (error == 0) {
   1488  1.11       chs 		error = vfs_busy(vfsp, 0);
   1489  1.11       chs 		vfs_rel(vfsp);
   1490  1.11       chs 		if (error != 0) {
   1491  1.11       chs 			*zfvp = NULL;
   1492  1.11       chs 			error = SET_ERROR(ESRCH);
   1493  1.11       chs 		}
   1494  1.11       chs 	}
   1495   1.4      haad 	return (error);
   1496   1.4      haad }
   1497   1.4      haad 
   1498   1.4      haad /*
   1499   1.4      haad  * Find a zfsvfs_t for a mounted filesystem, or create our own, in which
   1500   1.4      haad  * case its z_vfs will be NULL, and it will be opened as the owner.
   1501  1.11       chs  * If 'writer' is set, the z_teardown_lock will be held for RW_WRITER,
   1502  1.11       chs  * which prevents all vnode ops from running.
   1503   1.4      haad  */
   1504   1.4      haad static int
   1505  1.11       chs zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer)
   1506   1.4      haad {
   1507   1.4      haad 	int error = 0;
   1508   1.4      haad 
   1509   1.4      haad 	if (getzfsvfs(name, zfvp) != 0)
   1510   1.4      haad 		error = zfsvfs_create(name, zfvp);
   1511   1.4      haad 	if (error == 0) {
   1512  1.11       chs 		rrm_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER :
   1513  1.11       chs 		    RW_READER, tag);
   1514   1.4      haad 		if ((*zfvp)->z_unmounted) {
   1515   1.4      haad 			/*
   1516   1.4      haad 			 * XXX we could probably try again, since the unmounting
   1517   1.4      haad 			 * thread should be just about to disassociate the
   1518   1.4      haad 			 * objset from the zfsvfs.
   1519   1.4      haad 			 */
   1520  1.11       chs 			rrm_exit(&(*zfvp)->z_teardown_lock, tag);
   1521  1.11       chs 			return (SET_ERROR(EBUSY));
   1522   1.4      haad 		}
   1523   1.4      haad 	}
   1524   1.4      haad 	return (error);
   1525   1.4      haad }
   1526   1.4      haad 
   1527   1.4      haad static void
   1528   1.4      haad zfsvfs_rele(zfsvfs_t *zfsvfs, void *tag)
   1529   1.4      haad {
   1530  1.11       chs 	rrm_exit(&zfsvfs->z_teardown_lock, tag);
   1531   1.4      haad 
   1532   1.4      haad 	if (zfsvfs->z_vfs) {
   1533  1.11       chs #ifdef illumos
   1534   1.4      haad 		VFS_RELE(zfsvfs->z_vfs);
   1535  1.11       chs #else
   1536  1.11       chs 		vfs_unbusy(zfsvfs->z_vfs);
   1537  1.11       chs #endif
   1538   1.4      haad 	} else {
   1539   1.4      haad 		dmu_objset_disown(zfsvfs->z_os, zfsvfs);
   1540   1.4      haad 		zfsvfs_free(zfsvfs);
   1541   1.4      haad 	}
   1542   1.4      haad }
   1543   1.4      haad 
   1544   1.4      haad static int
   1545   1.1      haad zfs_ioc_pool_create(zfs_cmd_t *zc)
   1546   1.1      haad {
   1547   1.1      haad 	int error;
   1548   1.1      haad 	nvlist_t *config, *props = NULL;
   1549   1.1      haad 	nvlist_t *rootprops = NULL;
   1550   1.1      haad 	nvlist_t *zplprops = NULL;
   1551   1.1      haad 
   1552   1.1      haad 	if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
   1553   1.4      haad 	    zc->zc_iflags, &config))
   1554   1.1      haad 		return (error);
   1555   1.1      haad 
   1556   1.1      haad 	if (zc->zc_nvlist_src_size != 0 && (error =
   1557   1.4      haad 	    get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
   1558   1.4      haad 	    zc->zc_iflags, &props))) {
   1559   1.1      haad 		nvlist_free(config);
   1560   1.1      haad 		return (error);
   1561   1.1      haad 	}
   1562   1.1      haad 
   1563   1.1      haad 	if (props) {
   1564   1.1      haad 		nvlist_t *nvl = NULL;
   1565   1.1      haad 		uint64_t version = SPA_VERSION;
   1566   1.1      haad 
   1567   1.1      haad 		(void) nvlist_lookup_uint64(props,
   1568   1.1      haad 		    zpool_prop_to_name(ZPOOL_PROP_VERSION), &version);
   1569  1.11       chs 		if (!SPA_VERSION_IS_SUPPORTED(version)) {
   1570  1.11       chs 			error = SET_ERROR(EINVAL);
   1571   1.1      haad 			goto pool_props_bad;
   1572   1.1      haad 		}
   1573   1.1      haad 		(void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl);
   1574   1.1      haad 		if (nvl) {
   1575   1.1      haad 			error = nvlist_dup(nvl, &rootprops, KM_SLEEP);
   1576   1.1      haad 			if (error != 0) {
   1577   1.1      haad 				nvlist_free(config);
   1578   1.1      haad 				nvlist_free(props);
   1579   1.1      haad 				return (error);
   1580   1.1      haad 			}
   1581   1.1      haad 			(void) nvlist_remove_all(props, ZPOOL_ROOTFS_PROPS);
   1582   1.1      haad 		}
   1583   1.1      haad 		VERIFY(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   1584   1.1      haad 		error = zfs_fill_zplprops_root(version, rootprops,
   1585   1.1      haad 		    zplprops, NULL);
   1586  1.11       chs 		if (error != 0)
   1587   1.1      haad 			goto pool_props_bad;
   1588   1.1      haad 	}
   1589   1.1      haad 
   1590  1.11       chs 	error = spa_create(zc->zc_name, config, props, zplprops);
   1591   1.1      haad 
   1592   1.1      haad 	/*
   1593   1.1      haad 	 * Set the remaining root properties
   1594   1.1      haad 	 */
   1595   1.4      haad 	if (!error && (error = zfs_set_prop_nvlist(zc->zc_name,
   1596   1.4      haad 	    ZPROP_SRC_LOCAL, rootprops, NULL)) != 0)
   1597   1.1      haad 		(void) spa_destroy(zc->zc_name);
   1598   1.1      haad 
   1599   1.1      haad pool_props_bad:
   1600   1.1      haad 	nvlist_free(rootprops);
   1601   1.1      haad 	nvlist_free(zplprops);
   1602   1.1      haad 	nvlist_free(config);
   1603   1.1      haad 	nvlist_free(props);
   1604   1.1      haad 
   1605   1.1      haad 	return (error);
   1606   1.1      haad }
   1607   1.1      haad 
   1608   1.1      haad static int
   1609   1.1      haad zfs_ioc_pool_destroy(zfs_cmd_t *zc)
   1610   1.1      haad {
   1611   1.1      haad 	int error;
   1612   1.1      haad 	zfs_log_history(zc);
   1613   1.1      haad 	error = spa_destroy(zc->zc_name);
   1614   1.4      haad 	if (error == 0)
   1615   1.4      haad 		zvol_remove_minors(zc->zc_name);
   1616   1.1      haad 	return (error);
   1617   1.1      haad }
   1618   1.1      haad 
   1619   1.1      haad static int
   1620   1.1      haad zfs_ioc_pool_import(zfs_cmd_t *zc)
   1621   1.1      haad {
   1622   1.1      haad 	nvlist_t *config, *props = NULL;
   1623   1.1      haad 	uint64_t guid;
   1624   1.4      haad 	int error;
   1625   1.1      haad 
   1626   1.1      haad 	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
   1627   1.4      haad 	    zc->zc_iflags, &config)) != 0)
   1628   1.1      haad 		return (error);
   1629   1.1      haad 
   1630   1.1      haad 	if (zc->zc_nvlist_src_size != 0 && (error =
   1631   1.4      haad 	    get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
   1632   1.4      haad 	    zc->zc_iflags, &props))) {
   1633   1.1      haad 		nvlist_free(config);
   1634   1.1      haad 		return (error);
   1635   1.1      haad 	}
   1636   1.1      haad 
   1637   1.1      haad 	if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
   1638   1.1      haad 	    guid != zc->zc_guid)
   1639  1.11       chs 		error = SET_ERROR(EINVAL);
   1640   1.1      haad 	else
   1641  1.11       chs 		error = spa_import(zc->zc_name, config, props, zc->zc_cookie);
   1642  1.11       chs 
   1643  1.11       chs 	if (zc->zc_nvlist_dst != 0) {
   1644  1.11       chs 		int err;
   1645   1.1      haad 
   1646  1.11       chs 		if ((err = put_nvlist(zc, config)) != 0)
   1647  1.11       chs 			error = err;
   1648  1.11       chs 	}
   1649   1.4      haad 
   1650   1.1      haad 	nvlist_free(config);
   1651   1.1      haad 
   1652  1.11       chs 	nvlist_free(props);
   1653   1.1      haad 
   1654   1.1      haad 	return (error);
   1655   1.1      haad }
   1656   1.1      haad 
   1657   1.1      haad static int
   1658   1.1      haad zfs_ioc_pool_export(zfs_cmd_t *zc)
   1659   1.1      haad {
   1660   1.1      haad 	int error;
   1661   1.1      haad 	boolean_t force = (boolean_t)zc->zc_cookie;
   1662   1.4      haad 	boolean_t hardforce = (boolean_t)zc->zc_guid;
   1663   1.1      haad 
   1664   1.1      haad 	zfs_log_history(zc);
   1665   1.4      haad 	error = spa_export(zc->zc_name, NULL, force, hardforce);
   1666   1.4      haad 	if (error == 0)
   1667   1.4      haad 		zvol_remove_minors(zc->zc_name);
   1668   1.1      haad 	return (error);
   1669   1.1      haad }
   1670   1.1      haad 
   1671   1.1      haad static int
   1672   1.1      haad zfs_ioc_pool_configs(zfs_cmd_t *zc)
   1673   1.1      haad {
   1674   1.1      haad 	nvlist_t *configs;
   1675   1.1      haad 	int error;
   1676   1.1      haad 
   1677   1.1      haad 	if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
   1678  1.11       chs 		return (SET_ERROR(EEXIST));
   1679   1.1      haad 
   1680   1.1      haad 	error = put_nvlist(zc, configs);
   1681   1.1      haad 
   1682   1.1      haad 	nvlist_free(configs);
   1683   1.1      haad 
   1684   1.1      haad 	return (error);
   1685   1.1      haad }
   1686   1.1      haad 
   1687  1.11       chs /*
   1688  1.11       chs  * inputs:
   1689  1.11       chs  * zc_name		name of the pool
   1690  1.11       chs  *
   1691  1.11       chs  * outputs:
   1692  1.11       chs  * zc_cookie		real errno
   1693  1.11       chs  * zc_nvlist_dst	config nvlist
   1694  1.11       chs  * zc_nvlist_dst_size	size of config nvlist
   1695  1.11       chs  */
   1696   1.1      haad static int
   1697   1.1      haad zfs_ioc_pool_stats(zfs_cmd_t *zc)
   1698   1.1      haad {
   1699   1.1      haad 	nvlist_t *config;
   1700   1.1      haad 	int error;
   1701   1.1      haad 	int ret = 0;
   1702   1.1      haad 
   1703   1.1      haad 	error = spa_get_stats(zc->zc_name, &config, zc->zc_value,
   1704   1.1      haad 	    sizeof (zc->zc_value));
   1705   1.1      haad 
   1706   1.1      haad 	if (config != NULL) {
   1707   1.1      haad 		ret = put_nvlist(zc, config);
   1708   1.1      haad 		nvlist_free(config);
   1709   1.1      haad 
   1710   1.1      haad 		/*
   1711   1.1      haad 		 * The config may be present even if 'error' is non-zero.
   1712   1.1      haad 		 * In this case we return success, and preserve the real errno
   1713   1.1      haad 		 * in 'zc_cookie'.
   1714   1.1      haad 		 */
   1715   1.1      haad 		zc->zc_cookie = error;
   1716   1.1      haad 	} else {
   1717   1.1      haad 		ret = error;
   1718   1.1      haad 	}
   1719   1.1      haad 
   1720   1.1      haad 	return (ret);
   1721   1.1      haad }
   1722   1.1      haad 
   1723   1.1      haad /*
   1724   1.1      haad  * Try to import the given pool, returning pool stats as appropriate so that
   1725   1.1      haad  * user land knows which devices are available and overall pool health.
   1726   1.1      haad  */
   1727   1.1      haad static int
   1728   1.1      haad zfs_ioc_pool_tryimport(zfs_cmd_t *zc)
   1729   1.1      haad {
   1730   1.1      haad 	nvlist_t *tryconfig, *config;
   1731   1.1      haad 	int error;
   1732   1.1      haad 
   1733   1.1      haad 	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
   1734   1.4      haad 	    zc->zc_iflags, &tryconfig)) != 0)
   1735   1.1      haad 		return (error);
   1736   1.1      haad 
   1737   1.1      haad 	config = spa_tryimport(tryconfig);
   1738   1.1      haad 
   1739   1.1      haad 	nvlist_free(tryconfig);
   1740   1.1      haad 
   1741   1.1      haad 	if (config == NULL)
   1742  1.11       chs 		return (SET_ERROR(EINVAL));
   1743   1.1      haad 
   1744   1.1      haad 	error = put_nvlist(zc, config);
   1745   1.1      haad 	nvlist_free(config);
   1746   1.1      haad 
   1747   1.1      haad 	return (error);
   1748   1.1      haad }
   1749   1.1      haad 
   1750  1.11       chs /*
   1751  1.11       chs  * inputs:
   1752  1.11       chs  * zc_name              name of the pool
   1753  1.11       chs  * zc_cookie            scan func (pool_scan_func_t)
   1754  1.11       chs  */
   1755   1.1      haad static int
   1756  1.11       chs zfs_ioc_pool_scan(zfs_cmd_t *zc)
   1757   1.1      haad {
   1758   1.1      haad 	spa_t *spa;
   1759   1.1      haad 	int error;
   1760   1.1      haad 
   1761   1.1      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
   1762   1.1      haad 		return (error);
   1763   1.1      haad 
   1764  1.11       chs 	if (zc->zc_cookie == POOL_SCAN_NONE)
   1765  1.11       chs 		error = spa_scan_stop(spa);
   1766  1.11       chs 	else
   1767  1.11       chs 		error = spa_scan(spa, zc->zc_cookie);
   1768   1.1      haad 
   1769   1.1      haad 	spa_close(spa, FTAG);
   1770   1.1      haad 
   1771   1.1      haad 	return (error);
   1772   1.1      haad }
   1773   1.1      haad 
   1774   1.1      haad static int
   1775   1.1      haad zfs_ioc_pool_freeze(zfs_cmd_t *zc)
   1776   1.1      haad {
   1777   1.1      haad 	spa_t *spa;
   1778   1.1      haad 	int error;
   1779   1.1      haad 
   1780   1.1      haad 	error = spa_open(zc->zc_name, &spa, FTAG);
   1781   1.1      haad 	if (error == 0) {
   1782   1.1      haad 		spa_freeze(spa);
   1783   1.1      haad 		spa_close(spa, FTAG);
   1784   1.1      haad 	}
   1785   1.1      haad 	return (error);
   1786   1.1      haad }
   1787   1.1      haad 
   1788   1.1      haad static int
   1789   1.1      haad zfs_ioc_pool_upgrade(zfs_cmd_t *zc)
   1790   1.1      haad {
   1791   1.1      haad 	spa_t *spa;
   1792   1.1      haad 	int error;
   1793   1.1      haad 
   1794   1.1      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
   1795   1.1      haad 		return (error);
   1796   1.1      haad 
   1797  1.11       chs 	if (zc->zc_cookie < spa_version(spa) ||
   1798  1.11       chs 	    !SPA_VERSION_IS_SUPPORTED(zc->zc_cookie)) {
   1799   1.1      haad 		spa_close(spa, FTAG);
   1800  1.11       chs 		return (SET_ERROR(EINVAL));
   1801   1.1      haad 	}
   1802   1.1      haad 
   1803   1.1      haad 	spa_upgrade(spa, zc->zc_cookie);
   1804   1.1      haad 	spa_close(spa, FTAG);
   1805   1.1      haad 
   1806   1.1      haad 	return (error);
   1807   1.1      haad }
   1808   1.1      haad 
   1809   1.1      haad static int
   1810   1.1      haad zfs_ioc_pool_get_history(zfs_cmd_t *zc)
   1811   1.1      haad {
   1812   1.1      haad 	spa_t *spa;
   1813   1.1      haad 	char *hist_buf;
   1814   1.1      haad 	uint64_t size;
   1815   1.1      haad 	int error;
   1816   1.1      haad 
   1817   1.1      haad 	if ((size = zc->zc_history_len) == 0)
   1818  1.11       chs 		return (SET_ERROR(EINVAL));
   1819   1.1      haad 
   1820   1.1      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
   1821   1.1      haad 		return (error);
   1822   1.1      haad 
   1823   1.1      haad 	if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
   1824   1.1      haad 		spa_close(spa, FTAG);
   1825  1.11       chs 		return (SET_ERROR(ENOTSUP));
   1826   1.1      haad 	}
   1827   1.1      haad 
   1828   1.1      haad 	hist_buf = kmem_alloc(size, KM_SLEEP);
   1829   1.1      haad 	if ((error = spa_history_get(spa, &zc->zc_history_offset,
   1830   1.1      haad 	    &zc->zc_history_len, hist_buf)) == 0) {
   1831   1.4      haad 		error = ddi_copyout(hist_buf,
   1832   1.4      haad 		    (void *)(uintptr_t)zc->zc_history,
   1833   1.4      haad 		    zc->zc_history_len, zc->zc_iflags);
   1834   1.1      haad 	}
   1835   1.1      haad 
   1836   1.1      haad 	spa_close(spa, FTAG);
   1837   1.1      haad 	kmem_free(hist_buf, size);
   1838   1.1      haad 	return (error);
   1839   1.1      haad }
   1840   1.1      haad 
   1841   1.1      haad static int
   1842  1.11       chs zfs_ioc_pool_reguid(zfs_cmd_t *zc)
   1843   1.1      haad {
   1844  1.11       chs 	spa_t *spa;
   1845   1.1      haad 	int error;
   1846   1.1      haad 
   1847  1.11       chs 	error = spa_open(zc->zc_name, &spa, FTAG);
   1848  1.11       chs 	if (error == 0) {
   1849  1.11       chs 		error = spa_change_guid(spa);
   1850  1.11       chs 		spa_close(spa, FTAG);
   1851  1.11       chs 	}
   1852  1.11       chs 	return (error);
   1853  1.11       chs }
   1854   1.1      haad 
   1855  1.11       chs static int
   1856  1.11       chs zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc)
   1857  1.11       chs {
   1858  1.11       chs 	return (dsl_dsobj_to_dsname(zc->zc_name, zc->zc_obj, zc->zc_value));
   1859   1.1      haad }
   1860   1.1      haad 
   1861   1.4      haad /*
   1862   1.4      haad  * inputs:
   1863   1.4      haad  * zc_name		name of filesystem
   1864   1.4      haad  * zc_obj		object to find
   1865   1.4      haad  *
   1866   1.4      haad  * outputs:
   1867   1.4      haad  * zc_value		name of object
   1868   1.4      haad  */
   1869   1.1      haad static int
   1870   1.1      haad zfs_ioc_obj_to_path(zfs_cmd_t *zc)
   1871   1.1      haad {
   1872   1.4      haad 	objset_t *os;
   1873   1.1      haad 	int error;
   1874   1.1      haad 
   1875   1.4      haad 	/* XXX reading from objset not owned */
   1876   1.4      haad 	if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
   1877   1.1      haad 		return (error);
   1878   1.4      haad 	if (dmu_objset_type(os) != DMU_OST_ZFS) {
   1879   1.4      haad 		dmu_objset_rele(os, FTAG);
   1880  1.11       chs 		return (SET_ERROR(EINVAL));
   1881   1.4      haad 	}
   1882   1.4      haad 	error = zfs_obj_to_path(os, zc->zc_obj, zc->zc_value,
   1883   1.1      haad 	    sizeof (zc->zc_value));
   1884   1.4      haad 	dmu_objset_rele(os, FTAG);
   1885   1.1      haad 
   1886   1.1      haad 	return (error);
   1887   1.1      haad }
   1888   1.1      haad 
   1889  1.11       chs /*
   1890  1.11       chs  * inputs:
   1891  1.11       chs  * zc_name		name of filesystem
   1892  1.11       chs  * zc_obj		object to find
   1893  1.11       chs  *
   1894  1.11       chs  * outputs:
   1895  1.11       chs  * zc_stat		stats on object
   1896  1.11       chs  * zc_value		path to object
   1897  1.11       chs  */
   1898  1.11       chs static int
   1899  1.11       chs zfs_ioc_obj_to_stats(zfs_cmd_t *zc)
   1900  1.11       chs {
   1901  1.11       chs 	objset_t *os;
   1902  1.11       chs 	int error;
   1903  1.11       chs 
   1904  1.11       chs 	/* XXX reading from objset not owned */
   1905  1.11       chs 	if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
   1906  1.11       chs 		return (error);
   1907  1.11       chs 	if (dmu_objset_type(os) != DMU_OST_ZFS) {
   1908  1.11       chs 		dmu_objset_rele(os, FTAG);
   1909  1.11       chs 		return (SET_ERROR(EINVAL));
   1910  1.11       chs 	}
   1911  1.11       chs 	error = zfs_obj_to_stats(os, zc->zc_obj, &zc->zc_stat, zc->zc_value,
   1912  1.11       chs 	    sizeof (zc->zc_value));
   1913  1.11       chs 	dmu_objset_rele(os, FTAG);
   1914  1.11       chs 
   1915  1.11       chs 	return (error);
   1916  1.11       chs }
   1917  1.11       chs 
   1918   1.1      haad static int
   1919   1.1      haad zfs_ioc_vdev_add(zfs_cmd_t *zc)
   1920   1.1      haad {
   1921   1.1      haad 	spa_t *spa;
   1922   1.1      haad 	int error;
   1923   1.1      haad 	nvlist_t *config, **l2cache, **spares;
   1924   1.1      haad 	uint_t nl2cache = 0, nspares = 0;
   1925   1.1      haad 
   1926   1.1      haad 	error = spa_open(zc->zc_name, &spa, FTAG);
   1927   1.1      haad 	if (error != 0)
   1928   1.1      haad 		return (error);
   1929   1.1      haad 
   1930   1.1      haad 	error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
   1931   1.4      haad 	    zc->zc_iflags, &config);
   1932   1.1      haad 	(void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_L2CACHE,
   1933   1.1      haad 	    &l2cache, &nl2cache);
   1934   1.1      haad 
   1935   1.1      haad 	(void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_SPARES,
   1936   1.1      haad 	    &spares, &nspares);
   1937   1.1      haad 
   1938  1.11       chs #ifdef illumos
   1939   1.1      haad 	/*
   1940   1.1      haad 	 * A root pool with concatenated devices is not supported.
   1941   1.1      haad 	 * Thus, can not add a device to a root pool.
   1942   1.1      haad 	 *
   1943   1.1      haad 	 * Intent log device can not be added to a rootpool because
   1944   1.1      haad 	 * during mountroot, zil is replayed, a seperated log device
   1945   1.1      haad 	 * can not be accessed during the mountroot time.
   1946   1.1      haad 	 *
   1947   1.1      haad 	 * l2cache and spare devices are ok to be added to a rootpool.
   1948   1.1      haad 	 */
   1949   1.4      haad 	if (spa_bootfs(spa) != 0 && nl2cache == 0 && nspares == 0) {
   1950   1.4      haad 		nvlist_free(config);
   1951   1.1      haad 		spa_close(spa, FTAG);
   1952  1.11       chs 		return (SET_ERROR(EDOM));
   1953   1.1      haad 	}
   1954  1.11       chs #endif /* illumos */
   1955   1.1      haad 
   1956   1.1      haad 	if (error == 0) {
   1957   1.1      haad 		error = spa_vdev_add(spa, config);
   1958   1.1      haad 		nvlist_free(config);
   1959   1.1      haad 	}
   1960   1.1      haad 	spa_close(spa, FTAG);
   1961   1.1      haad 	return (error);
   1962   1.1      haad }
   1963   1.1      haad 
   1964  1.11       chs /*
   1965  1.11       chs  * inputs:
   1966  1.11       chs  * zc_name		name of the pool
   1967  1.11       chs  * zc_nvlist_conf	nvlist of devices to remove
   1968  1.11       chs  * zc_cookie		to stop the remove?
   1969  1.11       chs  */
   1970   1.1      haad static int
   1971   1.1      haad zfs_ioc_vdev_remove(zfs_cmd_t *zc)
   1972   1.1      haad {
   1973   1.1      haad 	spa_t *spa;
   1974   1.1      haad 	int error;
   1975   1.1      haad 
   1976   1.1      haad 	error = spa_open(zc->zc_name, &spa, FTAG);
   1977   1.1      haad 	if (error != 0)
   1978   1.1      haad 		return (error);
   1979   1.1      haad 	error = spa_vdev_remove(spa, zc->zc_guid, B_FALSE);
   1980   1.1      haad 	spa_close(spa, FTAG);
   1981   1.1      haad 	return (error);
   1982   1.1      haad }
   1983   1.1      haad 
   1984   1.1      haad static int
   1985   1.1      haad zfs_ioc_vdev_set_state(zfs_cmd_t *zc)
   1986   1.1      haad {
   1987   1.1      haad 	spa_t *spa;
   1988   1.1      haad 	int error;
   1989   1.1      haad 	vdev_state_t newstate = VDEV_STATE_UNKNOWN;
   1990   1.1      haad 
   1991   1.1      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
   1992   1.1      haad 		return (error);
   1993   1.1      haad 	switch (zc->zc_cookie) {
   1994   1.1      haad 	case VDEV_STATE_ONLINE:
   1995   1.1      haad 		error = vdev_online(spa, zc->zc_guid, zc->zc_obj, &newstate);
   1996   1.1      haad 		break;
   1997   1.1      haad 
   1998   1.1      haad 	case VDEV_STATE_OFFLINE:
   1999   1.1      haad 		error = vdev_offline(spa, zc->zc_guid, zc->zc_obj);
   2000   1.1      haad 		break;
   2001   1.1      haad 
   2002   1.1      haad 	case VDEV_STATE_FAULTED:
   2003   1.4      haad 		if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
   2004   1.4      haad 		    zc->zc_obj != VDEV_AUX_EXTERNAL)
   2005   1.4      haad 			zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
   2006   1.4      haad 
   2007   1.4      haad 		error = vdev_fault(spa, zc->zc_guid, zc->zc_obj);
   2008   1.1      haad 		break;
   2009   1.1      haad 
   2010   1.1      haad 	case VDEV_STATE_DEGRADED:
   2011   1.4      haad 		if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
   2012   1.4      haad 		    zc->zc_obj != VDEV_AUX_EXTERNAL)
   2013   1.4      haad 			zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
   2014   1.4      haad 
   2015   1.4      haad 		error = vdev_degrade(spa, zc->zc_guid, zc->zc_obj);
   2016   1.1      haad 		break;
   2017   1.1      haad 
   2018   1.1      haad 	default:
   2019  1.11       chs 		error = SET_ERROR(EINVAL);
   2020   1.1      haad 	}
   2021   1.1      haad 	zc->zc_cookie = newstate;
   2022   1.1      haad 	spa_close(spa, FTAG);
   2023   1.1      haad 	return (error);
   2024   1.1      haad }
   2025   1.1      haad 
   2026   1.1      haad static int
   2027   1.1      haad zfs_ioc_vdev_attach(zfs_cmd_t *zc)
   2028   1.1      haad {
   2029   1.1      haad 	spa_t *spa;
   2030   1.1      haad 	int replacing = zc->zc_cookie;
   2031   1.1      haad 	nvlist_t *config;
   2032   1.1      haad 	int error;
   2033   1.1      haad 
   2034   1.1      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
   2035   1.1      haad 		return (error);
   2036   1.1      haad 
   2037   1.1      haad 	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
   2038   1.4      haad 	    zc->zc_iflags, &config)) == 0) {
   2039   1.1      haad 		error = spa_vdev_attach(spa, zc->zc_guid, config, replacing);
   2040   1.1      haad 		nvlist_free(config);
   2041   1.1      haad 	}
   2042   1.1      haad 
   2043   1.1      haad 	spa_close(spa, FTAG);
   2044   1.1      haad 	return (error);
   2045   1.1      haad }
   2046   1.1      haad 
   2047   1.1      haad static int
   2048   1.1      haad zfs_ioc_vdev_detach(zfs_cmd_t *zc)
   2049   1.1      haad {
   2050   1.1      haad 	spa_t *spa;
   2051   1.1      haad 	int error;
   2052   1.1      haad 
   2053   1.1      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
   2054   1.1      haad 		return (error);
   2055   1.1      haad 
   2056   1.4      haad 	error = spa_vdev_detach(spa, zc->zc_guid, 0, B_FALSE);
   2057   1.1      haad 
   2058   1.1      haad 	spa_close(spa, FTAG);
   2059   1.1      haad 	return (error);
   2060   1.1      haad }
   2061   1.1      haad 
   2062   1.1      haad static int
   2063   1.4      haad zfs_ioc_vdev_split(zfs_cmd_t *zc)
   2064   1.1      haad {
   2065   1.1      haad 	spa_t *spa;
   2066   1.4      haad 	nvlist_t *config, *props = NULL;
   2067   1.1      haad 	int error;
   2068   1.4      haad 	boolean_t exp = !!(zc->zc_cookie & ZPOOL_EXPORT_AFTER_SPLIT);
   2069   1.1      haad 
   2070   1.4      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
   2071   1.4      haad 		return (error);
   2072   1.4      haad 
   2073   1.4      haad 	if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
   2074   1.4      haad 	    zc->zc_iflags, &config)) {
   2075   1.4      haad 		spa_close(spa, FTAG);
   2076   1.4      haad 		return (error);
   2077   1.4      haad 	}
   2078   1.4      haad 
   2079   1.4      haad 	if (zc->zc_nvlist_src_size != 0 && (error =
   2080   1.4      haad 	    get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
   2081   1.4      haad 	    zc->zc_iflags, &props))) {
   2082   1.4      haad 		spa_close(spa, FTAG);
   2083   1.4      haad 		nvlist_free(config);
   2084   1.4      haad 		return (error);
   2085   1.4      haad 	}
   2086   1.4      haad 
   2087   1.4      haad 	error = spa_vdev_split_mirror(spa, zc->zc_string, config, props, exp);
   2088   1.4      haad 
   2089   1.4      haad 	spa_close(spa, FTAG);
   2090   1.4      haad 
   2091   1.4      haad 	nvlist_free(config);
   2092   1.4      haad 	nvlist_free(props);
   2093   1.4      haad 
   2094   1.4      haad 	return (error);
   2095   1.4      haad }
   2096   1.4      haad 
   2097   1.4      haad static int
   2098   1.4      haad zfs_ioc_vdev_setpath(zfs_cmd_t *zc)
   2099   1.4      haad {
   2100   1.4      haad 	spa_t *spa;
   2101   1.4      haad 	char *path = zc->zc_value;
   2102   1.4      haad 	uint64_t guid = zc->zc_guid;
   2103   1.4      haad 	int error;
   2104   1.4      haad 
   2105   1.4      haad 	error = spa_open(zc->zc_name, &spa, FTAG);
   2106   1.4      haad 	if (error != 0)
   2107   1.1      haad 		return (error);
   2108   1.1      haad 
   2109   1.1      haad 	error = spa_vdev_setpath(spa, guid, path);
   2110   1.1      haad 	spa_close(spa, FTAG);
   2111   1.1      haad 	return (error);
   2112   1.1      haad }
   2113   1.1      haad 
   2114   1.4      haad static int
   2115   1.4      haad zfs_ioc_vdev_setfru(zfs_cmd_t *zc)
   2116   1.4      haad {
   2117   1.4      haad 	spa_t *spa;
   2118   1.4      haad 	char *fru = zc->zc_value;
   2119   1.4      haad 	uint64_t guid = zc->zc_guid;
   2120   1.4      haad 	int error;
   2121   1.4      haad 
   2122   1.4      haad 	error = spa_open(zc->zc_name, &spa, FTAG);
   2123   1.4      haad 	if (error != 0)
   2124   1.4      haad 		return (error);
   2125   1.4      haad 
   2126   1.4      haad 	error = spa_vdev_setfru(spa, guid, fru);
   2127   1.4      haad 	spa_close(spa, FTAG);
   2128   1.4      haad 	return (error);
   2129   1.4      haad }
   2130   1.4      haad 
   2131   1.1      haad static int
   2132  1.11       chs zfs_ioc_objset_stats_impl(zfs_cmd_t *zc, objset_t *os)
   2133   1.1      haad {
   2134  1.11       chs 	int error = 0;
   2135   1.1      haad 	nvlist_t *nv;
   2136   1.1      haad 
   2137   1.1      haad 	dmu_objset_fast_stat(os, &zc->zc_objset_stats);
   2138   1.1      haad 
   2139   1.1      haad 	if (zc->zc_nvlist_dst != 0 &&
   2140   1.4      haad 	    (error = dsl_prop_get_all(os, &nv)) == 0) {
   2141   1.1      haad 		dmu_objset_stats(os, nv);
   2142   1.1      haad 		/*
   2143   1.1      haad 		 * NB: zvol_get_stats() will read the objset contents,
   2144   1.1      haad 		 * which we aren't supposed to do with a
   2145   1.1      haad 		 * DS_MODE_USER hold, because it could be
   2146   1.1      haad 		 * inconsistent.  So this is a bit of a workaround...
   2147   1.4      haad 		 * XXX reading with out owning
   2148   1.1      haad 		 */
   2149  1.11       chs 		if (!zc->zc_objset_stats.dds_inconsistent &&
   2150  1.11       chs 		    dmu_objset_type(os) == DMU_OST_ZVOL) {
   2151  1.11       chs 			error = zvol_get_stats(os, nv);
   2152  1.11       chs 			if (error == EIO)
   2153  1.11       chs 				return (error);
   2154  1.11       chs 			VERIFY0(error);
   2155   1.1      haad 		}
   2156   1.1      haad 		error = put_nvlist(zc, nv);
   2157   1.1      haad 		nvlist_free(nv);
   2158   1.1      haad 	}
   2159   1.1      haad 
   2160  1.11       chs 	return (error);
   2161  1.11       chs }
   2162  1.11       chs 
   2163  1.11       chs /*
   2164  1.11       chs  * inputs:
   2165  1.11       chs  * zc_name		name of filesystem
   2166  1.11       chs  * zc_nvlist_dst_size	size of buffer for property nvlist
   2167  1.11       chs  *
   2168  1.11       chs  * outputs:
   2169  1.11       chs  * zc_objset_stats	stats
   2170  1.11       chs  * zc_nvlist_dst	property nvlist
   2171  1.11       chs  * zc_nvlist_dst_size	size of property nvlist
   2172  1.11       chs  */
   2173  1.11       chs static int
   2174  1.11       chs zfs_ioc_objset_stats(zfs_cmd_t *zc)
   2175  1.11       chs {
   2176  1.11       chs 	objset_t *os;
   2177  1.11       chs 	int error;
   2178  1.11       chs 
   2179  1.11       chs 	error = dmu_objset_hold(zc->zc_name, FTAG, &os);
   2180  1.11       chs 	if (error == 0) {
   2181  1.11       chs 		error = zfs_ioc_objset_stats_impl(zc, os);
   2182  1.11       chs 		dmu_objset_rele(os, FTAG);
   2183  1.11       chs 	}
   2184  1.11       chs 
   2185  1.11       chs 	if (error == ENOMEM)
   2186  1.11       chs 		error = 0;
   2187   1.4      haad 	return (error);
   2188   1.4      haad }
   2189   1.4      haad 
   2190   1.4      haad /*
   2191   1.4      haad  * inputs:
   2192   1.4      haad  * zc_name		name of filesystem
   2193   1.4      haad  * zc_nvlist_dst_size	size of buffer for property nvlist
   2194   1.4      haad  *
   2195   1.4      haad  * outputs:
   2196   1.4      haad  * zc_nvlist_dst	received property nvlist
   2197   1.4      haad  * zc_nvlist_dst_size	size of received property nvlist
   2198   1.4      haad  *
   2199   1.4      haad  * Gets received properties (distinct from local properties on or after
   2200   1.4      haad  * SPA_VERSION_RECVD_PROPS) for callers who want to differentiate received from
   2201   1.4      haad  * local property values.
   2202   1.4      haad  */
   2203   1.4      haad static int
   2204   1.4      haad zfs_ioc_objset_recvd_props(zfs_cmd_t *zc)
   2205   1.4      haad {
   2206  1.11       chs 	int error = 0;
   2207   1.4      haad 	nvlist_t *nv;
   2208   1.4      haad 
   2209   1.4      haad 	/*
   2210   1.4      haad 	 * Without this check, we would return local property values if the
   2211   1.4      haad 	 * caller has not already received properties on or after
   2212   1.4      haad 	 * SPA_VERSION_RECVD_PROPS.
   2213   1.4      haad 	 */
   2214  1.11       chs 	if (!dsl_prop_get_hasrecvd(zc->zc_name))
   2215  1.11       chs 		return (SET_ERROR(ENOTSUP));
   2216   1.4      haad 
   2217   1.4      haad 	if (zc->zc_nvlist_dst != 0 &&
   2218  1.11       chs 	    (error = dsl_prop_get_received(zc->zc_name, &nv)) == 0) {
   2219   1.4      haad 		error = put_nvlist(zc, nv);
   2220   1.4      haad 		nvlist_free(nv);
   2221   1.4      haad 	}
   2222   1.4      haad 
   2223   1.1      haad 	return (error);
   2224   1.1      haad }
   2225   1.1      haad 
   2226   1.1      haad static int
   2227   1.1      haad nvl_add_zplprop(objset_t *os, nvlist_t *props, zfs_prop_t prop)
   2228   1.1      haad {
   2229   1.1      haad 	uint64_t value;
   2230   1.1      haad 	int error;
   2231   1.1      haad 
   2232   1.1      haad 	/*
   2233   1.1      haad 	 * zfs_get_zplprop() will either find a value or give us
   2234   1.1      haad 	 * the default value (if there is one).
   2235   1.1      haad 	 */
   2236   1.1      haad 	if ((error = zfs_get_zplprop(os, prop, &value)) != 0)
   2237   1.1      haad 		return (error);
   2238   1.1      haad 	VERIFY(nvlist_add_uint64(props, zfs_prop_to_name(prop), value) == 0);
   2239   1.1      haad 	return (0);
   2240   1.1      haad }
   2241   1.1      haad 
   2242   1.1      haad /*
   2243   1.1      haad  * inputs:
   2244   1.1      haad  * zc_name		name of filesystem
   2245   1.1      haad  * zc_nvlist_dst_size	size of buffer for zpl property nvlist
   2246   1.1      haad  *
   2247   1.1      haad  * outputs:
   2248   1.1      haad  * zc_nvlist_dst	zpl property nvlist
   2249   1.1      haad  * zc_nvlist_dst_size	size of zpl property nvlist
   2250   1.1      haad  */
   2251   1.1      haad static int
   2252   1.1      haad zfs_ioc_objset_zplprops(zfs_cmd_t *zc)
   2253   1.1      haad {
   2254   1.1      haad 	objset_t *os;
   2255   1.1      haad 	int err;
   2256   1.1      haad 
   2257   1.4      haad 	/* XXX reading without owning */
   2258   1.4      haad 	if (err = dmu_objset_hold(zc->zc_name, FTAG, &os))
   2259   1.1      haad 		return (err);
   2260   1.1      haad 
   2261   1.1      haad 	dmu_objset_fast_stat(os, &zc->zc_objset_stats);
   2262   1.1      haad 
   2263   1.1      haad 	/*
   2264   1.1      haad 	 * NB: nvl_add_zplprop() will read the objset contents,
   2265   1.1      haad 	 * which we aren't supposed to do with a DS_MODE_USER
   2266   1.1      haad 	 * hold, because it could be inconsistent.
   2267   1.1      haad 	 */
   2268   1.8  christos 	if (zc->zc_nvlist_dst != 0 &&
   2269   1.1      haad 	    !zc->zc_objset_stats.dds_inconsistent &&
   2270   1.1      haad 	    dmu_objset_type(os) == DMU_OST_ZFS) {
   2271   1.1      haad 		nvlist_t *nv;
   2272   1.1      haad 
   2273   1.1      haad 		VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   2274   1.1      haad 		if ((err = nvl_add_zplprop(os, nv, ZFS_PROP_VERSION)) == 0 &&
   2275   1.1      haad 		    (err = nvl_add_zplprop(os, nv, ZFS_PROP_NORMALIZE)) == 0 &&
   2276   1.1      haad 		    (err = nvl_add_zplprop(os, nv, ZFS_PROP_UTF8ONLY)) == 0 &&
   2277   1.1      haad 		    (err = nvl_add_zplprop(os, nv, ZFS_PROP_CASE)) == 0)
   2278   1.1      haad 			err = put_nvlist(zc, nv);
   2279   1.1      haad 		nvlist_free(nv);
   2280   1.1      haad 	} else {
   2281  1.11       chs 		err = SET_ERROR(ENOENT);
   2282   1.1      haad 	}
   2283   1.4      haad 	dmu_objset_rele(os, FTAG);
   2284   1.1      haad 	return (err);
   2285   1.1      haad }
   2286   1.1      haad 
   2287  1.11       chs boolean_t
   2288   1.4      haad dataset_name_hidden(const char *name)
   2289   1.1      haad {
   2290   1.4      haad 	/*
   2291   1.4      haad 	 * Skip over datasets that are not visible in this zone,
   2292   1.4      haad 	 * internal datasets (which have a $ in their name), and
   2293   1.4      haad 	 * temporary datasets (which have a % in their name).
   2294   1.4      haad 	 */
   2295   1.4      haad 	if (strchr(name, '$') != NULL)
   2296   1.4      haad 		return (B_TRUE);
   2297   1.4      haad 	if (strchr(name, '%') != NULL)
   2298   1.4      haad 		return (B_TRUE);
   2299  1.11       chs 	if (!INGLOBALZONE(curthread) && !zone_dataset_visible(name, NULL))
   2300   1.4      haad 		return (B_TRUE);
   2301   1.4      haad 	return (B_FALSE);
   2302   1.1      haad }
   2303   1.1      haad 
   2304   1.1      haad /*
   2305   1.1      haad  * inputs:
   2306   1.1      haad  * zc_name		name of filesystem
   2307   1.1      haad  * zc_cookie		zap cursor
   2308   1.1      haad  * zc_nvlist_dst_size	size of buffer for property nvlist
   2309   1.1      haad  *
   2310   1.1      haad  * outputs:
   2311   1.1      haad  * zc_name		name of next filesystem
   2312   1.4      haad  * zc_cookie		zap cursor
   2313   1.1      haad  * zc_objset_stats	stats
   2314   1.1      haad  * zc_nvlist_dst	property nvlist
   2315   1.1      haad  * zc_nvlist_dst_size	size of property nvlist
   2316   1.1      haad  */
   2317   1.1      haad static int
   2318   1.1      haad zfs_ioc_dataset_list_next(zfs_cmd_t *zc)
   2319   1.1      haad {
   2320   1.1      haad 	objset_t *os;
   2321   1.1      haad 	int error;
   2322   1.1      haad 	char *p;
   2323   1.4      haad 	size_t orig_len = strlen(zc->zc_name);
   2324   1.1      haad 
   2325   1.4      haad top:
   2326   1.4      haad 	if (error = dmu_objset_hold(zc->zc_name, FTAG, &os)) {
   2327   1.1      haad 		if (error == ENOENT)
   2328  1.11       chs 			error = SET_ERROR(ESRCH);
   2329   1.1      haad 		return (error);
   2330   1.1      haad 	}
   2331   1.1      haad 
   2332   1.1      haad 	p = strrchr(zc->zc_name, '/');
   2333   1.1      haad 	if (p == NULL || p[1] != '\0')
   2334   1.1      haad 		(void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name));
   2335   1.1      haad 	p = zc->zc_name + strlen(zc->zc_name);
   2336   1.1      haad 
   2337   1.1      haad 	do {
   2338   1.1      haad 		error = dmu_dir_list_next(os,
   2339   1.1      haad 		    sizeof (zc->zc_name) - (p - zc->zc_name), p,
   2340   1.1      haad 		    NULL, &zc->zc_cookie);
   2341   1.1      haad 		if (error == ENOENT)
   2342  1.11       chs 			error = SET_ERROR(ESRCH);
   2343  1.11       chs 	} while (error == 0 && dataset_name_hidden(zc->zc_name));
   2344   1.4      haad 	dmu_objset_rele(os, FTAG);
   2345   1.1      haad 
   2346   1.1      haad 	/*
   2347   1.4      haad 	 * If it's an internal dataset (ie. with a '$' in its name),
   2348   1.4      haad 	 * don't try to get stats for it, otherwise we'll return ENOENT.
   2349   1.1      haad 	 */
   2350   1.4      haad 	if (error == 0 && strchr(zc->zc_name, '$') == NULL) {
   2351   1.1      haad 		error = zfs_ioc_objset_stats(zc); /* fill in the stats */
   2352   1.4      haad 		if (error == ENOENT) {
   2353   1.4      haad 			/* We lost a race with destroy, get the next one. */
   2354   1.4      haad 			zc->zc_name[orig_len] = '\0';
   2355   1.4      haad 			goto top;
   2356   1.4      haad 		}
   2357   1.4      haad 	}
   2358   1.1      haad 	return (error);
   2359   1.1      haad }
   2360   1.1      haad 
   2361   1.1      haad /*
   2362   1.1      haad  * inputs:
   2363   1.1      haad  * zc_name		name of filesystem
   2364   1.1      haad  * zc_cookie		zap cursor
   2365   1.1      haad  * zc_nvlist_dst_size	size of buffer for property nvlist
   2366  1.11       chs  * zc_simple		when set, only name is requested
   2367   1.1      haad  *
   2368   1.1      haad  * outputs:
   2369   1.1      haad  * zc_name		name of next snapshot
   2370   1.1      haad  * zc_objset_stats	stats
   2371   1.1      haad  * zc_nvlist_dst	property nvlist
   2372   1.1      haad  * zc_nvlist_dst_size	size of property nvlist
   2373   1.1      haad  */
   2374   1.1      haad static int
   2375   1.1      haad zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
   2376   1.1      haad {
   2377   1.1      haad 	objset_t *os;
   2378   1.1      haad 	int error;
   2379   1.1      haad 
   2380   1.4      haad 	error = dmu_objset_hold(zc->zc_name, FTAG, &os);
   2381  1.11       chs 	if (error != 0) {
   2382   1.1      haad 		return (error == ENOENT ? ESRCH : error);
   2383  1.11       chs 	}
   2384   1.1      haad 
   2385   1.1      haad 	/*
   2386   1.1      haad 	 * A dataset name of maximum length cannot have any snapshots,
   2387   1.1      haad 	 * so exit immediately.
   2388   1.1      haad 	 */
   2389  1.11       chs 	if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >=
   2390  1.11       chs 	    ZFS_MAX_DATASET_NAME_LEN) {
   2391   1.4      haad 		dmu_objset_rele(os, FTAG);
   2392  1.11       chs 		return (SET_ERROR(ESRCH));
   2393   1.1      haad 	}
   2394   1.1      haad 
   2395   1.1      haad 	error = dmu_snapshot_list_next(os,
   2396   1.1      haad 	    sizeof (zc->zc_name) - strlen(zc->zc_name),
   2397  1.11       chs 	    zc->zc_name + strlen(zc->zc_name), &zc->zc_obj, &zc->zc_cookie,
   2398  1.11       chs 	    NULL);
   2399  1.11       chs 
   2400  1.11       chs 	if (error == 0 && !zc->zc_simple) {
   2401  1.11       chs 		dsl_dataset_t *ds;
   2402  1.11       chs 		dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool;
   2403  1.11       chs 
   2404  1.11       chs 		error = dsl_dataset_hold_obj(dp, zc->zc_obj, FTAG, &ds);
   2405  1.11       chs 		if (error == 0) {
   2406  1.11       chs 			objset_t *ossnap;
   2407  1.11       chs 
   2408  1.11       chs 			error = dmu_objset_from_ds(ds, &ossnap);
   2409  1.11       chs 			if (error == 0)
   2410  1.11       chs 				error = zfs_ioc_objset_stats_impl(zc, ossnap);
   2411  1.11       chs 			dsl_dataset_rele(ds, FTAG);
   2412   1.4      haad 		}
   2413   1.4      haad 	} else if (error == ENOENT) {
   2414  1.11       chs 		error = SET_ERROR(ESRCH);
   2415   1.4      haad 	}
   2416   1.1      haad 
   2417  1.11       chs 	dmu_objset_rele(os, FTAG);
   2418   1.1      haad 	/* if we failed, undo the @ that we tacked on to zc_name */
   2419  1.11       chs 	if (error != 0)
   2420   1.1      haad 		*strchr(zc->zc_name, '@') = '\0';
   2421   1.1      haad 	return (error);
   2422   1.1      haad }
   2423   1.1      haad 
   2424   1.4      haad static int
   2425   1.4      haad zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
   2426   1.1      haad {
   2427   1.4      haad 	const char *propname = nvpair_name(pair);
   2428   1.4      haad 	uint64_t *valary;
   2429   1.4      haad 	unsigned int vallen;
   2430   1.4      haad 	const char *domain;
   2431  1.11       chs 	char *dash;
   2432   1.4      haad 	zfs_userquota_prop_t type;
   2433   1.4      haad 	uint64_t rid;
   2434   1.4      haad 	uint64_t quota;
   2435   1.4      haad 	zfsvfs_t *zfsvfs;
   2436   1.4      haad 	int err;
   2437   1.4      haad 
   2438   1.4      haad 	if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
   2439   1.4      haad 		nvlist_t *attrs;
   2440   1.4      haad 		VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
   2441  1.11       chs 		if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
   2442  1.11       chs 		    &pair) != 0)
   2443  1.11       chs 			return (SET_ERROR(EINVAL));
   2444   1.4      haad 	}
   2445   1.1      haad 
   2446  1.11       chs 	/*
   2447  1.11       chs 	 * A correctly constructed propname is encoded as
   2448  1.11       chs 	 * userquota@<rid>-<domain>.
   2449  1.11       chs 	 */
   2450  1.11       chs 	if ((dash = strchr(propname, '-')) == NULL ||
   2451  1.11       chs 	    nvpair_value_uint64_array(pair, &valary, &vallen) != 0 ||
   2452  1.11       chs 	    vallen != 3)
   2453  1.11       chs 		return (SET_ERROR(EINVAL));
   2454  1.11       chs 
   2455  1.11       chs 	domain = dash + 1;
   2456   1.4      haad 	type = valary[0];
   2457   1.4      haad 	rid = valary[1];
   2458   1.4      haad 	quota = valary[2];
   2459   1.4      haad 
   2460  1.11       chs 	err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_FALSE);
   2461   1.4      haad 	if (err == 0) {
   2462   1.4      haad 		err = zfs_set_userquota(zfsvfs, type, domain, rid, quota);
   2463   1.4      haad 		zfsvfs_rele(zfsvfs, FTAG);
   2464   1.4      haad 	}
   2465   1.4      haad 
   2466   1.4      haad 	return (err);
   2467   1.4      haad }
   2468   1.1      haad 
   2469   1.4      haad /*
   2470   1.4      haad  * If the named property is one that has a special function to set its value,
   2471   1.4      haad  * return 0 on success and a positive error code on failure; otherwise if it is
   2472   1.4      haad  * not one of the special properties handled by this function, return -1.
   2473   1.4      haad  *
   2474  1.11       chs  * XXX: It would be better for callers of the property interface if we handled
   2475   1.4      haad  * these special cases in dsl_prop.c (in the dsl layer).
   2476   1.4      haad  */
   2477   1.4      haad static int
   2478   1.4      haad zfs_prop_set_special(const char *dsname, zprop_source_t source,
   2479   1.4      haad     nvpair_t *pair)
   2480   1.4      haad {
   2481   1.4      haad 	const char *propname = nvpair_name(pair);
   2482   1.4      haad 	zfs_prop_t prop = zfs_name_to_prop(propname);
   2483   1.4      haad 	uint64_t intval;
   2484  1.11       chs 	int err = -1;
   2485   1.1      haad 
   2486   1.4      haad 	if (prop == ZPROP_INVAL) {
   2487   1.4      haad 		if (zfs_prop_userquota(propname))
   2488   1.4      haad 			return (zfs_prop_set_userquota(dsname, pair));
   2489   1.4      haad 		return (-1);
   2490   1.4      haad 	}
   2491   1.1      haad 
   2492   1.4      haad 	if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
   2493   1.4      haad 		nvlist_t *attrs;
   2494   1.4      haad 		VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
   2495   1.4      haad 		VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
   2496   1.4      haad 		    &pair) == 0);
   2497   1.4      haad 	}
   2498   1.1      haad 
   2499   1.4      haad 	if (zfs_prop_get_type(prop) == PROP_TYPE_STRING)
   2500   1.4      haad 		return (-1);
   2501   1.1      haad 
   2502   1.4      haad 	VERIFY(0 == nvpair_value_uint64(pair, &intval));
   2503   1.1      haad 
   2504   1.4      haad 	switch (prop) {
   2505   1.4      haad 	case ZFS_PROP_QUOTA:
   2506   1.4      haad 		err = dsl_dir_set_quota(dsname, source, intval);
   2507   1.4      haad 		break;
   2508   1.4      haad 	case ZFS_PROP_REFQUOTA:
   2509  1.11       chs 		err = dsl_dataset_set_refquota(dsname, source, intval);
   2510  1.11       chs 		break;
   2511  1.11       chs 	case ZFS_PROP_FILESYSTEM_LIMIT:
   2512  1.11       chs 	case ZFS_PROP_SNAPSHOT_LIMIT:
   2513  1.11       chs 		if (intval == UINT64_MAX) {
   2514  1.11       chs 			/* clearing the limit, just do it */
   2515  1.11       chs 			err = 0;
   2516  1.11       chs 		} else {
   2517  1.11       chs 			err = dsl_dir_activate_fs_ss_limit(dsname);
   2518  1.11       chs 		}
   2519  1.11       chs 		/*
   2520  1.11       chs 		 * Set err to -1 to force the zfs_set_prop_nvlist code down the
   2521  1.11       chs 		 * default path to set the value in the nvlist.
   2522  1.11       chs 		 */
   2523  1.11       chs 		if (err == 0)
   2524  1.11       chs 			err = -1;
   2525   1.4      haad 		break;
   2526   1.4      haad 	case ZFS_PROP_RESERVATION:
   2527   1.4      haad 		err = dsl_dir_set_reservation(dsname, source, intval);
   2528   1.4      haad 		break;
   2529   1.4      haad 	case ZFS_PROP_REFRESERVATION:
   2530  1.11       chs 		err = dsl_dataset_set_refreservation(dsname, source, intval);
   2531   1.4      haad 		break;
   2532   1.4      haad 	case ZFS_PROP_VOLSIZE:
   2533  1.11       chs 		err = zvol_set_volsize(dsname, intval);
   2534   1.4      haad 		break;
   2535   1.4      haad 	case ZFS_PROP_VERSION:
   2536   1.4      haad 	{
   2537   1.4      haad 		zfsvfs_t *zfsvfs;
   2538   1.1      haad 
   2539  1.11       chs 		if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_TRUE)) != 0)
   2540   1.1      haad 			break;
   2541   1.1      haad 
   2542   1.4      haad 		err = zfs_set_version(zfsvfs, intval);
   2543   1.4      haad 		zfsvfs_rele(zfsvfs, FTAG);
   2544   1.1      haad 
   2545   1.4      haad 		if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
   2546   1.4      haad 			zfs_cmd_t *zc;
   2547   1.1      haad 
   2548   1.4      haad 			zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
   2549   1.4      haad 			(void) strcpy(zc->zc_name, dsname);
   2550   1.4      haad 			(void) zfs_ioc_userspace_upgrade(zc);
   2551   1.4      haad 			kmem_free(zc, sizeof (zfs_cmd_t));
   2552   1.1      haad 		}
   2553   1.4      haad 		break;
   2554   1.4      haad 	}
   2555   1.4      haad 	default:
   2556   1.4      haad 		err = -1;
   2557   1.4      haad 	}
   2558   1.1      haad 
   2559   1.4      haad 	return (err);
   2560   1.4      haad }
   2561   1.1      haad 
   2562   1.4      haad /*
   2563   1.4      haad  * This function is best effort. If it fails to set any of the given properties,
   2564  1.11       chs  * it continues to set as many as it can and returns the last error
   2565  1.11       chs  * encountered. If the caller provides a non-NULL errlist, it will be filled in
   2566  1.11       chs  * with the list of names of all the properties that failed along with the
   2567  1.11       chs  * corresponding error numbers.
   2568   1.4      haad  *
   2569  1.11       chs  * If every property is set successfully, zero is returned and errlist is not
   2570  1.11       chs  * modified.
   2571   1.4      haad  */
   2572   1.4      haad int
   2573   1.4      haad zfs_set_prop_nvlist(const char *dsname, zprop_source_t source, nvlist_t *nvl,
   2574  1.11       chs     nvlist_t *errlist)
   2575   1.4      haad {
   2576   1.4      haad 	nvpair_t *pair;
   2577   1.4      haad 	nvpair_t *propval;
   2578   1.4      haad 	int rv = 0;
   2579   1.4      haad 	uint64_t intval;
   2580   1.4      haad 	char *strval;
   2581  1.11       chs 	nvlist_t *genericnvl = fnvlist_alloc();
   2582  1.11       chs 	nvlist_t *retrynvl = fnvlist_alloc();
   2583   1.4      haad 
   2584   1.4      haad retry:
   2585   1.4      haad 	pair = NULL;
   2586   1.4      haad 	while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
   2587   1.4      haad 		const char *propname = nvpair_name(pair);
   2588   1.4      haad 		zfs_prop_t prop = zfs_name_to_prop(propname);
   2589   1.4      haad 		int err = 0;
   2590   1.1      haad 
   2591   1.4      haad 		/* decode the property value */
   2592   1.4      haad 		propval = pair;
   2593   1.4      haad 		if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
   2594   1.4      haad 			nvlist_t *attrs;
   2595  1.11       chs 			attrs = fnvpair_value_nvlist(pair);
   2596  1.11       chs 			if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
   2597  1.11       chs 			    &propval) != 0)
   2598  1.11       chs 				err = SET_ERROR(EINVAL);
   2599   1.4      haad 		}
   2600   1.1      haad 
   2601   1.4      haad 		/* Validate value type */
   2602  1.11       chs 		if (err == 0 && prop == ZPROP_INVAL) {
   2603   1.4      haad 			if (zfs_prop_user(propname)) {
   2604   1.4      haad 				if (nvpair_type(propval) != DATA_TYPE_STRING)
   2605  1.11       chs 					err = SET_ERROR(EINVAL);
   2606   1.4      haad 			} else if (zfs_prop_userquota(propname)) {
   2607   1.4      haad 				if (nvpair_type(propval) !=
   2608   1.4      haad 				    DATA_TYPE_UINT64_ARRAY)
   2609  1.11       chs 					err = SET_ERROR(EINVAL);
   2610  1.11       chs 			} else {
   2611  1.11       chs 				err = SET_ERROR(EINVAL);
   2612   1.4      haad 			}
   2613  1.11       chs 		} else if (err == 0) {
   2614   1.4      haad 			if (nvpair_type(propval) == DATA_TYPE_STRING) {
   2615   1.4      haad 				if (zfs_prop_get_type(prop) != PROP_TYPE_STRING)
   2616  1.11       chs 					err = SET_ERROR(EINVAL);
   2617   1.4      haad 			} else if (nvpair_type(propval) == DATA_TYPE_UINT64) {
   2618   1.1      haad 				const char *unused;
   2619   1.1      haad 
   2620  1.11       chs 				intval = fnvpair_value_uint64(propval);
   2621   1.1      haad 
   2622   1.1      haad 				switch (zfs_prop_get_type(prop)) {
   2623   1.1      haad 				case PROP_TYPE_NUMBER:
   2624   1.1      haad 					break;
   2625   1.1      haad 				case PROP_TYPE_STRING:
   2626  1.11       chs 					err = SET_ERROR(EINVAL);
   2627   1.4      haad 					break;
   2628   1.1      haad 				case PROP_TYPE_INDEX:
   2629   1.1      haad 					if (zfs_prop_index_to_string(prop,
   2630   1.1      haad 					    intval, &unused) != 0)
   2631  1.11       chs 						err = SET_ERROR(EINVAL);
   2632   1.1      haad 					break;
   2633   1.1      haad 				default:
   2634   1.1      haad 					cmn_err(CE_PANIC,
   2635   1.1      haad 					    "unknown property type");
   2636   1.1      haad 				}
   2637   1.4      haad 			} else {
   2638  1.11       chs 				err = SET_ERROR(EINVAL);
   2639   1.4      haad 			}
   2640   1.4      haad 		}
   2641   1.4      haad 
   2642   1.4      haad 		/* Validate permissions */
   2643   1.4      haad 		if (err == 0)
   2644   1.4      haad 			err = zfs_check_settable(dsname, pair, CRED());
   2645   1.4      haad 
   2646   1.4      haad 		if (err == 0) {
   2647   1.4      haad 			err = zfs_prop_set_special(dsname, source, pair);
   2648   1.4      haad 			if (err == -1) {
   2649   1.4      haad 				/*
   2650   1.4      haad 				 * For better performance we build up a list of
   2651   1.4      haad 				 * properties to set in a single transaction.
   2652   1.4      haad 				 */
   2653   1.4      haad 				err = nvlist_add_nvpair(genericnvl, pair);
   2654   1.4      haad 			} else if (err != 0 && nvl != retrynvl) {
   2655   1.4      haad 				/*
   2656   1.4      haad 				 * This may be a spurious error caused by
   2657   1.4      haad 				 * receiving quota and reservation out of order.
   2658   1.4      haad 				 * Try again in a second pass.
   2659   1.4      haad 				 */
   2660   1.4      haad 				err = nvlist_add_nvpair(retrynvl, pair);
   2661   1.4      haad 			}
   2662   1.4      haad 		}
   2663   1.4      haad 
   2664  1.11       chs 		if (err != 0) {
   2665  1.11       chs 			if (errlist != NULL)
   2666  1.11       chs 				fnvlist_add_int32(errlist, propname, err);
   2667  1.11       chs 			rv = err;
   2668  1.11       chs 		}
   2669   1.4      haad 	}
   2670   1.4      haad 
   2671   1.4      haad 	if (nvl != retrynvl && !nvlist_empty(retrynvl)) {
   2672   1.4      haad 		nvl = retrynvl;
   2673   1.4      haad 		goto retry;
   2674   1.4      haad 	}
   2675   1.4      haad 
   2676   1.4      haad 	if (!nvlist_empty(genericnvl) &&
   2677   1.4      haad 	    dsl_props_set(dsname, source, genericnvl) != 0) {
   2678   1.4      haad 		/*
   2679   1.4      haad 		 * If this fails, we still want to set as many properties as we
   2680   1.4      haad 		 * can, so try setting them individually.
   2681   1.4      haad 		 */
   2682   1.4      haad 		pair = NULL;
   2683   1.4      haad 		while ((pair = nvlist_next_nvpair(genericnvl, pair)) != NULL) {
   2684   1.4      haad 			const char *propname = nvpair_name(pair);
   2685   1.4      haad 			int err = 0;
   2686   1.4      haad 
   2687   1.4      haad 			propval = pair;
   2688   1.4      haad 			if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
   2689   1.4      haad 				nvlist_t *attrs;
   2690  1.11       chs 				attrs = fnvpair_value_nvlist(pair);
   2691  1.11       chs 				propval = fnvlist_lookup_nvpair(attrs,
   2692  1.11       chs 				    ZPROP_VALUE);
   2693   1.4      haad 			}
   2694   1.1      haad 
   2695   1.4      haad 			if (nvpair_type(propval) == DATA_TYPE_STRING) {
   2696  1.11       chs 				strval = fnvpair_value_string(propval);
   2697  1.11       chs 				err = dsl_prop_set_string(dsname, propname,
   2698  1.11       chs 				    source, strval);
   2699   1.1      haad 			} else {
   2700  1.11       chs 				intval = fnvpair_value_uint64(propval);
   2701  1.11       chs 				err = dsl_prop_set_int(dsname, propname, source,
   2702  1.11       chs 				    intval);
   2703   1.4      haad 			}
   2704   1.4      haad 
   2705   1.4      haad 			if (err != 0) {
   2706  1.11       chs 				if (errlist != NULL) {
   2707  1.11       chs 					fnvlist_add_int32(errlist, propname,
   2708  1.11       chs 					    err);
   2709  1.11       chs 				}
   2710  1.11       chs 				rv = err;
   2711   1.1      haad 			}
   2712   1.1      haad 		}
   2713   1.1      haad 	}
   2714   1.4      haad 	nvlist_free(genericnvl);
   2715   1.4      haad 	nvlist_free(retrynvl);
   2716   1.4      haad 
   2717   1.4      haad 	return (rv);
   2718   1.4      haad }
   2719   1.4      haad 
   2720   1.4      haad /*
   2721   1.4      haad  * Check that all the properties are valid user properties.
   2722   1.4      haad  */
   2723   1.4      haad static int
   2724  1.11       chs zfs_check_userprops(const char *fsname, nvlist_t *nvl)
   2725   1.4      haad {
   2726   1.4      haad 	nvpair_t *pair = NULL;
   2727   1.4      haad 	int error = 0;
   2728   1.1      haad 
   2729   1.4      haad 	while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
   2730   1.4      haad 		const char *propname = nvpair_name(pair);
   2731   1.4      haad 
   2732   1.4      haad 		if (!zfs_prop_user(propname) ||
   2733   1.4      haad 		    nvpair_type(pair) != DATA_TYPE_STRING)
   2734  1.11       chs 			return (SET_ERROR(EINVAL));
   2735   1.4      haad 
   2736   1.4      haad 		if (error = zfs_secpolicy_write_perms(fsname,
   2737   1.4      haad 		    ZFS_DELEG_PERM_USERPROP, CRED()))
   2738   1.4      haad 			return (error);
   2739   1.4      haad 
   2740   1.4      haad 		if (strlen(propname) >= ZAP_MAXNAMELEN)
   2741  1.11       chs 			return (SET_ERROR(ENAMETOOLONG));
   2742   1.4      haad 
   2743  1.11       chs 		if (strlen(fnvpair_value_string(pair)) >= ZAP_MAXVALUELEN)
   2744   1.4      haad 			return (E2BIG);
   2745   1.4      haad 	}
   2746   1.1      haad 	return (0);
   2747   1.1      haad }
   2748   1.1      haad 
   2749   1.4      haad static void
   2750   1.4      haad props_skip(nvlist_t *props, nvlist_t *skipped, nvlist_t **newprops)
   2751   1.4      haad {
   2752   1.4      haad 	nvpair_t *pair;
   2753   1.4      haad 
   2754   1.4      haad 	VERIFY(nvlist_alloc(newprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   2755   1.4      haad 
   2756   1.4      haad 	pair = NULL;
   2757   1.4      haad 	while ((pair = nvlist_next_nvpair(props, pair)) != NULL) {
   2758   1.4      haad 		if (nvlist_exists(skipped, nvpair_name(pair)))
   2759   1.4      haad 			continue;
   2760   1.4      haad 
   2761   1.4      haad 		VERIFY(nvlist_add_nvpair(*newprops, pair) == 0);
   2762   1.4      haad 	}
   2763   1.4      haad }
   2764   1.4      haad 
   2765   1.4      haad static int
   2766  1.11       chs clear_received_props(const char *dsname, nvlist_t *props,
   2767   1.4      haad     nvlist_t *skipped)
   2768   1.4      haad {
   2769   1.4      haad 	int err = 0;
   2770   1.4      haad 	nvlist_t *cleared_props = NULL;
   2771   1.4      haad 	props_skip(props, skipped, &cleared_props);
   2772   1.4      haad 	if (!nvlist_empty(cleared_props)) {
   2773   1.4      haad 		/*
   2774   1.4      haad 		 * Acts on local properties until the dataset has received
   2775   1.4      haad 		 * properties at least once on or after SPA_VERSION_RECVD_PROPS.
   2776   1.4      haad 		 */
   2777   1.4      haad 		zprop_source_t flags = (ZPROP_SRC_NONE |
   2778  1.11       chs 		    (dsl_prop_get_hasrecvd(dsname) ? ZPROP_SRC_RECEIVED : 0));
   2779  1.11       chs 		err = zfs_set_prop_nvlist(dsname, flags, cleared_props, NULL);
   2780   1.4      haad 	}
   2781   1.4      haad 	nvlist_free(cleared_props);
   2782   1.4      haad 	return (err);
   2783   1.4      haad }
   2784   1.4      haad 
   2785   1.1      haad /*
   2786   1.1      haad  * inputs:
   2787   1.1      haad  * zc_name		name of filesystem
   2788   1.4      haad  * zc_value		name of property to set
   2789   1.1      haad  * zc_nvlist_src{_size}	nvlist of properties to apply
   2790   1.4      haad  * zc_cookie		received properties flag
   2791   1.1      haad  *
   2792   1.4      haad  * outputs:
   2793   1.4      haad  * zc_nvlist_dst{_size} error for each unapplied received property
   2794   1.1      haad  */
   2795   1.1      haad static int
   2796   1.1      haad zfs_ioc_set_prop(zfs_cmd_t *zc)
   2797   1.1      haad {
   2798   1.1      haad 	nvlist_t *nvl;
   2799   1.4      haad 	boolean_t received = zc->zc_cookie;
   2800   1.4      haad 	zprop_source_t source = (received ? ZPROP_SRC_RECEIVED :
   2801   1.4      haad 	    ZPROP_SRC_LOCAL);
   2802  1.11       chs 	nvlist_t *errors;
   2803   1.1      haad 	int error;
   2804   1.1      haad 
   2805   1.1      haad 	if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
   2806   1.4      haad 	    zc->zc_iflags, &nvl)) != 0)
   2807   1.1      haad 		return (error);
   2808   1.1      haad 
   2809   1.4      haad 	if (received) {
   2810   1.1      haad 		nvlist_t *origprops;
   2811   1.1      haad 
   2812  1.11       chs 		if (dsl_prop_get_received(zc->zc_name, &origprops) == 0) {
   2813  1.11       chs 			(void) clear_received_props(zc->zc_name,
   2814  1.11       chs 			    origprops, nvl);
   2815  1.11       chs 			nvlist_free(origprops);
   2816  1.11       chs 		}
   2817   1.4      haad 
   2818  1.11       chs 		error = dsl_prop_set_hasrecvd(zc->zc_name);
   2819   1.4      haad 	}
   2820   1.4      haad 
   2821  1.11       chs 	errors = fnvlist_alloc();
   2822  1.11       chs 	if (error == 0)
   2823  1.11       chs 		error = zfs_set_prop_nvlist(zc->zc_name, source, nvl, errors);
   2824   1.1      haad 
   2825  1.11       chs 	if (zc->zc_nvlist_dst != 0 && errors != NULL) {
   2826   1.4      haad 		(void) put_nvlist(zc, errors);
   2827   1.1      haad 	}
   2828   1.1      haad 
   2829   1.4      haad 	nvlist_free(errors);
   2830   1.1      haad 	nvlist_free(nvl);
   2831   1.1      haad 	return (error);
   2832   1.1      haad }
   2833   1.1      haad 
   2834   1.1      haad /*
   2835   1.1      haad  * inputs:
   2836   1.1      haad  * zc_name		name of filesystem
   2837   1.1      haad  * zc_value		name of property to inherit
   2838   1.4      haad  * zc_cookie		revert to received value if TRUE
   2839   1.1      haad  *
   2840   1.1      haad  * outputs:		none
   2841   1.1      haad  */
   2842   1.1      haad static int
   2843   1.1      haad zfs_ioc_inherit_prop(zfs_cmd_t *zc)
   2844   1.1      haad {
   2845   1.4      haad 	const char *propname = zc->zc_value;
   2846   1.4      haad 	zfs_prop_t prop = zfs_name_to_prop(propname);
   2847   1.4      haad 	boolean_t received = zc->zc_cookie;
   2848   1.4      haad 	zprop_source_t source = (received
   2849   1.4      haad 	    ? ZPROP_SRC_NONE		/* revert to received value, if any */
   2850   1.4      haad 	    : ZPROP_SRC_INHERITED);	/* explicitly inherit */
   2851   1.4      haad 
   2852   1.4      haad 	if (received) {
   2853   1.4      haad 		nvlist_t *dummy;
   2854   1.4      haad 		nvpair_t *pair;
   2855   1.4      haad 		zprop_type_t type;
   2856   1.4      haad 		int err;
   2857   1.4      haad 
   2858   1.4      haad 		/*
   2859   1.4      haad 		 * zfs_prop_set_special() expects properties in the form of an
   2860   1.4      haad 		 * nvpair with type info.
   2861   1.4      haad 		 */
   2862   1.4      haad 		if (prop == ZPROP_INVAL) {
   2863   1.4      haad 			if (!zfs_prop_user(propname))
   2864  1.11       chs 				return (SET_ERROR(EINVAL));
   2865   1.4      haad 
   2866   1.4      haad 			type = PROP_TYPE_STRING;
   2867   1.4      haad 		} else if (prop == ZFS_PROP_VOLSIZE ||
   2868   1.4      haad 		    prop == ZFS_PROP_VERSION) {
   2869  1.11       chs 			return (SET_ERROR(EINVAL));
   2870   1.4      haad 		} else {
   2871   1.4      haad 			type = zfs_prop_get_type(prop);
   2872   1.4      haad 		}
   2873   1.4      haad 
   2874   1.4      haad 		VERIFY(nvlist_alloc(&dummy, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   2875   1.4      haad 
   2876   1.4      haad 		switch (type) {
   2877   1.4      haad 		case PROP_TYPE_STRING:
   2878   1.4      haad 			VERIFY(0 == nvlist_add_string(dummy, propname, ""));
   2879   1.4      haad 			break;
   2880   1.4      haad 		case PROP_TYPE_NUMBER:
   2881   1.4      haad 		case PROP_TYPE_INDEX:
   2882   1.4      haad 			VERIFY(0 == nvlist_add_uint64(dummy, propname, 0));
   2883   1.4      haad 			break;
   2884   1.4      haad 		default:
   2885   1.4      haad 			nvlist_free(dummy);
   2886  1.11       chs 			return (SET_ERROR(EINVAL));
   2887   1.4      haad 		}
   2888   1.4      haad 
   2889   1.4      haad 		pair = nvlist_next_nvpair(dummy, NULL);
   2890   1.4      haad 		err = zfs_prop_set_special(zc->zc_name, source, pair);
   2891   1.4      haad 		nvlist_free(dummy);
   2892   1.4      haad 		if (err != -1)
   2893   1.4      haad 			return (err); /* special property already handled */
   2894   1.4      haad 	} else {
   2895   1.4      haad 		/*
   2896   1.4      haad 		 * Only check this in the non-received case. We want to allow
   2897   1.4      haad 		 * 'inherit -S' to revert non-inheritable properties like quota
   2898   1.4      haad 		 * and reservation to the received or default values even though
   2899   1.4      haad 		 * they are not considered inheritable.
   2900   1.4      haad 		 */
   2901   1.4      haad 		if (prop != ZPROP_INVAL && !zfs_prop_inheritable(prop))
   2902  1.11       chs 			return (SET_ERROR(EINVAL));
   2903   1.4      haad 	}
   2904   1.4      haad 
   2905  1.11       chs 	/* property name has been validated by zfs_secpolicy_inherit_prop() */
   2906  1.11       chs 	return (dsl_prop_inherit(zc->zc_name, zc->zc_value, source));
   2907   1.1      haad }
   2908   1.1      haad 
   2909   1.1      haad static int
   2910   1.1      haad zfs_ioc_pool_set_props(zfs_cmd_t *zc)
   2911   1.1      haad {
   2912   1.1      haad 	nvlist_t *props;
   2913   1.1      haad 	spa_t *spa;
   2914   1.1      haad 	int error;
   2915   1.4      haad 	nvpair_t *pair;
   2916   1.1      haad 
   2917   1.4      haad 	if (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
   2918   1.4      haad 	    zc->zc_iflags, &props))
   2919   1.1      haad 		return (error);
   2920   1.1      haad 
   2921   1.4      haad 	/*
   2922   1.4      haad 	 * If the only property is the configfile, then just do a spa_lookup()
   2923   1.4      haad 	 * to handle the faulted case.
   2924   1.4      haad 	 */
   2925   1.4      haad 	pair = nvlist_next_nvpair(props, NULL);
   2926   1.4      haad 	if (pair != NULL && strcmp(nvpair_name(pair),
   2927   1.4      haad 	    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE)) == 0 &&
   2928   1.4      haad 	    nvlist_next_nvpair(props, pair) == NULL) {
   2929   1.4      haad 		mutex_enter(&spa_namespace_lock);
   2930   1.4      haad 		if ((spa = spa_lookup(zc->zc_name)) != NULL) {
   2931   1.4      haad 			spa_configfile_set(spa, props, B_FALSE);
   2932   1.4      haad 			spa_config_sync(spa, B_FALSE, B_TRUE);
   2933   1.4      haad 		}
   2934   1.4      haad 		mutex_exit(&spa_namespace_lock);
   2935   1.4      haad 		if (spa != NULL) {
   2936   1.4      haad 			nvlist_free(props);
   2937   1.4      haad 			return (0);
   2938   1.4      haad 		}
   2939   1.4      haad 	}
   2940   1.4      haad 
   2941   1.1      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
   2942   1.1      haad 		nvlist_free(props);
   2943   1.1      haad 		return (error);
   2944   1.1      haad 	}
   2945   1.1      haad 
   2946   1.1      haad 	error = spa_prop_set(spa, props);
   2947   1.1      haad 
   2948   1.1      haad 	nvlist_free(props);
   2949   1.1      haad 	spa_close(spa, FTAG);
   2950   1.1      haad 
   2951   1.1      haad 	return (error);
   2952   1.1      haad }
   2953   1.1      haad 
   2954   1.1      haad static int
   2955   1.1      haad zfs_ioc_pool_get_props(zfs_cmd_t *zc)
   2956   1.1      haad {
   2957   1.1      haad 	spa_t *spa;
   2958   1.1      haad 	int error;
   2959   1.1      haad 	nvlist_t *nvp = NULL;
   2960   1.1      haad 
   2961   1.4      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
   2962   1.4      haad 		/*
   2963   1.4      haad 		 * If the pool is faulted, there may be properties we can still
   2964   1.4      haad 		 * get (such as altroot and cachefile), so attempt to get them
   2965   1.4      haad 		 * anyway.
   2966   1.4      haad 		 */
   2967   1.4      haad 		mutex_enter(&spa_namespace_lock);
   2968   1.4      haad 		if ((spa = spa_lookup(zc->zc_name)) != NULL)
   2969   1.4      haad 			error = spa_prop_get(spa, &nvp);
   2970   1.4      haad 		mutex_exit(&spa_namespace_lock);
   2971   1.4      haad 	} else {
   2972   1.4      haad 		error = spa_prop_get(spa, &nvp);
   2973   1.4      haad 		spa_close(spa, FTAG);
   2974   1.4      haad 	}
   2975   1.1      haad 
   2976   1.8  christos 	if (error == 0 && zc->zc_nvlist_dst != 0)
   2977   1.1      haad 		error = put_nvlist(zc, nvp);
   2978   1.1      haad 	else
   2979  1.11       chs 		error = SET_ERROR(EFAULT);
   2980   1.1      haad 
   2981   1.1      haad 	nvlist_free(nvp);
   2982   1.1      haad 	return (error);
   2983   1.1      haad }
   2984   1.1      haad 
   2985   1.1      haad /*
   2986   1.1      haad  * inputs:
   2987   1.1      haad  * zc_name		name of filesystem
   2988   1.1      haad  * zc_nvlist_src{_size}	nvlist of delegated permissions
   2989   1.1      haad  * zc_perm_action	allow/unallow flag
   2990   1.1      haad  *
   2991   1.1      haad  * outputs:		none
   2992   1.1      haad  */
   2993   1.1      haad static int
   2994   1.1      haad zfs_ioc_set_fsacl(zfs_cmd_t *zc)
   2995   1.1      haad {
   2996   1.1      haad 	int error;
   2997   1.1      haad 	nvlist_t *fsaclnv = NULL;
   2998   1.1      haad 
   2999   1.1      haad 	if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
   3000   1.4      haad 	    zc->zc_iflags, &fsaclnv)) != 0)
   3001   1.1      haad 		return (error);
   3002   1.1      haad 
   3003   1.1      haad 	/*
   3004   1.1      haad 	 * Verify nvlist is constructed correctly
   3005   1.1      haad 	 */
   3006   1.1      haad 	if ((error = zfs_deleg_verify_nvlist(fsaclnv)) != 0) {
   3007   1.1      haad 		nvlist_free(fsaclnv);
   3008  1.11       chs 		return (SET_ERROR(EINVAL));
   3009   1.1      haad 	}
   3010   1.1      haad 
   3011   1.1      haad 	/*
   3012   1.1      haad 	 * If we don't have PRIV_SYS_MOUNT, then validate
   3013   1.1      haad 	 * that user is allowed to hand out each permission in
   3014   1.1      haad 	 * the nvlist(s)
   3015   1.1      haad 	 */
   3016   1.1      haad 
   3017   1.1      haad 	error = secpolicy_zfs(CRED());
   3018  1.11       chs 	if (error != 0) {
   3019   1.1      haad 		if (zc->zc_perm_action == B_FALSE) {
   3020   1.1      haad 			error = dsl_deleg_can_allow(zc->zc_name,
   3021   1.1      haad 			    fsaclnv, CRED());
   3022   1.1      haad 		} else {
   3023   1.1      haad 			error = dsl_deleg_can_unallow(zc->zc_name,
   3024   1.1      haad 			    fsaclnv, CRED());
   3025   1.1      haad 		}
   3026   1.1      haad 	}
   3027   1.1      haad 
   3028   1.1      haad 	if (error == 0)
   3029   1.1      haad 		error = dsl_deleg_set(zc->zc_name, fsaclnv, zc->zc_perm_action);
   3030   1.1      haad 
   3031   1.1      haad 	nvlist_free(fsaclnv);
   3032   1.1      haad 	return (error);
   3033   1.1      haad }
   3034   1.1      haad 
   3035   1.1      haad /*
   3036   1.1      haad  * inputs:
   3037   1.1      haad  * zc_name		name of filesystem
   3038   1.1      haad  *
   3039   1.1      haad  * outputs:
   3040   1.1      haad  * zc_nvlist_src{_size}	nvlist of delegated permissions
   3041   1.1      haad  */
   3042   1.1      haad static int
   3043   1.1      haad zfs_ioc_get_fsacl(zfs_cmd_t *zc)
   3044   1.1      haad {
   3045   1.1      haad 	nvlist_t *nvp;
   3046   1.1      haad 	int error;
   3047   1.1      haad 
   3048   1.1      haad 	if ((error = dsl_deleg_get(zc->zc_name, &nvp)) == 0) {
   3049   1.1      haad 		error = put_nvlist(zc, nvp);
   3050   1.1      haad 		nvlist_free(nvp);
   3051   1.1      haad 	}
   3052   1.1      haad 
   3053   1.1      haad 	return (error);
   3054   1.1      haad }
   3055   1.1      haad 
   3056   1.1      haad /*
   3057   1.1      haad  * Search the vfs list for a specified resource.  Returns a pointer to it
   3058   1.1      haad  * or NULL if no suitable entry is found. The caller of this routine
   3059   1.1      haad  * is responsible for releasing the returned vfs pointer.
   3060   1.1      haad  */
   3061   1.1      haad static vfs_t *
   3062   1.1      haad zfs_get_vfs(const char *resource)
   3063   1.1      haad {
   3064  1.11       chs 	vfs_t *vfsp;
   3065  1.11       chs 
   3066  1.11       chs #ifdef __FreeBSD__
   3067  1.11       chs 	mtx_lock(&mountlist_mtx);
   3068  1.11       chs 	TAILQ_FOREACH(vfsp, &mountlist, mnt_list) {
   3069  1.11       chs 		if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) {
   3070  1.11       chs 			if (vfs_busy(vfsp, MBF_MNTLSTLOCK) != 0)
   3071  1.11       chs 				vfsp = NULL;
   3072  1.11       chs 			break;
   3073  1.11       chs 		}
   3074  1.11       chs 	}
   3075  1.11       chs 	if (vfsp == NULL)
   3076  1.11       chs 		mtx_unlock(&mountlist_mtx);
   3077  1.11       chs #endif
   3078  1.11       chs #ifdef __NetBSD__
   3079  1.25    simonb 	mount_iterator_t *iter;
   3080  1.11       chs 
   3081  1.11       chs 	mountlist_iterator_init(&iter);
   3082  1.11       chs 	while ((vfsp = mountlist_iterator_next(iter)) != NULL) {
   3083  1.11       chs 		if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) {
   3084  1.11       chs 			if (vfs_busy(vfsp, 0) != 0)
   3085  1.11       chs 				vfsp = NULL;
   3086  1.11       chs 			break;
   3087  1.11       chs 		}
   3088  1.11       chs 	}
   3089  1.11       chs 	mountlist_iterator_destroy(iter);
   3090  1.11       chs #endif
   3091   1.1      haad 
   3092  1.11       chs 	return (vfsp);
   3093   1.1      haad }
   3094   1.1      haad 
   3095   1.1      haad /* ARGSUSED */
   3096   1.1      haad static void
   3097   1.1      haad zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
   3098   1.1      haad {
   3099   1.1      haad 	zfs_creat_t *zct = arg;
   3100   1.1      haad 
   3101   1.1      haad 	zfs_create_fs(os, cr, zct->zct_zplprops, tx);
   3102   1.1      haad }
   3103   1.1      haad 
   3104   1.1      haad #define	ZFS_PROP_UNDEFINED	((uint64_t)-1)
   3105   1.1      haad 
   3106   1.1      haad /*
   3107   1.1      haad  * inputs:
   3108  1.11       chs  * os			parent objset pointer (NULL if root fs)
   3109  1.11       chs  * fuids_ok		fuids allowed in this version of the spa?
   3110  1.11       chs  * sa_ok		SAs allowed in this version of the spa?
   3111   1.1      haad  * createprops		list of properties requested by creator
   3112   1.1      haad  *
   3113   1.1      haad  * outputs:
   3114   1.1      haad  * zplprops	values for the zplprops we attach to the master node object
   3115   1.1      haad  * is_ci	true if requested file system will be purely case-insensitive
   3116   1.1      haad  *
   3117   1.1      haad  * Determine the settings for utf8only, normalization and
   3118   1.1      haad  * casesensitivity.  Specific values may have been requested by the
   3119   1.1      haad  * creator and/or we can inherit values from the parent dataset.  If
   3120   1.1      haad  * the file system is of too early a vintage, a creator can not
   3121   1.1      haad  * request settings for these properties, even if the requested
   3122   1.1      haad  * setting is the default value.  We don't actually want to create dsl
   3123   1.1      haad  * properties for these, so remove them from the source nvlist after
   3124   1.1      haad  * processing.
   3125   1.1      haad  */
   3126   1.1      haad static int
   3127   1.4      haad zfs_fill_zplprops_impl(objset_t *os, uint64_t zplver,
   3128  1.11       chs     boolean_t fuids_ok, boolean_t sa_ok, nvlist_t *createprops,
   3129  1.11       chs     nvlist_t *zplprops, boolean_t *is_ci)
   3130   1.1      haad {
   3131   1.1      haad 	uint64_t sense = ZFS_PROP_UNDEFINED;
   3132   1.1      haad 	uint64_t norm = ZFS_PROP_UNDEFINED;
   3133   1.1      haad 	uint64_t u8 = ZFS_PROP_UNDEFINED;
   3134   1.1      haad 
   3135   1.1      haad 	ASSERT(zplprops != NULL);
   3136   1.1      haad 
   3137   1.1      haad 	/*
   3138   1.1      haad 	 * Pull out creator prop choices, if any.
   3139   1.1      haad 	 */
   3140   1.1      haad 	if (createprops) {
   3141   1.1      haad 		(void) nvlist_lookup_uint64(createprops,
   3142   1.1      haad 		    zfs_prop_to_name(ZFS_PROP_VERSION), &zplver);
   3143   1.1      haad 		(void) nvlist_lookup_uint64(createprops,
   3144   1.1      haad 		    zfs_prop_to_name(ZFS_PROP_NORMALIZE), &norm);
   3145   1.1      haad 		(void) nvlist_remove_all(createprops,
   3146   1.1      haad 		    zfs_prop_to_name(ZFS_PROP_NORMALIZE));
   3147   1.1      haad 		(void) nvlist_lookup_uint64(createprops,
   3148   1.1      haad 		    zfs_prop_to_name(ZFS_PROP_UTF8ONLY), &u8);
   3149   1.1      haad 		(void) nvlist_remove_all(createprops,
   3150   1.1      haad 		    zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
   3151   1.1      haad 		(void) nvlist_lookup_uint64(createprops,
   3152   1.1      haad 		    zfs_prop_to_name(ZFS_PROP_CASE), &sense);
   3153   1.1      haad 		(void) nvlist_remove_all(createprops,
   3154   1.1      haad 		    zfs_prop_to_name(ZFS_PROP_CASE));
   3155   1.1      haad 	}
   3156   1.1      haad 
   3157   1.1      haad 	/*
   3158   1.1      haad 	 * If the zpl version requested is whacky or the file system
   3159   1.1      haad 	 * or pool is version is too "young" to support normalization
   3160   1.1      haad 	 * and the creator tried to set a value for one of the props,
   3161   1.1      haad 	 * error out.
   3162   1.1      haad 	 */
   3163   1.1      haad 	if ((zplver < ZPL_VERSION_INITIAL || zplver > ZPL_VERSION) ||
   3164   1.1      haad 	    (zplver >= ZPL_VERSION_FUID && !fuids_ok) ||
   3165  1.11       chs 	    (zplver >= ZPL_VERSION_SA && !sa_ok) ||
   3166   1.1      haad 	    (zplver < ZPL_VERSION_NORMALIZATION &&
   3167   1.1      haad 	    (norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED ||
   3168   1.1      haad 	    sense != ZFS_PROP_UNDEFINED)))
   3169  1.11       chs 		return (SET_ERROR(ENOTSUP));
   3170   1.1      haad 
   3171   1.1      haad 	/*
   3172   1.1      haad 	 * Put the version in the zplprops
   3173   1.1      haad 	 */
   3174   1.1      haad 	VERIFY(nvlist_add_uint64(zplprops,
   3175   1.1      haad 	    zfs_prop_to_name(ZFS_PROP_VERSION), zplver) == 0);
   3176   1.1      haad 
   3177   1.1      haad 	if (norm == ZFS_PROP_UNDEFINED)
   3178   1.1      haad 		VERIFY(zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &norm) == 0);
   3179   1.1      haad 	VERIFY(nvlist_add_uint64(zplprops,
   3180   1.1      haad 	    zfs_prop_to_name(ZFS_PROP_NORMALIZE), norm) == 0);
   3181   1.1      haad 
   3182   1.1      haad 	/*
   3183   1.1      haad 	 * If we're normalizing, names must always be valid UTF-8 strings.
   3184   1.1      haad 	 */
   3185   1.1      haad 	if (norm)
   3186   1.1      haad 		u8 = 1;
   3187   1.1      haad 	if (u8 == ZFS_PROP_UNDEFINED)
   3188   1.1      haad 		VERIFY(zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &u8) == 0);
   3189   1.1      haad 	VERIFY(nvlist_add_uint64(zplprops,
   3190   1.1      haad 	    zfs_prop_to_name(ZFS_PROP_UTF8ONLY), u8) == 0);
   3191   1.1      haad 
   3192   1.1      haad 	if (sense == ZFS_PROP_UNDEFINED)
   3193   1.1      haad 		VERIFY(zfs_get_zplprop(os, ZFS_PROP_CASE, &sense) == 0);
   3194   1.1      haad 	VERIFY(nvlist_add_uint64(zplprops,
   3195   1.1      haad 	    zfs_prop_to_name(ZFS_PROP_CASE), sense) == 0);
   3196   1.1      haad 
   3197   1.1      haad 	if (is_ci)
   3198   1.1      haad 		*is_ci = (sense == ZFS_CASE_INSENSITIVE);
   3199   1.1      haad 
   3200   1.1      haad 	return (0);
   3201   1.1      haad }
   3202   1.1      haad 
   3203   1.1      haad static int
   3204   1.1      haad zfs_fill_zplprops(const char *dataset, nvlist_t *createprops,
   3205   1.1      haad     nvlist_t *zplprops, boolean_t *is_ci)
   3206   1.1      haad {
   3207  1.11       chs 	boolean_t fuids_ok, sa_ok;
   3208   1.1      haad 	uint64_t zplver = ZPL_VERSION;
   3209   1.1      haad 	objset_t *os = NULL;
   3210  1.11       chs 	char parentname[ZFS_MAX_DATASET_NAME_LEN];
   3211   1.1      haad 	char *cp;
   3212  1.11       chs 	spa_t *spa;
   3213  1.11       chs 	uint64_t spa_vers;
   3214   1.1      haad 	int error;
   3215   1.1      haad 
   3216   1.1      haad 	(void) strlcpy(parentname, dataset, sizeof (parentname));
   3217   1.1      haad 	cp = strrchr(parentname, '/');
   3218   1.1      haad 	ASSERT(cp != NULL);
   3219   1.1      haad 	cp[0] = '\0';
   3220   1.1      haad 
   3221  1.11       chs 	if ((error = spa_open(dataset, &spa, FTAG)) != 0)
   3222  1.11       chs 		return (error);
   3223  1.11       chs 
   3224  1.11       chs 	spa_vers = spa_version(spa);
   3225  1.11       chs 	spa_close(spa, FTAG);
   3226  1.11       chs 
   3227  1.11       chs 	zplver = zfs_zpl_version_map(spa_vers);
   3228  1.11       chs 	fuids_ok = (zplver >= ZPL_VERSION_FUID);
   3229  1.11       chs 	sa_ok = (zplver >= ZPL_VERSION_SA);
   3230   1.1      haad 
   3231   1.1      haad 	/*
   3232   1.1      haad 	 * Open parent object set so we can inherit zplprop values.
   3233   1.1      haad 	 */
   3234   1.4      haad 	if ((error = dmu_objset_hold(parentname, FTAG, &os)) != 0)
   3235   1.1      haad 		return (error);
   3236   1.1      haad 
   3237  1.11       chs 	error = zfs_fill_zplprops_impl(os, zplver, fuids_ok, sa_ok, createprops,
   3238   1.1      haad 	    zplprops, is_ci);
   3239   1.4      haad 	dmu_objset_rele(os, FTAG);
   3240   1.1      haad 	return (error);
   3241   1.1      haad }
   3242   1.1      haad 
   3243   1.1      haad static int
   3244   1.1      haad zfs_fill_zplprops_root(uint64_t spa_vers, nvlist_t *createprops,
   3245   1.1      haad     nvlist_t *zplprops, boolean_t *is_ci)
   3246   1.1      haad {
   3247  1.11       chs 	boolean_t fuids_ok;
   3248  1.11       chs 	boolean_t sa_ok;
   3249   1.1      haad 	uint64_t zplver = ZPL_VERSION;
   3250   1.1      haad 	int error;
   3251   1.1      haad 
   3252  1.11       chs 	zplver = zfs_zpl_version_map(spa_vers);
   3253  1.11       chs 	fuids_ok = (zplver >= ZPL_VERSION_FUID);
   3254  1.11       chs 	sa_ok = (zplver >= ZPL_VERSION_SA);
   3255   1.1      haad 
   3256  1.11       chs 	error = zfs_fill_zplprops_impl(NULL, zplver, fuids_ok, sa_ok,
   3257  1.11       chs 	    createprops, zplprops, is_ci);
   3258   1.1      haad 	return (error);
   3259   1.1      haad }
   3260   1.1      haad 
   3261   1.1      haad /*
   3262  1.11       chs  * innvl: {
   3263  1.11       chs  *     "type" -> dmu_objset_type_t (int32)
   3264  1.11       chs  *     (optional) "props" -> { prop -> value }
   3265  1.11       chs  * }
   3266   1.1      haad  *
   3267  1.11       chs  * outnvl: propname -> error code (int32)
   3268   1.1      haad  */
   3269   1.1      haad static int
   3270  1.11       chs zfs_ioc_create(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
   3271   1.1      haad {
   3272   1.1      haad 	int error = 0;
   3273  1.11       chs 	zfs_creat_t zct = { 0 };
   3274   1.1      haad 	nvlist_t *nvprops = NULL;
   3275   1.1      haad 	void (*cbfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
   3276  1.11       chs 	int32_t type32;
   3277  1.11       chs 	dmu_objset_type_t type;
   3278  1.11       chs 	boolean_t is_insensitive = B_FALSE;
   3279  1.11       chs 
   3280  1.11       chs 	if (nvlist_lookup_int32(innvl, "type", &type32) != 0)
   3281  1.11       chs 		return (SET_ERROR(EINVAL));
   3282  1.11       chs 	type = type32;
   3283  1.11       chs 	(void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
   3284   1.1      haad 
   3285   1.1      haad 	switch (type) {
   3286   1.1      haad 	case DMU_OST_ZFS:
   3287   1.1      haad 		cbfunc = zfs_create_cb;
   3288   1.1      haad 		break;
   3289   1.1      haad 
   3290   1.1      haad 	case DMU_OST_ZVOL:
   3291   1.1      haad 		cbfunc = zvol_create_cb;
   3292   1.1      haad 		break;
   3293   1.1      haad 
   3294   1.1      haad 	default:
   3295   1.1      haad 		cbfunc = NULL;
   3296   1.1      haad 		break;
   3297   1.1      haad 	}
   3298  1.11       chs 	if (strchr(fsname, '@') ||
   3299  1.11       chs 	    strchr(fsname, '%'))
   3300  1.11       chs 		return (SET_ERROR(EINVAL));
   3301   1.1      haad 
   3302   1.1      haad 	zct.zct_props = nvprops;
   3303   1.1      haad 
   3304  1.11       chs 	if (cbfunc == NULL)
   3305  1.11       chs 		return (SET_ERROR(EINVAL));
   3306   1.1      haad 
   3307  1.11       chs 	if (type == DMU_OST_ZVOL) {
   3308  1.11       chs 		uint64_t volsize, volblocksize;
   3309   1.1      haad 
   3310  1.11       chs 		if (nvprops == NULL)
   3311  1.11       chs 			return (SET_ERROR(EINVAL));
   3312  1.11       chs 		if (nvlist_lookup_uint64(nvprops,
   3313  1.11       chs 		    zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) != 0)
   3314  1.11       chs 			return (SET_ERROR(EINVAL));
   3315  1.11       chs 
   3316  1.11       chs 		if ((error = nvlist_lookup_uint64(nvprops,
   3317  1.11       chs 		    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
   3318  1.11       chs 		    &volblocksize)) != 0 && error != ENOENT)
   3319  1.11       chs 			return (SET_ERROR(EINVAL));
   3320   1.1      haad 
   3321  1.11       chs 		if (error != 0)
   3322  1.11       chs 			volblocksize = zfs_prop_default_numeric(
   3323  1.11       chs 			    ZFS_PROP_VOLBLOCKSIZE);
   3324   1.1      haad 
   3325  1.11       chs 		if ((error = zvol_check_volblocksize(
   3326  1.11       chs 		    volblocksize)) != 0 ||
   3327  1.11       chs 		    (error = zvol_check_volsize(volsize,
   3328  1.11       chs 		    volblocksize)) != 0)
   3329  1.11       chs 			return (error);
   3330  1.11       chs 	} else if (type == DMU_OST_ZFS) {
   3331  1.11       chs 		int error;
   3332   1.1      haad 
   3333  1.11       chs 		/*
   3334  1.11       chs 		 * We have to have normalization and
   3335  1.11       chs 		 * case-folding flags correct when we do the
   3336  1.11       chs 		 * file system creation, so go figure them out
   3337  1.11       chs 		 * now.
   3338  1.11       chs 		 */
   3339  1.11       chs 		VERIFY(nvlist_alloc(&zct.zct_zplprops,
   3340  1.11       chs 		    NV_UNIQUE_NAME, KM_SLEEP) == 0);
   3341  1.11       chs 		error = zfs_fill_zplprops(fsname, nvprops,
   3342  1.11       chs 		    zct.zct_zplprops, &is_insensitive);
   3343  1.11       chs 		if (error != 0) {
   3344  1.11       chs 			nvlist_free(zct.zct_zplprops);
   3345  1.11       chs 			return (error);
   3346   1.1      haad 		}
   3347   1.1      haad 	}
   3348   1.1      haad 
   3349  1.11       chs 	error = dmu_objset_create(fsname, type,
   3350  1.11       chs 	    is_insensitive ? DS_FLAG_CI_DATASET : 0, cbfunc, &zct);
   3351  1.11       chs 	nvlist_free(zct.zct_zplprops);
   3352  1.11       chs 
   3353   1.1      haad 	/*
   3354   1.1      haad 	 * It would be nice to do this atomically.
   3355   1.1      haad 	 */
   3356   1.1      haad 	if (error == 0) {
   3357  1.11       chs 		error = zfs_set_prop_nvlist(fsname, ZPROP_SRC_LOCAL,
   3358  1.11       chs 		    nvprops, outnvl);
   3359   1.4      haad 		if (error != 0)
   3360  1.11       chs 			(void) dsl_destroy_head(fsname);
   3361   1.1      haad 	}
   3362  1.11       chs 	if (error == 0 && type == DMU_OST_ZVOL)
   3363  1.11       chs 		zvol_create_minors(fsname);
   3364   1.1      haad 	return (error);
   3365   1.1      haad }
   3366   1.1      haad 
   3367   1.1      haad /*
   3368  1.11       chs  * innvl: {
   3369  1.11       chs  *     "origin" -> name of origin snapshot
   3370  1.11       chs  *     (optional) "props" -> { prop -> value }
   3371  1.11       chs  * }
   3372   1.1      haad  *
   3373  1.11       chs  * outnvl: propname -> error code (int32)
   3374   1.1      haad  */
   3375   1.1      haad static int
   3376  1.11       chs zfs_ioc_clone(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
   3377   1.1      haad {
   3378  1.11       chs 	int error = 0;
   3379   1.1      haad 	nvlist_t *nvprops = NULL;
   3380  1.11       chs 	char *origin_name;
   3381   1.1      haad 
   3382  1.11       chs 	if (nvlist_lookup_string(innvl, "origin", &origin_name) != 0)
   3383  1.11       chs 		return (SET_ERROR(EINVAL));
   3384  1.11       chs 	(void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
   3385  1.11       chs 
   3386  1.11       chs 	if (strchr(fsname, '@') ||
   3387  1.11       chs 	    strchr(fsname, '%'))
   3388  1.11       chs 		return (SET_ERROR(EINVAL));
   3389  1.11       chs 
   3390  1.11       chs 	if (dataset_namecheck(origin_name, NULL, NULL) != 0)
   3391  1.11       chs 		return (SET_ERROR(EINVAL));
   3392  1.11       chs 	error = dmu_objset_clone(fsname, origin_name);
   3393  1.11       chs 	if (error != 0)
   3394   1.1      haad 		return (error);
   3395   1.1      haad 
   3396  1.11       chs 	/*
   3397  1.11       chs 	 * It would be nice to do this atomically.
   3398  1.11       chs 	 */
   3399  1.11       chs 	if (error == 0) {
   3400  1.11       chs 		error = zfs_set_prop_nvlist(fsname, ZPROP_SRC_LOCAL,
   3401  1.11       chs 		    nvprops, outnvl);
   3402  1.11       chs 		if (error != 0)
   3403  1.11       chs 			(void) dsl_destroy_head(fsname);
   3404   1.1      haad 	}
   3405  1.11       chs 	if (error == 0)
   3406  1.11       chs 		zvol_create_minors(fsname);
   3407   1.1      haad 	return (error);
   3408   1.1      haad }
   3409   1.1      haad 
   3410  1.11       chs /*
   3411  1.11       chs  * innvl: {
   3412  1.11       chs  *     "snaps" -> { snapshot1, snapshot2 }
   3413  1.11       chs  *     (optional) "props" -> { prop -> value (string) }
   3414  1.11       chs  * }
   3415  1.11       chs  *
   3416  1.11       chs  * outnvl: snapshot -> error code (int32)
   3417  1.11       chs  */
   3418  1.11       chs static int
   3419  1.11       chs zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
   3420   1.1      haad {
   3421  1.11       chs 	nvlist_t *snaps;
   3422  1.11       chs 	nvlist_t *props = NULL;
   3423  1.11       chs 	int error, poollen;
   3424  1.11       chs 	nvpair_t *pair;
   3425   1.1      haad 
   3426  1.11       chs 	(void) nvlist_lookup_nvlist(innvl, "props", &props);
   3427  1.11       chs 	if ((error = zfs_check_userprops(poolname, props)) != 0)
   3428  1.11       chs 		return (error);
   3429   1.1      haad 
   3430  1.11       chs 	if (!nvlist_empty(props) &&
   3431  1.11       chs 	    zfs_earlier_version(poolname, SPA_VERSION_SNAP_PROPS))
   3432  1.11       chs 		return (SET_ERROR(ENOTSUP));
   3433  1.11       chs 
   3434  1.11       chs 	if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
   3435  1.11       chs 		return (SET_ERROR(EINVAL));
   3436  1.11       chs 	poollen = strlen(poolname);
   3437  1.11       chs 	for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
   3438  1.11       chs 	    pair = nvlist_next_nvpair(snaps, pair)) {
   3439  1.11       chs 		const char *name = nvpair_name(pair);
   3440  1.11       chs 		const char *cp = strchr(name, '@');
   3441   1.2      haad 
   3442   1.1      haad 		/*
   3443  1.11       chs 		 * The snap name must contain an @, and the part after it must
   3444  1.11       chs 		 * contain only valid characters.
   3445   1.1      haad 		 */
   3446  1.11       chs 		if (cp == NULL ||
   3447  1.11       chs 		    zfs_component_namecheck(cp + 1, NULL, NULL) != 0)
   3448  1.11       chs 			return (SET_ERROR(EINVAL));
   3449   1.1      haad 
   3450  1.11       chs 		/*
   3451  1.11       chs 		 * The snap must be in the specified pool.
   3452  1.11       chs 		 */
   3453  1.11       chs 		if (strncmp(name, poolname, poollen) != 0 ||
   3454  1.11       chs 		    (name[poollen] != '/' && name[poollen] != '@'))
   3455  1.11       chs 			return (SET_ERROR(EXDEV));
   3456  1.11       chs 
   3457  1.11       chs 		/* This must be the only snap of this fs. */
   3458  1.11       chs 		for (nvpair_t *pair2 = nvlist_next_nvpair(snaps, pair);
   3459  1.11       chs 		    pair2 != NULL; pair2 = nvlist_next_nvpair(snaps, pair2)) {
   3460  1.11       chs 			if (strncmp(name, nvpair_name(pair2), cp - name + 1)
   3461  1.11       chs 			    == 0) {
   3462  1.11       chs 				return (SET_ERROR(EXDEV));
   3463  1.11       chs 			}
   3464   1.1      haad 		}
   3465   1.1      haad 	}
   3466  1.11       chs 
   3467  1.11       chs 	error = dsl_dataset_snapshot(snaps, props, outnvl);
   3468  1.11       chs 	return (error);
   3469   1.1      haad }
   3470   1.1      haad 
   3471   1.1      haad /*
   3472  1.11       chs  * innvl: "message" -> string
   3473   1.1      haad  */
   3474  1.11       chs /* ARGSUSED */
   3475   1.1      haad static int
   3476  1.11       chs zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl)
   3477   1.1      haad {
   3478  1.11       chs 	char *message;
   3479  1.11       chs 	spa_t *spa;
   3480  1.11       chs 	int error;
   3481  1.11       chs 	char *poolname;
   3482  1.11       chs 
   3483  1.11       chs 	/*
   3484  1.11       chs 	 * The poolname in the ioctl is not set, we get it from the TSD,
   3485  1.11       chs 	 * which was set at the end of the last successful ioctl that allows
   3486  1.11       chs 	 * logging.  The secpolicy func already checked that it is set.
   3487  1.11       chs 	 * Only one log ioctl is allowed after each successful ioctl, so
   3488  1.11       chs 	 * we clear the TSD here.
   3489  1.11       chs 	 */
   3490  1.11       chs 	poolname = tsd_get(zfs_allow_log_key);
   3491  1.11       chs 	(void) tsd_set(zfs_allow_log_key, NULL);
   3492  1.11       chs 	error = spa_open(poolname, &spa, FTAG);
   3493  1.11       chs 	strfree(poolname);
   3494  1.11       chs 	if (error != 0)
   3495  1.11       chs 		return (error);
   3496  1.11       chs 
   3497  1.11       chs 	if (nvlist_lookup_string(innvl, "message", &message) != 0)  {
   3498  1.11       chs 		spa_close(spa, FTAG);
   3499  1.11       chs 		return (SET_ERROR(EINVAL));
   3500  1.11       chs 	}
   3501  1.11       chs 
   3502  1.11       chs 	if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
   3503  1.11       chs 		spa_close(spa, FTAG);
   3504  1.11       chs 		return (SET_ERROR(ENOTSUP));
   3505  1.11       chs 	}
   3506   1.1      haad 
   3507  1.11       chs 	error = spa_history_log(spa, message);
   3508  1.11       chs 	spa_close(spa, FTAG);
   3509  1.11       chs 	return (error);
   3510   1.1      haad }
   3511   1.1      haad 
   3512  1.11       chs #ifdef __FreeBSD__
   3513   1.1      haad static int
   3514  1.11       chs zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl)
   3515   1.1      haad {
   3516  1.11       chs 	char name[MAXNAMELEN];
   3517  1.11       chs 	spa_t *spa;
   3518  1.11       chs 	vdev_t *vd;
   3519  1.11       chs 	char *command;
   3520  1.11       chs 	uint64_t pool_guid;
   3521  1.11       chs 	uint64_t vdev_guid;
   3522  1.11       chs 	int error;
   3523  1.11       chs 
   3524  1.11       chs 	if (nvlist_lookup_uint64(innvl,
   3525  1.11       chs 	    ZPOOL_CONFIG_POOL_GUID, &pool_guid) != 0)
   3526  1.11       chs 		return (EINVAL);
   3527  1.11       chs 	if (nvlist_lookup_uint64(innvl,
   3528  1.11       chs 	    ZPOOL_CONFIG_GUID, &vdev_guid) != 0)
   3529  1.11       chs 		return (EINVAL);
   3530  1.11       chs 	if (nvlist_lookup_string(innvl,
   3531  1.11       chs 	    "command", &command) != 0)
   3532  1.11       chs 		return (EINVAL);
   3533  1.11       chs 
   3534  1.11       chs 	mutex_enter(&spa_namespace_lock);
   3535  1.11       chs 	spa = spa_by_guid(pool_guid, vdev_guid);
   3536  1.11       chs 	if (spa != NULL)
   3537  1.11       chs 		strcpy(name, spa_name(spa));
   3538  1.11       chs 	mutex_exit(&spa_namespace_lock);
   3539  1.11       chs 	if (spa == NULL)
   3540  1.11       chs 		return (ENOENT);
   3541  1.11       chs 
   3542  1.11       chs 	if ((error = spa_open(name, &spa, FTAG)) != 0)
   3543  1.11       chs 		return (error);
   3544  1.11       chs 	spa_vdev_state_enter(spa, SCL_ALL);
   3545  1.11       chs 	vd = spa_lookup_by_guid(spa, vdev_guid, B_TRUE);
   3546  1.11       chs 	if (vd == NULL) {
   3547  1.11       chs 		(void) spa_vdev_state_exit(spa, NULL, ENXIO);
   3548  1.11       chs 		spa_close(spa, FTAG);
   3549  1.11       chs 		return (ENODEV);
   3550   1.1      haad 	}
   3551  1.11       chs 	error = vdev_label_write_pad2(vd, command, strlen(command));
   3552  1.11       chs 	(void) spa_vdev_state_exit(spa, NULL, 0);
   3553  1.11       chs 	txg_wait_synced(spa->spa_dsl_pool, 0);
   3554  1.11       chs 	spa_close(spa, FTAG);
   3555  1.11       chs 	return (error);
   3556   1.1      haad }
   3557  1.11       chs #endif
   3558   1.1      haad 
   3559   1.1      haad /*
   3560  1.11       chs  * The dp_config_rwlock must not be held when calling this, because the
   3561  1.11       chs  * unmount may need to write out data.
   3562  1.11       chs  *
   3563  1.11       chs  * This function is best-effort.  Callers must deal gracefully if it
   3564  1.11       chs  * remains mounted (or is remounted after this call).
   3565   1.1      haad  *
   3566  1.11       chs  * Returns 0 if the argument is not a snapshot, or it is not currently a
   3567  1.11       chs  * filesystem, or we were able to unmount it.  Returns error code otherwise.
   3568   1.1      haad  */
   3569  1.11       chs int
   3570  1.11       chs zfs_unmount_snap(const char *snapname)
   3571   1.1      haad {
   3572  1.11       chs 	vfs_t *vfsp;
   3573   1.4      haad 	zfsvfs_t *zfsvfs;
   3574  1.11       chs 	int err;
   3575   1.1      haad 
   3576  1.11       chs 	if (strchr(snapname, '@') == NULL)
   3577  1.11       chs 		return (0);
   3578   1.1      haad 
   3579  1.11       chs 	vfsp = zfs_get_vfs(snapname);
   3580  1.11       chs 	if (vfsp == NULL)
   3581  1.11       chs 		return (0);
   3582   1.4      haad 
   3583  1.11       chs 	zfsvfs = vfsp->vfs_data;
   3584  1.11       chs 	ASSERT(!dsl_pool_config_held(dmu_objset_pool(zfsvfs->z_os)));
   3585   1.1      haad 
   3586  1.11       chs 	err = vn_vfswlock(vfsp->vfs_vnodecovered);
   3587  1.11       chs #ifdef illumos
   3588  1.11       chs 	VFS_RELE(vfsp);
   3589  1.11       chs #else
   3590  1.11       chs 	vfs_unbusy(vfsp);
   3591  1.11       chs #endif
   3592  1.11       chs 	if (err != 0)
   3593  1.11       chs 		return (SET_ERROR(err));
   3594   1.4      haad 
   3595   1.4      haad 	/*
   3596  1.11       chs 	 * Always force the unmount for snapshots.
   3597   1.4      haad 	 */
   3598   1.1      haad 
   3599  1.11       chs #ifdef illumos
   3600  1.11       chs 	(void) dounmount(vfsp, MS_FORCE, kcred);
   3601  1.11       chs #else
   3602  1.11       chs 	vfs_ref(vfsp);
   3603  1.11       chs 	(void) dounmount(vfsp, MS_FORCE, curthread);
   3604  1.11       chs #endif
   3605  1.11       chs 	return (0);
   3606  1.11       chs }
   3607   1.1      haad 
   3608  1.11       chs /* ARGSUSED */
   3609  1.11       chs static int
   3610  1.11       chs zfs_unmount_snap_cb(const char *snapname, void *arg)
   3611  1.11       chs {
   3612  1.11       chs 	return (zfs_unmount_snap(snapname));
   3613   1.1      haad }
   3614   1.1      haad 
   3615   1.1      haad /*
   3616  1.11       chs  * When a clone is destroyed, its origin may also need to be destroyed,
   3617  1.11       chs  * in which case it must be unmounted.  This routine will do that unmount
   3618  1.11       chs  * if necessary.
   3619   1.1      haad  */
   3620  1.11       chs void
   3621  1.11       chs zfs_destroy_unmount_origin(const char *fsname)
   3622  1.11       chs {
   3623  1.11       chs 	int error;
   3624  1.11       chs 	objset_t *os;
   3625  1.11       chs 	dsl_dataset_t *ds;
   3626  1.11       chs 
   3627  1.11       chs 	error = dmu_objset_hold(fsname, FTAG, &os);
   3628  1.11       chs 	if (error != 0)
   3629  1.11       chs 		return;
   3630  1.11       chs 	ds = dmu_objset_ds(os);
   3631  1.11       chs 	if (dsl_dir_is_clone(ds->ds_dir) && DS_IS_DEFER_DESTROY(ds->ds_prev)) {
   3632  1.11       chs 		char originname[ZFS_MAX_DATASET_NAME_LEN];
   3633  1.11       chs 		dsl_dataset_name(ds->ds_prev, originname);
   3634  1.11       chs 		dmu_objset_rele(os, FTAG);
   3635  1.11       chs 		(void) zfs_unmount_snap(originname);
   3636  1.11       chs 	} else {
   3637  1.11       chs 		dmu_objset_rele(os, FTAG);
   3638  1.11       chs 	}
   3639  1.11       chs }
   3640  1.11       chs 
   3641  1.11       chs /*
   3642  1.11       chs  * innvl: {
   3643  1.11       chs  *     "snaps" -> { snapshot1, snapshot2 }
   3644  1.11       chs  *     (optional boolean) "defer"
   3645  1.11       chs  * }
   3646  1.11       chs  *
   3647  1.11       chs  * outnvl: snapshot -> error code (int32)
   3648  1.11       chs  *
   3649  1.11       chs  */
   3650  1.11       chs /* ARGSUSED */
   3651  1.11       chs static int
   3652  1.11       chs zfs_ioc_destroy_snaps(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
   3653  1.11       chs {
   3654  1.11       chs 	int error, poollen;
   3655  1.11       chs 	nvlist_t *snaps;
   3656  1.11       chs 	nvpair_t *pair;
   3657  1.11       chs 	boolean_t defer;
   3658  1.11       chs 
   3659  1.11       chs 	if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
   3660  1.11       chs 		return (SET_ERROR(EINVAL));
   3661  1.11       chs 	defer = nvlist_exists(innvl, "defer");
   3662  1.11       chs 
   3663  1.11       chs 	poollen = strlen(poolname);
   3664  1.11       chs 	for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
   3665  1.11       chs 	    pair = nvlist_next_nvpair(snaps, pair)) {
   3666  1.11       chs 		const char *name = nvpair_name(pair);
   3667  1.11       chs 
   3668  1.11       chs 		/*
   3669  1.11       chs 		 * The snap must be in the specified pool to prevent the
   3670  1.11       chs 		 * invalid removal of zvol minors below.
   3671  1.11       chs 		 */
   3672  1.11       chs 		if (strncmp(name, poolname, poollen) != 0 ||
   3673  1.11       chs 		    (name[poollen] != '/' && name[poollen] != '@'))
   3674  1.11       chs 			return (SET_ERROR(EXDEV));
   3675  1.11       chs 
   3676  1.11       chs 		error = zfs_unmount_snap(name);
   3677  1.11       chs 		if (error != 0)
   3678  1.11       chs 			return (error);
   3679  1.11       chs 		zvol_remove_minors(name);
   3680  1.11       chs 	}
   3681  1.11       chs 
   3682  1.11       chs 	return (dsl_destroy_snapshots_nvl(snaps, defer, outnvl));
   3683  1.11       chs }
   3684  1.11       chs 
   3685  1.11       chs /*
   3686  1.11       chs  * Create bookmarks.  Bookmark names are of the form <fs>#<bmark>.
   3687  1.11       chs  * All bookmarks must be in the same pool.
   3688  1.11       chs  *
   3689  1.11       chs  * innvl: {
   3690  1.11       chs  *     bookmark1 -> snapshot1, bookmark2 -> snapshot2
   3691  1.11       chs  * }
   3692  1.11       chs  *
   3693  1.11       chs  * outnvl: bookmark -> error code (int32)
   3694  1.11       chs  *
   3695  1.11       chs  */
   3696  1.11       chs /* ARGSUSED */
   3697  1.11       chs static int
   3698  1.11       chs zfs_ioc_bookmark(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
   3699  1.11       chs {
   3700  1.11       chs 	for (nvpair_t *pair = nvlist_next_nvpair(innvl, NULL);
   3701  1.11       chs 	    pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
   3702  1.11       chs 		char *snap_name;
   3703  1.11       chs 
   3704  1.11       chs 		/*
   3705  1.11       chs 		 * Verify the snapshot argument.
   3706  1.11       chs 		 */
   3707  1.11       chs 		if (nvpair_value_string(pair, &snap_name) != 0)
   3708  1.11       chs 			return (SET_ERROR(EINVAL));
   3709  1.11       chs 
   3710  1.11       chs 
   3711  1.11       chs 		/* Verify that the keys (bookmarks) are unique */
   3712  1.11       chs 		for (nvpair_t *pair2 = nvlist_next_nvpair(innvl, pair);
   3713  1.11       chs 		    pair2 != NULL; pair2 = nvlist_next_nvpair(innvl, pair2)) {
   3714  1.11       chs 			if (strcmp(nvpair_name(pair), nvpair_name(pair2)) == 0)
   3715  1.11       chs 				return (SET_ERROR(EINVAL));
   3716  1.11       chs 		}
   3717  1.11       chs 	}
   3718  1.11       chs 
   3719  1.11       chs 	return (dsl_bookmark_create(innvl, outnvl));
   3720  1.11       chs }
   3721  1.11       chs 
   3722  1.11       chs /*
   3723  1.11       chs  * innvl: {
   3724  1.11       chs  *     property 1, property 2, ...
   3725  1.11       chs  * }
   3726  1.11       chs  *
   3727  1.11       chs  * outnvl: {
   3728  1.11       chs  *     bookmark name 1 -> { property 1, property 2, ... },
   3729  1.11       chs  *     bookmark name 2 -> { property 1, property 2, ... }
   3730  1.11       chs  * }
   3731  1.11       chs  *
   3732  1.11       chs  */
   3733  1.11       chs static int
   3734  1.11       chs zfs_ioc_get_bookmarks(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
   3735  1.11       chs {
   3736  1.11       chs 	return (dsl_get_bookmarks(fsname, innvl, outnvl));
   3737  1.11       chs }
   3738  1.11       chs 
   3739  1.11       chs /*
   3740  1.11       chs  * innvl: {
   3741  1.11       chs  *     bookmark name 1, bookmark name 2
   3742  1.11       chs  * }
   3743  1.11       chs  *
   3744  1.11       chs  * outnvl: bookmark -> error code (int32)
   3745  1.11       chs  *
   3746  1.11       chs  */
   3747  1.11       chs static int
   3748  1.11       chs zfs_ioc_destroy_bookmarks(const char *poolname, nvlist_t *innvl,
   3749  1.11       chs     nvlist_t *outnvl)
   3750  1.11       chs {
   3751  1.11       chs 	int error, poollen;
   3752  1.11       chs 
   3753  1.11       chs 	poollen = strlen(poolname);
   3754  1.11       chs 	for (nvpair_t *pair = nvlist_next_nvpair(innvl, NULL);
   3755  1.11       chs 	    pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
   3756  1.11       chs 		const char *name = nvpair_name(pair);
   3757  1.11       chs 		const char *cp = strchr(name, '#');
   3758  1.11       chs 
   3759  1.11       chs 		/*
   3760  1.11       chs 		 * The bookmark name must contain an #, and the part after it
   3761  1.11       chs 		 * must contain only valid characters.
   3762  1.11       chs 		 */
   3763  1.11       chs 		if (cp == NULL ||
   3764  1.11       chs 		    zfs_component_namecheck(cp + 1, NULL, NULL) != 0)
   3765  1.11       chs 			return (SET_ERROR(EINVAL));
   3766  1.11       chs 
   3767  1.11       chs 		/*
   3768  1.11       chs 		 * The bookmark must be in the specified pool.
   3769  1.11       chs 		 */
   3770  1.11       chs 		if (strncmp(name, poolname, poollen) != 0 ||
   3771  1.11       chs 		    (name[poollen] != '/' && name[poollen] != '#'))
   3772  1.11       chs 			return (SET_ERROR(EXDEV));
   3773  1.11       chs 	}
   3774  1.11       chs 
   3775  1.11       chs 	error = dsl_bookmark_destroy(innvl, outnvl);
   3776  1.11       chs 	return (error);
   3777  1.11       chs }
   3778  1.11       chs 
   3779  1.11       chs /*
   3780  1.11       chs  * inputs:
   3781  1.11       chs  * zc_name		name of dataset to destroy
   3782  1.11       chs  * zc_objset_type	type of objset
   3783  1.11       chs  * zc_defer_destroy	mark for deferred destroy
   3784  1.11       chs  *
   3785  1.11       chs  * outputs:		none
   3786  1.11       chs  */
   3787  1.11       chs static int
   3788  1.11       chs zfs_ioc_destroy(zfs_cmd_t *zc)
   3789  1.11       chs {
   3790  1.11       chs 	int err;
   3791  1.11       chs 
   3792  1.11       chs 	if (zc->zc_objset_type == DMU_OST_ZFS) {
   3793  1.11       chs 		err = zfs_unmount_snap(zc->zc_name);
   3794  1.11       chs 		if (err != 0)
   3795  1.11       chs 			return (err);
   3796  1.11       chs 	}
   3797  1.11       chs 
   3798  1.11       chs 	if (strchr(zc->zc_name, '@'))
   3799  1.11       chs 		err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy);
   3800  1.11       chs 	else
   3801  1.11       chs 		err = dsl_destroy_head(zc->zc_name);
   3802  1.11       chs 	if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0)
   3803  1.19   hannken #if defined(__FreeBSD__) || defined(__NetBSD__)
   3804  1.11       chs 		zvol_remove_minors(zc->zc_name);
   3805  1.11       chs #else
   3806  1.11       chs 		(void) zvol_remove_minor(zc->zc_name);
   3807  1.11       chs #endif
   3808  1.11       chs 	return (err);
   3809  1.11       chs }
   3810  1.11       chs 
   3811  1.11       chs /*
   3812  1.11       chs  * fsname is name of dataset to rollback (to most recent snapshot)
   3813  1.11       chs  *
   3814  1.11       chs  * innvl is not used.
   3815  1.11       chs  *
   3816  1.11       chs  * outnvl: "target" -> name of most recent snapshot
   3817  1.11       chs  * }
   3818  1.11       chs  */
   3819  1.11       chs /* ARGSUSED */
   3820  1.11       chs static int
   3821  1.11       chs zfs_ioc_rollback(const char *fsname, nvlist_t *args, nvlist_t *outnvl)
   3822  1.11       chs {
   3823  1.11       chs 	zfsvfs_t *zfsvfs;
   3824  1.11       chs 	int error;
   3825  1.11       chs 
   3826  1.11       chs 	if (getzfsvfs(fsname, &zfsvfs) == 0) {
   3827  1.11       chs 		dsl_dataset_t *ds;
   3828  1.11       chs 
   3829  1.11       chs 		ds = dmu_objset_ds(zfsvfs->z_os);
   3830  1.11       chs 		error = zfs_suspend_fs(zfsvfs);
   3831  1.11       chs 		if (error == 0) {
   3832  1.11       chs 			int resume_err;
   3833  1.11       chs 
   3834  1.11       chs 			error = dsl_dataset_rollback(fsname, zfsvfs, outnvl);
   3835  1.11       chs 			resume_err = zfs_resume_fs(zfsvfs, ds);
   3836  1.11       chs 			error = error ? error : resume_err;
   3837  1.11       chs 		}
   3838  1.11       chs #ifdef illumos
   3839  1.11       chs 		VFS_RELE(zfsvfs->z_vfs);
   3840  1.11       chs #else
   3841  1.11       chs 		vfs_unbusy(zfsvfs->z_vfs);
   3842  1.11       chs #endif
   3843  1.11       chs 	} else {
   3844  1.11       chs 		error = dsl_dataset_rollback(fsname, NULL, outnvl);
   3845  1.11       chs 	}
   3846  1.11       chs 	return (error);
   3847  1.11       chs }
   3848  1.11       chs 
   3849  1.11       chs static int
   3850  1.11       chs recursive_unmount(const char *fsname, void *arg)
   3851  1.11       chs {
   3852  1.11       chs 	const char *snapname = arg;
   3853  1.11       chs 	char fullname[ZFS_MAX_DATASET_NAME_LEN];
   3854  1.11       chs 
   3855  1.11       chs 	(void) snprintf(fullname, sizeof (fullname), "%s@%s", fsname, snapname);
   3856  1.11       chs 	return (zfs_unmount_snap(fullname));
   3857  1.11       chs }
   3858  1.11       chs 
   3859  1.11       chs /*
   3860  1.11       chs  * inputs:
   3861  1.11       chs  * zc_name	old name of dataset
   3862  1.11       chs  * zc_value	new name of dataset
   3863  1.11       chs  * zc_cookie	recursive flag (only valid for snapshots)
   3864  1.11       chs  *
   3865  1.11       chs  * outputs:	none
   3866  1.11       chs  */
   3867  1.11       chs static int
   3868  1.11       chs zfs_ioc_rename(zfs_cmd_t *zc)
   3869   1.1      haad {
   3870   1.1      haad 	boolean_t recursive = zc->zc_cookie & 1;
   3871  1.11       chs 	char *at;
   3872  1.11       chs 	boolean_t allow_mounted = B_TRUE;
   3873  1.11       chs 
   3874  1.16   hannken #if defined(__FreeBSD__) || defined(__NetBSD__)
   3875  1.11       chs 	allow_mounted = (zc->zc_cookie & 2) != 0;
   3876  1.11       chs #endif
   3877   1.1      haad 
   3878   1.1      haad 	zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
   3879   1.1      haad 	if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
   3880   1.1      haad 	    strchr(zc->zc_value, '%'))
   3881  1.11       chs 		return (SET_ERROR(EINVAL));
   3882  1.11       chs 
   3883  1.11       chs 	at = strchr(zc->zc_name, '@');
   3884  1.11       chs 	if (at != NULL) {
   3885  1.11       chs 		/* snaps must be in same fs */
   3886  1.11       chs 		int error;
   3887  1.11       chs 
   3888  1.11       chs 		if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
   3889  1.11       chs 			return (SET_ERROR(EXDEV));
   3890  1.11       chs 		*at = '\0';
   3891  1.11       chs 		if (zc->zc_objset_type == DMU_OST_ZFS && !allow_mounted) {
   3892  1.11       chs 			error = dmu_objset_find(zc->zc_name,
   3893  1.11       chs 			    recursive_unmount, at + 1,
   3894  1.11       chs 			    recursive ? DS_FIND_CHILDREN : 0);
   3895  1.11       chs 			if (error != 0) {
   3896  1.11       chs 				*at = '@';
   3897  1.11       chs 				return (error);
   3898  1.11       chs 			}
   3899  1.11       chs 		}
   3900  1.11       chs 		error = dsl_dataset_rename_snapshot(zc->zc_name,
   3901  1.11       chs 		    at + 1, strchr(zc->zc_value, '@') + 1, recursive);
   3902  1.11       chs 		*at = '@';
   3903   1.1      haad 
   3904  1.11       chs 		return (error);
   3905  1.11       chs 	} else {
   3906  1.11       chs #ifdef illumos
   3907  1.11       chs 		if (zc->zc_objset_type == DMU_OST_ZVOL)
   3908  1.11       chs 			(void) zvol_remove_minor(zc->zc_name);
   3909  1.11       chs #endif
   3910  1.11       chs 		return (dsl_dir_rename(zc->zc_name, zc->zc_value));
   3911   1.1      haad 	}
   3912   1.1      haad }
   3913   1.1      haad 
   3914   1.4      haad static int
   3915   1.4      haad zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
   3916   1.4      haad {
   3917   1.4      haad 	const char *propname = nvpair_name(pair);
   3918   1.4      haad 	boolean_t issnap = (strchr(dsname, '@') != NULL);
   3919   1.4      haad 	zfs_prop_t prop = zfs_name_to_prop(propname);
   3920   1.4      haad 	uint64_t intval;
   3921   1.4      haad 	int err;
   3922   1.4      haad 
   3923   1.4      haad 	if (prop == ZPROP_INVAL) {
   3924   1.4      haad 		if (zfs_prop_user(propname)) {
   3925   1.4      haad 			if (err = zfs_secpolicy_write_perms(dsname,
   3926   1.4      haad 			    ZFS_DELEG_PERM_USERPROP, cr))
   3927   1.4      haad 				return (err);
   3928   1.4      haad 			return (0);
   3929   1.4      haad 		}
   3930   1.4      haad 
   3931   1.4      haad 		if (!issnap && zfs_prop_userquota(propname)) {
   3932   1.4      haad 			const char *perm = NULL;
   3933   1.4      haad 			const char *uq_prefix =
   3934   1.4      haad 			    zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA];
   3935   1.4      haad 			const char *gq_prefix =
   3936   1.4      haad 			    zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA];
   3937   1.4      haad 
   3938   1.4      haad 			if (strncmp(propname, uq_prefix,
   3939   1.4      haad 			    strlen(uq_prefix)) == 0) {
   3940   1.4      haad 				perm = ZFS_DELEG_PERM_USERQUOTA;
   3941   1.4      haad 			} else if (strncmp(propname, gq_prefix,
   3942   1.4      haad 			    strlen(gq_prefix)) == 0) {
   3943   1.4      haad 				perm = ZFS_DELEG_PERM_GROUPQUOTA;
   3944   1.4      haad 			} else {
   3945   1.4      haad 				/* USERUSED and GROUPUSED are read-only */
   3946  1.11       chs 				return (SET_ERROR(EINVAL));
   3947   1.4      haad 			}
   3948   1.4      haad 
   3949   1.4      haad 			if (err = zfs_secpolicy_write_perms(dsname, perm, cr))
   3950   1.4      haad 				return (err);
   3951   1.4      haad 			return (0);
   3952   1.4      haad 		}
   3953   1.4      haad 
   3954  1.11       chs 		return (SET_ERROR(EINVAL));
   3955   1.4      haad 	}
   3956   1.4      haad 
   3957   1.4      haad 	if (issnap)
   3958  1.11       chs 		return (SET_ERROR(EINVAL));
   3959   1.4      haad 
   3960   1.4      haad 	if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
   3961   1.4      haad 		/*
   3962   1.4      haad 		 * dsl_prop_get_all_impl() returns properties in this
   3963   1.4      haad 		 * format.
   3964   1.4      haad 		 */
   3965   1.4      haad 		nvlist_t *attrs;
   3966   1.4      haad 		VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
   3967   1.4      haad 		VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
   3968   1.4      haad 		    &pair) == 0);
   3969   1.4      haad 	}
   3970   1.4      haad 
   3971   1.4      haad 	/*
   3972   1.4      haad 	 * Check that this value is valid for this pool version
   3973   1.4      haad 	 */
   3974   1.4      haad 	switch (prop) {
   3975   1.4      haad 	case ZFS_PROP_COMPRESSION:
   3976   1.4      haad 		/*
   3977   1.4      haad 		 * If the user specified gzip compression, make sure
   3978   1.4      haad 		 * the SPA supports it. We ignore any errors here since
   3979   1.4      haad 		 * we'll catch them later.
   3980   1.4      haad 		 */
   3981  1.11       chs 		if (nvpair_value_uint64(pair, &intval) == 0) {
   3982   1.4      haad 			if (intval >= ZIO_COMPRESS_GZIP_1 &&
   3983   1.4      haad 			    intval <= ZIO_COMPRESS_GZIP_9 &&
   3984   1.4      haad 			    zfs_earlier_version(dsname,
   3985   1.4      haad 			    SPA_VERSION_GZIP_COMPRESSION)) {
   3986  1.11       chs 				return (SET_ERROR(ENOTSUP));
   3987   1.4      haad 			}
   3988   1.4      haad 
   3989   1.4      haad 			if (intval == ZIO_COMPRESS_ZLE &&
   3990   1.4      haad 			    zfs_earlier_version(dsname,
   3991   1.4      haad 			    SPA_VERSION_ZLE_COMPRESSION))
   3992  1.11       chs 				return (SET_ERROR(ENOTSUP));
   3993  1.11       chs 
   3994  1.11       chs 			if (intval == ZIO_COMPRESS_LZ4) {
   3995  1.11       chs 				spa_t *spa;
   3996  1.11       chs 
   3997  1.11       chs 				if ((err = spa_open(dsname, &spa, FTAG)) != 0)
   3998  1.11       chs 					return (err);
   3999  1.11       chs 
   4000  1.11       chs 				if (!spa_feature_is_enabled(spa,
   4001  1.11       chs 				    SPA_FEATURE_LZ4_COMPRESS)) {
   4002  1.11       chs 					spa_close(spa, FTAG);
   4003  1.11       chs 					return (SET_ERROR(ENOTSUP));
   4004  1.11       chs 				}
   4005  1.11       chs 				spa_close(spa, FTAG);
   4006  1.11       chs 			}
   4007   1.4      haad 
   4008   1.4      haad 			/*
   4009   1.4      haad 			 * If this is a bootable dataset then
   4010   1.4      haad 			 * verify that the compression algorithm
   4011   1.4      haad 			 * is supported for booting. We must return
   4012   1.4      haad 			 * something other than ENOTSUP since it
   4013   1.4      haad 			 * implies a downrev pool version.
   4014   1.4      haad 			 */
   4015   1.4      haad 			if (zfs_is_bootfs(dsname) &&
   4016   1.4      haad 			    !BOOTFS_COMPRESS_VALID(intval)) {
   4017  1.11       chs 				return (SET_ERROR(ERANGE));
   4018   1.4      haad 			}
   4019   1.4      haad 		}
   4020   1.4      haad 		break;
   4021   1.4      haad 
   4022   1.4      haad 	case ZFS_PROP_COPIES:
   4023   1.4      haad 		if (zfs_earlier_version(dsname, SPA_VERSION_DITTO_BLOCKS))
   4024  1.11       chs 			return (SET_ERROR(ENOTSUP));
   4025   1.4      haad 		break;
   4026   1.4      haad 
   4027  1.11       chs 	case ZFS_PROP_RECORDSIZE:
   4028  1.11       chs 		/* Record sizes above 128k need the feature to be enabled */
   4029  1.11       chs 		if (nvpair_value_uint64(pair, &intval) == 0 &&
   4030  1.11       chs 		    intval > SPA_OLD_MAXBLOCKSIZE) {
   4031  1.11       chs 			spa_t *spa;
   4032  1.11       chs 
   4033  1.11       chs 			/*
   4034  1.11       chs 			 * We don't allow setting the property above 1MB,
   4035  1.11       chs 			 * unless the tunable has been changed.
   4036  1.11       chs 			 */
   4037  1.11       chs 			if (intval > zfs_max_recordsize ||
   4038  1.11       chs 			    intval > SPA_MAXBLOCKSIZE)
   4039  1.11       chs 				return (SET_ERROR(ERANGE));
   4040  1.11       chs 
   4041  1.11       chs 			if ((err = spa_open(dsname, &spa, FTAG)) != 0)
   4042  1.11       chs 				return (err);
   4043  1.11       chs 
   4044  1.11       chs 			if (!spa_feature_is_enabled(spa,
   4045  1.11       chs 			    SPA_FEATURE_LARGE_BLOCKS)) {
   4046  1.11       chs 				spa_close(spa, FTAG);
   4047  1.11       chs 				return (SET_ERROR(ENOTSUP));
   4048  1.11       chs 			}
   4049  1.11       chs 			spa_close(spa, FTAG);
   4050  1.11       chs 		}
   4051   1.4      haad 		break;
   4052   1.4      haad 
   4053   1.4      haad 	case ZFS_PROP_SHARESMB:
   4054   1.4      haad 		if (zpl_earlier_version(dsname, ZPL_VERSION_FUID))
   4055  1.11       chs 			return (SET_ERROR(ENOTSUP));
   4056   1.4      haad 		break;
   4057   1.4      haad 
   4058   1.4      haad 	case ZFS_PROP_ACLINHERIT:
   4059   1.4      haad 		if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
   4060   1.4      haad 		    nvpair_value_uint64(pair, &intval) == 0) {
   4061   1.4      haad 			if (intval == ZFS_ACL_PASSTHROUGH_X &&
   4062   1.4      haad 			    zfs_earlier_version(dsname,
   4063   1.4      haad 			    SPA_VERSION_PASSTHROUGH_X))
   4064  1.11       chs 				return (SET_ERROR(ENOTSUP));
   4065  1.11       chs 		}
   4066  1.11       chs 		break;
   4067  1.11       chs 
   4068  1.11       chs 	case ZFS_PROP_CHECKSUM:
   4069  1.11       chs 	case ZFS_PROP_DEDUP:
   4070  1.11       chs 	{
   4071  1.11       chs 		spa_feature_t feature;
   4072  1.11       chs 		spa_t *spa;
   4073  1.11       chs 
   4074  1.11       chs 		/* dedup feature version checks */
   4075  1.11       chs 		if (prop == ZFS_PROP_DEDUP &&
   4076  1.11       chs 		    zfs_earlier_version(dsname, SPA_VERSION_DEDUP))
   4077  1.11       chs 			return (SET_ERROR(ENOTSUP));
   4078  1.11       chs 
   4079  1.11       chs 		if (nvpair_value_uint64(pair, &intval) != 0)
   4080  1.11       chs 			return (SET_ERROR(EINVAL));
   4081  1.11       chs 
   4082  1.11       chs 		/* check prop value is enabled in features */
   4083  1.11       chs 		feature = zio_checksum_to_feature(intval & ZIO_CHECKSUM_MASK);
   4084  1.11       chs 		if (feature == SPA_FEATURE_NONE)
   4085  1.11       chs 			break;
   4086  1.11       chs 
   4087  1.11       chs 		if ((err = spa_open(dsname, &spa, FTAG)) != 0)
   4088  1.11       chs 			return (err);
   4089  1.11       chs 		/*
   4090  1.11       chs 		 * Salted checksums are not supported on root pools.
   4091  1.11       chs 		 */
   4092  1.11       chs 		if (spa_bootfs(spa) != 0 &&
   4093  1.11       chs 		    intval < ZIO_CHECKSUM_FUNCTIONS &&
   4094  1.11       chs 		    (zio_checksum_table[intval].ci_flags &
   4095  1.11       chs 		    ZCHECKSUM_FLAG_SALTED)) {
   4096  1.11       chs 			spa_close(spa, FTAG);
   4097  1.11       chs 			return (SET_ERROR(ERANGE));
   4098  1.11       chs 		}
   4099  1.11       chs 		if (!spa_feature_is_enabled(spa, feature)) {
   4100  1.11       chs 			spa_close(spa, FTAG);
   4101  1.11       chs 			return (SET_ERROR(ENOTSUP));
   4102   1.4      haad 		}
   4103  1.11       chs 		spa_close(spa, FTAG);
   4104   1.4      haad 		break;
   4105   1.4      haad 	}
   4106  1.11       chs 	}
   4107   1.4      haad 
   4108   1.4      haad 	return (zfs_secpolicy_setprop(dsname, prop, pair, CRED()));
   4109   1.4      haad }
   4110   1.4      haad 
   4111   1.4      haad /*
   4112  1.11       chs  * Checks for a race condition to make sure we don't increment a feature flag
   4113  1.11       chs  * multiple times.
   4114  1.11       chs  */
   4115  1.11       chs static int
   4116  1.11       chs zfs_prop_activate_feature_check(void *arg, dmu_tx_t *tx)
   4117  1.11       chs {
   4118  1.11       chs 	spa_t *spa = dmu_tx_pool(tx)->dp_spa;
   4119  1.11       chs 	spa_feature_t *featurep = arg;
   4120  1.11       chs 
   4121  1.11       chs 	if (!spa_feature_is_active(spa, *featurep))
   4122  1.11       chs 		return (0);
   4123  1.11       chs 	else
   4124  1.11       chs 		return (SET_ERROR(EBUSY));
   4125  1.11       chs }
   4126  1.11       chs 
   4127  1.11       chs /*
   4128  1.11       chs  * The callback invoked on feature activation in the sync task caused by
   4129  1.11       chs  * zfs_prop_activate_feature.
   4130  1.11       chs  */
   4131  1.11       chs static void
   4132  1.11       chs zfs_prop_activate_feature_sync(void *arg, dmu_tx_t *tx)
   4133  1.11       chs {
   4134  1.11       chs 	spa_t *spa = dmu_tx_pool(tx)->dp_spa;
   4135  1.11       chs 	spa_feature_t *featurep = arg;
   4136  1.11       chs 
   4137  1.11       chs 	spa_feature_incr(spa, *featurep, tx);
   4138  1.11       chs }
   4139  1.11       chs 
   4140  1.11       chs /*
   4141  1.11       chs  * Activates a feature on a pool in response to a property setting. This
   4142  1.11       chs  * creates a new sync task which modifies the pool to reflect the feature
   4143  1.11       chs  * as being active.
   4144  1.11       chs  */
   4145  1.11       chs static int
   4146  1.11       chs zfs_prop_activate_feature(spa_t *spa, spa_feature_t feature)
   4147  1.11       chs {
   4148  1.11       chs 	int err;
   4149  1.11       chs 
   4150  1.11       chs 	/* EBUSY here indicates that the feature is already active */
   4151  1.11       chs 	err = dsl_sync_task(spa_name(spa),
   4152  1.11       chs 	    zfs_prop_activate_feature_check, zfs_prop_activate_feature_sync,
   4153  1.11       chs 	    &feature, 2, ZFS_SPACE_CHECK_RESERVED);
   4154  1.11       chs 
   4155  1.11       chs 	if (err != 0 && err != EBUSY)
   4156  1.11       chs 		return (err);
   4157  1.11       chs 	else
   4158  1.11       chs 		return (0);
   4159  1.11       chs }
   4160  1.11       chs 
   4161  1.11       chs /*
   4162   1.4      haad  * Removes properties from the given props list that fail permission checks
   4163   1.4      haad  * needed to clear them and to restore them in case of a receive error. For each
   4164   1.4      haad  * property, make sure we have both set and inherit permissions.
   4165   1.4      haad  *
   4166   1.4      haad  * Returns the first error encountered if any permission checks fail. If the
   4167   1.4      haad  * caller provides a non-NULL errlist, it also gives the complete list of names
   4168   1.4      haad  * of all the properties that failed a permission check along with the
   4169   1.4      haad  * corresponding error numbers. The caller is responsible for freeing the
   4170   1.4      haad  * returned errlist.
   4171   1.4      haad  *
   4172   1.4      haad  * If every property checks out successfully, zero is returned and the list
   4173   1.4      haad  * pointed at by errlist is NULL.
   4174   1.4      haad  */
   4175   1.4      haad static int
   4176   1.4      haad zfs_check_clearable(char *dataset, nvlist_t *props, nvlist_t **errlist)
   4177   1.1      haad {
   4178   1.1      haad 	zfs_cmd_t *zc;
   4179   1.4      haad 	nvpair_t *pair, *next_pair;
   4180   1.4      haad 	nvlist_t *errors;
   4181   1.4      haad 	int err, rv = 0;
   4182   1.1      haad 
   4183   1.1      haad 	if (props == NULL)
   4184   1.4      haad 		return (0);
   4185   1.4      haad 
   4186   1.4      haad 	VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   4187   1.4      haad 
   4188   1.1      haad 	zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP);
   4189   1.1      haad 	(void) strcpy(zc->zc_name, dataset);
   4190   1.4      haad 	pair = nvlist_next_nvpair(props, NULL);
   4191   1.4      haad 	while (pair != NULL) {
   4192   1.4      haad 		next_pair = nvlist_next_nvpair(props, pair);
   4193   1.4      haad 
   4194   1.4      haad 		(void) strcpy(zc->zc_value, nvpair_name(pair));
   4195   1.4      haad 		if ((err = zfs_check_settable(dataset, pair, CRED())) != 0 ||
   4196  1.11       chs 		    (err = zfs_secpolicy_inherit_prop(zc, NULL, CRED())) != 0) {
   4197   1.4      haad 			VERIFY(nvlist_remove_nvpair(props, pair) == 0);
   4198   1.4      haad 			VERIFY(nvlist_add_int32(errors,
   4199   1.4      haad 			    zc->zc_value, err) == 0);
   4200   1.4      haad 		}
   4201   1.4      haad 		pair = next_pair;
   4202   1.1      haad 	}
   4203   1.1      haad 	kmem_free(zc, sizeof (zfs_cmd_t));
   4204   1.4      haad 
   4205   1.4      haad 	if ((pair = nvlist_next_nvpair(errors, NULL)) == NULL) {
   4206   1.4      haad 		nvlist_free(errors);
   4207   1.4      haad 		errors = NULL;
   4208   1.4      haad 	} else {
   4209   1.4      haad 		VERIFY(nvpair_value_int32(pair, &rv) == 0);
   4210   1.4      haad 	}
   4211   1.4      haad 
   4212   1.4      haad 	if (errlist == NULL)
   4213   1.4      haad 		nvlist_free(errors);
   4214   1.4      haad 	else
   4215   1.4      haad 		*errlist = errors;
   4216   1.4      haad 
   4217   1.4      haad 	return (rv);
   4218   1.4      haad }
   4219   1.4      haad 
   4220   1.4      haad static boolean_t
   4221   1.4      haad propval_equals(nvpair_t *p1, nvpair_t *p2)
   4222   1.4      haad {
   4223   1.4      haad 	if (nvpair_type(p1) == DATA_TYPE_NVLIST) {
   4224   1.4      haad 		/* dsl_prop_get_all_impl() format */
   4225   1.4      haad 		nvlist_t *attrs;
   4226   1.4      haad 		VERIFY(nvpair_value_nvlist(p1, &attrs) == 0);
   4227   1.4      haad 		VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
   4228   1.4      haad 		    &p1) == 0);
   4229   1.4      haad 	}
   4230   1.4      haad 
   4231   1.4      haad 	if (nvpair_type(p2) == DATA_TYPE_NVLIST) {
   4232   1.4      haad 		nvlist_t *attrs;
   4233   1.4      haad 		VERIFY(nvpair_value_nvlist(p2, &attrs) == 0);
   4234   1.4      haad 		VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
   4235   1.4      haad 		    &p2) == 0);
   4236   1.4      haad 	}
   4237   1.4      haad 
   4238   1.4      haad 	if (nvpair_type(p1) != nvpair_type(p2))
   4239   1.4      haad 		return (B_FALSE);
   4240   1.4      haad 
   4241   1.4      haad 	if (nvpair_type(p1) == DATA_TYPE_STRING) {
   4242   1.4      haad 		char *valstr1, *valstr2;
   4243   1.4      haad 
   4244   1.4      haad 		VERIFY(nvpair_value_string(p1, (char **)&valstr1) == 0);
   4245   1.4      haad 		VERIFY(nvpair_value_string(p2, (char **)&valstr2) == 0);
   4246   1.4      haad 		return (strcmp(valstr1, valstr2) == 0);
   4247   1.4      haad 	} else {
   4248   1.4      haad 		uint64_t intval1, intval2;
   4249   1.4      haad 
   4250   1.4      haad 		VERIFY(nvpair_value_uint64(p1, &intval1) == 0);
   4251   1.4      haad 		VERIFY(nvpair_value_uint64(p2, &intval2) == 0);
   4252   1.4      haad 		return (intval1 == intval2);
   4253   1.4      haad 	}
   4254   1.4      haad }
   4255   1.4      haad 
   4256   1.4      haad /*
   4257   1.4      haad  * Remove properties from props if they are not going to change (as determined
   4258   1.4      haad  * by comparison with origprops). Remove them from origprops as well, since we
   4259   1.4      haad  * do not need to clear or restore properties that won't change.
   4260   1.4      haad  */
   4261   1.4      haad static void
   4262   1.4      haad props_reduce(nvlist_t *props, nvlist_t *origprops)
   4263   1.4      haad {
   4264   1.4      haad 	nvpair_t *pair, *next_pair;
   4265   1.4      haad 
   4266   1.4      haad 	if (origprops == NULL)
   4267   1.4      haad 		return; /* all props need to be received */
   4268   1.4      haad 
   4269   1.4      haad 	pair = nvlist_next_nvpair(props, NULL);
   4270   1.4      haad 	while (pair != NULL) {
   4271   1.4      haad 		const char *propname = nvpair_name(pair);
   4272   1.4      haad 		nvpair_t *match;
   4273   1.4      haad 
   4274   1.4      haad 		next_pair = nvlist_next_nvpair(props, pair);
   4275   1.4      haad 
   4276   1.4      haad 		if ((nvlist_lookup_nvpair(origprops, propname,
   4277   1.4      haad 		    &match) != 0) || !propval_equals(pair, match))
   4278   1.4      haad 			goto next; /* need to set received value */
   4279   1.4      haad 
   4280   1.4      haad 		/* don't clear the existing received value */
   4281   1.4      haad 		(void) nvlist_remove_nvpair(origprops, match);
   4282   1.4      haad 		/* don't bother receiving the property */
   4283   1.4      haad 		(void) nvlist_remove_nvpair(props, pair);
   4284   1.4      haad next:
   4285   1.4      haad 		pair = next_pair;
   4286   1.4      haad 	}
   4287   1.4      haad }
   4288   1.4      haad 
   4289  1.11       chs /*
   4290  1.11       chs  * Extract properties that cannot be set PRIOR to the receipt of a dataset.
   4291  1.11       chs  * For example, refquota cannot be set until after the receipt of a dataset,
   4292  1.11       chs  * because in replication streams, an older/earlier snapshot may exceed the
   4293  1.11       chs  * refquota.  We want to receive the older/earlier snapshot, but setting
   4294  1.11       chs  * refquota pre-receipt will set the dsl's ACTUAL quota, which will prevent
   4295  1.11       chs  * the older/earlier snapshot from being received (with EDQUOT).
   4296  1.11       chs  *
   4297  1.11       chs  * The ZFS test "zfs_receive_011_pos" demonstrates such a scenario.
   4298  1.11       chs  *
   4299  1.11       chs  * libzfs will need to be judicious handling errors encountered by props
   4300  1.11       chs  * extracted by this function.
   4301  1.11       chs  */
   4302  1.11       chs static nvlist_t *
   4303  1.11       chs extract_delay_props(nvlist_t *props)
   4304  1.11       chs {
   4305  1.11       chs 	nvlist_t *delayprops;
   4306  1.11       chs 	nvpair_t *nvp, *tmp;
   4307  1.11       chs 	static const zfs_prop_t delayable[] = { ZFS_PROP_REFQUOTA, 0 };
   4308  1.11       chs 	int i;
   4309  1.11       chs 
   4310  1.11       chs 	VERIFY(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   4311  1.11       chs 
   4312  1.11       chs 	for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL;
   4313  1.11       chs 	    nvp = nvlist_next_nvpair(props, nvp)) {
   4314  1.11       chs 		/*
   4315  1.11       chs 		 * strcmp() is safe because zfs_prop_to_name() always returns
   4316  1.11       chs 		 * a bounded string.
   4317  1.11       chs 		 */
   4318  1.11       chs 		for (i = 0; delayable[i] != 0; i++) {
   4319  1.11       chs 			if (strcmp(zfs_prop_to_name(delayable[i]),
   4320  1.11       chs 			    nvpair_name(nvp)) == 0) {
   4321  1.11       chs 				break;
   4322  1.11       chs 			}
   4323  1.11       chs 		}
   4324  1.11       chs 		if (delayable[i] != 0) {
   4325  1.11       chs 			tmp = nvlist_prev_nvpair(props, nvp);
   4326  1.11       chs 			VERIFY(nvlist_add_nvpair(delayprops, nvp) == 0);
   4327  1.11       chs 			VERIFY(nvlist_remove_nvpair(props, nvp) == 0);
   4328  1.11       chs 			nvp = tmp;
   4329  1.11       chs 		}
   4330  1.11       chs 	}
   4331  1.11       chs 
   4332  1.11       chs 	if (nvlist_empty(delayprops)) {
   4333  1.11       chs 		nvlist_free(delayprops);
   4334  1.11       chs 		delayprops = NULL;
   4335  1.11       chs 	}
   4336  1.11       chs 	return (delayprops);
   4337  1.11       chs }
   4338  1.11       chs 
   4339   1.4      haad #ifdef	DEBUG
   4340   1.4      haad static boolean_t zfs_ioc_recv_inject_err;
   4341   1.4      haad #endif
   4342   1.1      haad 
   4343   1.1      haad /*
   4344   1.1      haad  * inputs:
   4345   1.1      haad  * zc_name		name of containing filesystem
   4346   1.1      haad  * zc_nvlist_src{_size}	nvlist of properties to apply
   4347   1.1      haad  * zc_value		name of snapshot to create
   4348   1.1      haad  * zc_string		name of clone origin (if DRR_FLAG_CLONE)
   4349   1.1      haad  * zc_cookie		file descriptor to recv from
   4350   1.1      haad  * zc_begin_record	the BEGIN record of the stream (not byteswapped)
   4351   1.1      haad  * zc_guid		force flag
   4352  1.11       chs  * zc_cleanup_fd	cleanup-on-exit file descriptor
   4353  1.11       chs  * zc_action_handle	handle for this guid/ds mapping (or zero on first call)
   4354  1.11       chs  * zc_resumable		if data is incomplete assume sender will resume
   4355   1.1      haad  *
   4356   1.1      haad  * outputs:
   4357   1.1      haad  * zc_cookie		number of bytes read
   4358   1.4      haad  * zc_nvlist_dst{_size} error for each unapplied received property
   4359   1.4      haad  * zc_obj		zprop_errflags_t
   4360  1.11       chs  * zc_action_handle	handle for this guid/ds mapping
   4361   1.1      haad  */
   4362   1.1      haad static int
   4363   1.1      haad zfs_ioc_recv(zfs_cmd_t *zc)
   4364   1.1      haad {
   4365   1.1      haad 	file_t *fp;
   4366   1.1      haad 	dmu_recv_cookie_t drc;
   4367   1.1      haad 	boolean_t force = (boolean_t)zc->zc_guid;
   4368   1.4      haad 	int fd;
   4369   1.4      haad 	int error = 0;
   4370   1.4      haad 	int props_error = 0;
   4371   1.4      haad 	nvlist_t *errors;
   4372   1.1      haad 	offset_t off;
   4373   1.4      haad 	nvlist_t *props = NULL; /* sent properties */
   4374   1.4      haad 	nvlist_t *origprops = NULL; /* existing properties */
   4375  1.11       chs 	nvlist_t *delayprops = NULL; /* sent properties applied post-receive */
   4376  1.11       chs 	char *origin = NULL;
   4377   1.1      haad 	char *tosnap;
   4378  1.11       chs 	char tofs[ZFS_MAX_DATASET_NAME_LEN];
   4379  1.11       chs #ifdef __FreeBSD__
   4380  1.11       chs 	cap_rights_t rights;
   4381  1.11       chs #endif
   4382   1.4      haad 	boolean_t first_recvd_props = B_FALSE;
   4383   1.1      haad 
   4384   1.1      haad 	if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
   4385   1.1      haad 	    strchr(zc->zc_value, '@') == NULL ||
   4386   1.1      haad 	    strchr(zc->zc_value, '%'))
   4387  1.11       chs 		return (SET_ERROR(EINVAL));
   4388   1.1      haad 
   4389   1.1      haad 	(void) strcpy(tofs, zc->zc_value);
   4390   1.1      haad 	tosnap = strchr(tofs, '@');
   4391   1.4      haad 	*tosnap++ = '\0';
   4392   1.1      haad 
   4393   1.8  christos 	if (zc->zc_nvlist_src != 0 &&
   4394   1.1      haad 	    (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
   4395   1.4      haad 	    zc->zc_iflags, &props)) != 0)
   4396   1.1      haad 		return (error);
   4397   1.1      haad 
   4398   1.1      haad 	fd = zc->zc_cookie;
   4399  1.11       chs #ifdef __FreeBSD__
   4400  1.11       chs 	fget_read(curthread, fd, cap_rights_init(&rights, CAP_PREAD), &fp);
   4401  1.11       chs #else
   4402  1.11       chs 	fp = getf(fd);
   4403  1.11       chs #endif
   4404  1.11       chs 	if (fp == NULL) {
   4405   1.1      haad 		nvlist_free(props);
   4406  1.11       chs 		return (SET_ERROR(EBADF));
   4407   1.1      haad 	}
   4408   1.1      haad 
   4409  1.11       chs 	errors = fnvlist_alloc();
   4410  1.11       chs 
   4411  1.11       chs 	if (zc->zc_string[0])
   4412  1.11       chs 		origin = zc->zc_string;
   4413  1.11       chs 
   4414  1.11       chs 	error = dmu_recv_begin(tofs, tosnap,
   4415  1.11       chs 	    &zc->zc_begin_record, force, zc->zc_resumable, origin, &drc);
   4416  1.11       chs 	if (error != 0)
   4417  1.11       chs 		goto out;
   4418   1.4      haad 
   4419  1.11       chs 	/*
   4420  1.11       chs 	 * Set properties before we receive the stream so that they are applied
   4421  1.11       chs 	 * to the new data. Note that we must call dmu_recv_stream() if
   4422  1.11       chs 	 * dmu_recv_begin() succeeds.
   4423  1.11       chs 	 */
   4424  1.11       chs 	if (props != NULL && !drc.drc_newfs) {
   4425  1.11       chs 		if (spa_version(dsl_dataset_get_spa(drc.drc_ds)) >=
   4426  1.11       chs 		    SPA_VERSION_RECVD_PROPS &&
   4427  1.11       chs 		    !dsl_prop_get_hasrecvd(tofs))
   4428   1.4      haad 			first_recvd_props = B_TRUE;
   4429   1.1      haad 
   4430   1.1      haad 		/*
   4431   1.4      haad 		 * If new received properties are supplied, they are to
   4432   1.4      haad 		 * completely replace the existing received properties, so stash
   4433   1.4      haad 		 * away the existing ones.
   4434   1.1      haad 		 */
   4435  1.11       chs 		if (dsl_prop_get_received(tofs, &origprops) == 0) {
   4436   1.4      haad 			nvlist_t *errlist = NULL;
   4437   1.4      haad 			/*
   4438   1.4      haad 			 * Don't bother writing a property if its value won't
   4439   1.4      haad 			 * change (and avoid the unnecessary security checks).
   4440   1.4      haad 			 *
   4441   1.4      haad 			 * The first receive after SPA_VERSION_RECVD_PROPS is a
   4442   1.4      haad 			 * special case where we blow away all local properties
   4443   1.4      haad 			 * regardless.
   4444   1.4      haad 			 */
   4445   1.4      haad 			if (!first_recvd_props)
   4446   1.4      haad 				props_reduce(props, origprops);
   4447  1.11       chs 			if (zfs_check_clearable(tofs, origprops, &errlist) != 0)
   4448   1.4      haad 				(void) nvlist_merge(errors, errlist, 0);
   4449   1.4      haad 			nvlist_free(errlist);
   4450   1.4      haad 
   4451  1.11       chs 			if (clear_received_props(tofs, origprops,
   4452  1.11       chs 			    first_recvd_props ? NULL : props) != 0)
   4453   1.4      haad 				zc->zc_obj |= ZPROP_ERR_NOCLEAR;
   4454  1.11       chs 		} else {
   4455   1.4      haad 			zc->zc_obj |= ZPROP_ERR_NOCLEAR;
   4456   1.4      haad 		}
   4457  1.11       chs 	}
   4458   1.4      haad 
   4459  1.11       chs 	if (props != NULL) {
   4460  1.11       chs 		props_error = dsl_prop_set_hasrecvd(tofs);
   4461   1.4      haad 
   4462  1.11       chs 		if (props_error == 0) {
   4463  1.11       chs 			delayprops = extract_delay_props(props);
   4464  1.11       chs 			(void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
   4465  1.11       chs 			    props, errors);
   4466  1.11       chs 		}
   4467   1.1      haad 	}
   4468   1.1      haad 
   4469   1.1      haad 	off = fp->f_offset;
   4470  1.11       chs 	error = dmu_recv_stream(&drc, fp, &off, zc->zc_cleanup_fd,
   4471  1.11       chs 	    &zc->zc_action_handle);
   4472   1.1      haad 
   4473   1.4      haad 	if (error == 0) {
   4474   1.4      haad 		zfsvfs_t *zfsvfs = NULL;
   4475   1.4      haad 
   4476   1.4      haad 		if (getzfsvfs(tofs, &zfsvfs) == 0) {
   4477   1.4      haad 			/* online recv */
   4478  1.11       chs 			dsl_dataset_t *ds;
   4479   1.4      haad 			int end_err;
   4480   1.1      haad 
   4481  1.11       chs 			ds = dmu_objset_ds(zfsvfs->z_os);
   4482   1.4      haad 			error = zfs_suspend_fs(zfsvfs);
   4483   1.4      haad 			/*
   4484   1.4      haad 			 * If the suspend fails, then the recv_end will
   4485   1.4      haad 			 * likely also fail, and clean up after itself.
   4486   1.4      haad 			 */
   4487  1.11       chs 			end_err = dmu_recv_end(&drc, zfsvfs);
   4488  1.11       chs 			if (error == 0)
   4489  1.11       chs 				error = zfs_resume_fs(zfsvfs, ds);
   4490   1.4      haad 			error = error ? error : end_err;
   4491  1.11       chs #ifdef illumos
   4492   1.4      haad 			VFS_RELE(zfsvfs->z_vfs);
   4493  1.11       chs #else
   4494  1.11       chs 			vfs_unbusy(zfsvfs->z_vfs);
   4495  1.11       chs #endif
   4496   1.4      haad 		} else {
   4497  1.11       chs 			error = dmu_recv_end(&drc, NULL);
   4498  1.11       chs 		}
   4499  1.11       chs 
   4500  1.11       chs 		/* Set delayed properties now, after we're done receiving. */
   4501  1.11       chs 		if (delayprops != NULL && error == 0) {
   4502  1.11       chs 			(void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
   4503  1.11       chs 			    delayprops, errors);
   4504   1.1      haad 		}
   4505   1.1      haad 	}
   4506   1.1      haad 
   4507  1.11       chs 	if (delayprops != NULL) {
   4508  1.11       chs 		/*
   4509  1.11       chs 		 * Merge delayed props back in with initial props, in case
   4510  1.11       chs 		 * we're DEBUG and zfs_ioc_recv_inject_err is set (which means
   4511  1.11       chs 		 * we have to make sure clear_received_props() includes
   4512  1.11       chs 		 * the delayed properties).
   4513  1.11       chs 		 *
   4514  1.11       chs 		 * Since zfs_ioc_recv_inject_err is only in DEBUG kernels,
   4515  1.11       chs 		 * using ASSERT() will be just like a VERIFY.
   4516  1.11       chs 		 */
   4517  1.11       chs 		ASSERT(nvlist_merge(props, delayprops, 0) == 0);
   4518  1.11       chs 		nvlist_free(delayprops);
   4519  1.11       chs 	}
   4520  1.11       chs 
   4521  1.11       chs 	/*
   4522  1.11       chs 	 * Now that all props, initial and delayed, are set, report the prop
   4523  1.11       chs 	 * errors to the caller.
   4524  1.11       chs 	 */
   4525  1.11       chs 	if (zc->zc_nvlist_dst_size != 0 &&
   4526  1.11       chs 	    (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
   4527  1.11       chs 	    put_nvlist(zc, errors) != 0)) {
   4528  1.11       chs 		/*
   4529  1.11       chs 		 * Caller made zc->zc_nvlist_dst less than the minimum expected
   4530  1.11       chs 		 * size or supplied an invalid address.
   4531  1.11       chs 		 */
   4532  1.11       chs 		props_error = SET_ERROR(EINVAL);
   4533  1.11       chs 	}
   4534  1.11       chs 
   4535   1.1      haad 	zc->zc_cookie = off - fp->f_offset;
   4536  1.11       chs 	if (off >= 0 && off <= MAXOFFSET_T)
   4537   1.1      haad 		fp->f_offset = off;
   4538   1.1      haad 
   4539   1.4      haad #ifdef	DEBUG
   4540   1.4      haad 	if (zfs_ioc_recv_inject_err) {
   4541   1.4      haad 		zfs_ioc_recv_inject_err = B_FALSE;
   4542   1.4      haad 		error = 1;
   4543   1.4      haad 	}
   4544   1.4      haad #endif
   4545  1.11       chs 
   4546  1.11       chs 	if (error == 0)
   4547  1.11       chs 		zvol_create_minors(tofs);
   4548  1.11       chs 
   4549   1.1      haad 	/*
   4550   1.1      haad 	 * On error, restore the original props.
   4551   1.1      haad 	 */
   4552  1.11       chs 	if (error != 0 && props != NULL && !drc.drc_newfs) {
   4553  1.11       chs 		if (clear_received_props(tofs, props, NULL) != 0) {
   4554  1.11       chs 			/*
   4555  1.11       chs 			 * We failed to clear the received properties.
   4556  1.11       chs 			 * Since we may have left a $recvd value on the
   4557  1.11       chs 			 * system, we can't clear the $hasrecvd flag.
   4558  1.11       chs 			 */
   4559   1.4      haad 			zc->zc_obj |= ZPROP_ERR_NORESTORE;
   4560  1.11       chs 		} else if (first_recvd_props) {
   4561  1.11       chs 			dsl_prop_unset_hasrecvd(tofs);
   4562   1.4      haad 		}
   4563   1.4      haad 
   4564   1.4      haad 		if (origprops == NULL && !drc.drc_newfs) {
   4565   1.4      haad 			/* We failed to stash the original properties. */
   4566   1.4      haad 			zc->zc_obj |= ZPROP_ERR_NORESTORE;
   4567   1.4      haad 		}
   4568   1.4      haad 
   4569   1.4      haad 		/*
   4570   1.4      haad 		 * dsl_props_set() will not convert RECEIVED to LOCAL on or
   4571   1.4      haad 		 * after SPA_VERSION_RECVD_PROPS, so we need to specify LOCAL
   4572   1.4      haad 		 * explictly if we're restoring local properties cleared in the
   4573   1.4      haad 		 * first new-style receive.
   4574   1.4      haad 		 */
   4575   1.4      haad 		if (origprops != NULL &&
   4576   1.4      haad 		    zfs_set_prop_nvlist(tofs, (first_recvd_props ?
   4577   1.4      haad 		    ZPROP_SRC_LOCAL : ZPROP_SRC_RECEIVED),
   4578   1.4      haad 		    origprops, NULL) != 0) {
   4579   1.4      haad 			/*
   4580   1.4      haad 			 * We stashed the original properties but failed to
   4581   1.4      haad 			 * restore them.
   4582   1.4      haad 			 */
   4583   1.4      haad 			zc->zc_obj |= ZPROP_ERR_NORESTORE;
   4584   1.4      haad 		}
   4585   1.1      haad 	}
   4586   1.1      haad out:
   4587   1.1      haad 	nvlist_free(props);
   4588   1.1      haad 	nvlist_free(origprops);
   4589   1.4      haad 	nvlist_free(errors);
   4590  1.11       chs 	releasef(fd);
   4591   1.4      haad 
   4592   1.4      haad 	if (error == 0)
   4593   1.4      haad 		error = props_error;
   4594   1.4      haad 
   4595   1.1      haad 	return (error);
   4596   1.1      haad }
   4597   1.1      haad 
   4598   1.1      haad /*
   4599   1.1      haad  * inputs:
   4600   1.1      haad  * zc_name	name of snapshot to send
   4601   1.1      haad  * zc_cookie	file descriptor to send stream to
   4602  1.11       chs  * zc_obj	fromorigin flag (mutually exclusive with zc_fromobj)
   4603  1.11       chs  * zc_sendobj	objsetid of snapshot to send
   4604  1.11       chs  * zc_fromobj	objsetid of incremental fromsnap (may be zero)
   4605  1.11       chs  * zc_guid	if set, estimate size of stream only.  zc_cookie is ignored.
   4606  1.11       chs  *		output size in zc_objset_type.
   4607  1.11       chs  * zc_flags	lzc_send_flags
   4608   1.1      haad  *
   4609  1.11       chs  * outputs:
   4610  1.11       chs  * zc_objset_type	estimated size, if zc_guid is set
   4611   1.1      haad  */
   4612   1.1      haad static int
   4613   1.1      haad zfs_ioc_send(zfs_cmd_t *zc)
   4614   1.1      haad {
   4615   1.1      haad 	int error;
   4616   1.1      haad 	offset_t off;
   4617  1.11       chs 	boolean_t estimate = (zc->zc_guid != 0);
   4618  1.11       chs 	boolean_t embedok = (zc->zc_flags & 0x1);
   4619  1.11       chs 	boolean_t large_block_ok = (zc->zc_flags & 0x2);
   4620  1.11       chs 
   4621  1.11       chs 	if (zc->zc_obj != 0) {
   4622  1.11       chs 		dsl_pool_t *dp;
   4623  1.11       chs 		dsl_dataset_t *tosnap;
   4624  1.11       chs 
   4625  1.11       chs 		error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
   4626  1.11       chs 		if (error != 0)
   4627  1.11       chs 			return (error);
   4628  1.11       chs 
   4629  1.11       chs 		error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
   4630  1.11       chs 		if (error != 0) {
   4631  1.11       chs 			dsl_pool_rele(dp, FTAG);
   4632  1.11       chs 			return (error);
   4633  1.11       chs 		}
   4634  1.11       chs 
   4635  1.11       chs 		if (dsl_dir_is_clone(tosnap->ds_dir))
   4636  1.11       chs 			zc->zc_fromobj =
   4637  1.11       chs 			    dsl_dir_phys(tosnap->ds_dir)->dd_origin_obj;
   4638  1.11       chs 		dsl_dataset_rele(tosnap, FTAG);
   4639  1.11       chs 		dsl_pool_rele(dp, FTAG);
   4640  1.11       chs 	}
   4641   1.1      haad 
   4642  1.11       chs 	if (estimate) {
   4643  1.11       chs 		dsl_pool_t *dp;
   4644  1.11       chs 		dsl_dataset_t *tosnap;
   4645  1.11       chs 		dsl_dataset_t *fromsnap = NULL;
   4646  1.11       chs 
   4647  1.11       chs 		error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
   4648  1.11       chs 		if (error != 0)
   4649  1.11       chs 			return (error);
   4650   1.1      haad 
   4651  1.11       chs 		error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
   4652  1.11       chs 		if (error != 0) {
   4653  1.11       chs 			dsl_pool_rele(dp, FTAG);
   4654   1.1      haad 			return (error);
   4655   1.1      haad 		}
   4656  1.11       chs 
   4657  1.11       chs 		if (zc->zc_fromobj != 0) {
   4658  1.11       chs 			error = dsl_dataset_hold_obj(dp, zc->zc_fromobj,
   4659  1.11       chs 			    FTAG, &fromsnap);
   4660  1.11       chs 			if (error != 0) {
   4661  1.11       chs 				dsl_dataset_rele(tosnap, FTAG);
   4662  1.11       chs 				dsl_pool_rele(dp, FTAG);
   4663  1.11       chs 				return (error);
   4664  1.11       chs 			}
   4665  1.11       chs 		}
   4666  1.11       chs 
   4667  1.11       chs 		error = dmu_send_estimate(tosnap, fromsnap,
   4668  1.11       chs 		    &zc->zc_objset_type);
   4669  1.11       chs 
   4670  1.11       chs 		if (fromsnap != NULL)
   4671  1.11       chs 			dsl_dataset_rele(fromsnap, FTAG);
   4672  1.11       chs 		dsl_dataset_rele(tosnap, FTAG);
   4673  1.11       chs 		dsl_pool_rele(dp, FTAG);
   4674  1.11       chs 	} else {
   4675  1.11       chs 		file_t *fp;
   4676  1.11       chs #ifdef __FreeBSD__
   4677  1.11       chs 		cap_rights_t rights;
   4678  1.11       chs 
   4679  1.11       chs 		fget_write(curthread, zc->zc_cookie,
   4680  1.11       chs 		    cap_rights_init(&rights, CAP_WRITE), &fp);
   4681  1.11       chs #else
   4682  1.11       chs 		fp = getf(zc->zc_cookie);
   4683  1.11       chs #endif
   4684  1.11       chs 		if (fp == NULL)
   4685  1.11       chs 			return (SET_ERROR(EBADF));
   4686  1.11       chs 
   4687  1.11       chs 		off = fp->f_offset;
   4688  1.11       chs 		error = dmu_send_obj(zc->zc_name, zc->zc_sendobj,
   4689  1.11       chs 		    zc->zc_fromobj, embedok, large_block_ok,
   4690  1.11       chs #ifdef illumos
   4691  1.11       chs 		    zc->zc_cookie, fp->f_vnode, &off);
   4692  1.11       chs #else
   4693  1.11       chs 		    zc->zc_cookie, fp, &off);
   4694  1.11       chs #endif
   4695  1.11       chs 
   4696  1.11       chs 		if (off >= 0 && off <= MAXOFFSET_T)
   4697  1.11       chs 			fp->f_offset = off;
   4698  1.11       chs 		releasef(zc->zc_cookie);
   4699   1.1      haad 	}
   4700  1.11       chs 	return (error);
   4701  1.11       chs }
   4702  1.11       chs 
   4703  1.11       chs /*
   4704  1.11       chs  * inputs:
   4705  1.11       chs  * zc_name	name of snapshot on which to report progress
   4706  1.11       chs  * zc_cookie	file descriptor of send stream
   4707  1.11       chs  *
   4708  1.11       chs  * outputs:
   4709  1.11       chs  * zc_cookie	number of bytes written in send stream thus far
   4710  1.11       chs  */
   4711  1.11       chs static int
   4712  1.11       chs zfs_ioc_send_progress(zfs_cmd_t *zc)
   4713  1.11       chs {
   4714  1.11       chs 	dsl_pool_t *dp;
   4715  1.11       chs 	dsl_dataset_t *ds;
   4716  1.11       chs 	dmu_sendarg_t *dsp = NULL;
   4717  1.11       chs 	int error;
   4718  1.11       chs 
   4719  1.11       chs 	error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
   4720  1.11       chs 	if (error != 0)
   4721  1.11       chs 		return (error);
   4722   1.1      haad 
   4723  1.11       chs 	error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &ds);
   4724   1.2      haad 	if (error != 0) {
   4725  1.11       chs 		dsl_pool_rele(dp, FTAG);
   4726   1.2      haad 		return (error);
   4727   1.1      haad 	}
   4728   1.1      haad 
   4729  1.11       chs 	mutex_enter(&ds->ds_sendstream_lock);
   4730  1.11       chs 
   4731  1.11       chs 	/*
   4732  1.11       chs 	 * Iterate over all the send streams currently active on this dataset.
   4733  1.11       chs 	 * If there's one which matches the specified file descriptor _and_ the
   4734  1.11       chs 	 * stream was started by the current process, return the progress of
   4735  1.11       chs 	 * that stream.
   4736  1.11       chs 	 */
   4737  1.11       chs 	for (dsp = list_head(&ds->ds_sendstreams); dsp != NULL;
   4738  1.11       chs 	    dsp = list_next(&ds->ds_sendstreams, dsp)) {
   4739  1.11       chs 		if (dsp->dsa_outfd == zc->zc_cookie &&
   4740  1.11       chs 		    dsp->dsa_proc == curproc)
   4741  1.11       chs 			break;
   4742  1.11       chs 	}
   4743  1.11       chs 
   4744  1.11       chs 	if (dsp != NULL)
   4745  1.11       chs 		zc->zc_cookie = *(dsp->dsa_off);
   4746  1.11       chs 	else
   4747  1.11       chs 		error = SET_ERROR(ENOENT);
   4748   1.1      haad 
   4749  1.11       chs 	mutex_exit(&ds->ds_sendstream_lock);
   4750  1.11       chs 	dsl_dataset_rele(ds, FTAG);
   4751  1.11       chs 	dsl_pool_rele(dp, FTAG);
   4752   1.1      haad 	return (error);
   4753   1.1      haad }
   4754   1.1      haad 
   4755   1.1      haad static int
   4756   1.1      haad zfs_ioc_inject_fault(zfs_cmd_t *zc)
   4757   1.1      haad {
   4758   1.1      haad 	int id, error;
   4759   1.1      haad 
   4760   1.1      haad 	error = zio_inject_fault(zc->zc_name, (int)zc->zc_guid, &id,
   4761   1.1      haad 	    &zc->zc_inject_record);
   4762   1.1      haad 
   4763   1.1      haad 	if (error == 0)
   4764   1.1      haad 		zc->zc_guid = (uint64_t)id;
   4765   1.1      haad 
   4766   1.1      haad 	return (error);
   4767   1.1      haad }
   4768   1.1      haad 
   4769   1.1      haad static int
   4770   1.1      haad zfs_ioc_clear_fault(zfs_cmd_t *zc)
   4771   1.1      haad {
   4772   1.1      haad 	return (zio_clear_fault((int)zc->zc_guid));
   4773   1.1      haad }
   4774   1.1      haad 
   4775   1.1      haad static int
   4776   1.1      haad zfs_ioc_inject_list_next(zfs_cmd_t *zc)
   4777   1.1      haad {
   4778   1.1      haad 	int id = (int)zc->zc_guid;
   4779   1.1      haad 	int error;
   4780   1.1      haad 
   4781   1.1      haad 	error = zio_inject_list_next(&id, zc->zc_name, sizeof (zc->zc_name),
   4782   1.1      haad 	    &zc->zc_inject_record);
   4783   1.1      haad 
   4784   1.1      haad 	zc->zc_guid = id;
   4785   1.1      haad 
   4786   1.1      haad 	return (error);
   4787   1.1      haad }
   4788   1.1      haad 
   4789   1.1      haad static int
   4790   1.1      haad zfs_ioc_error_log(zfs_cmd_t *zc)
   4791   1.1      haad {
   4792   1.1      haad 	spa_t *spa;
   4793   1.1      haad 	int error;
   4794   1.1      haad 	size_t count = (size_t)zc->zc_nvlist_dst_size;
   4795   1.1      haad 
   4796   1.1      haad 	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
   4797   1.1      haad 		return (error);
   4798   1.1      haad 
   4799   1.1      haad 	error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst,
   4800   1.1      haad 	    &count);
   4801   1.1      haad 	if (error == 0)
   4802   1.1      haad 		zc->zc_nvlist_dst_size = count;
   4803   1.1      haad 	else
   4804   1.1      haad 		zc->zc_nvlist_dst_size = spa_get_errlog_size(spa);
   4805   1.1      haad 
   4806   1.1      haad 	spa_close(spa, FTAG);
   4807   1.1      haad 
   4808   1.1      haad 	return (error);
   4809   1.1      haad }
   4810   1.1      haad 
   4811   1.1      haad static int
   4812   1.1      haad zfs_ioc_clear(zfs_cmd_t *zc)
   4813   1.1      haad {
   4814   1.1      haad 	spa_t *spa;
   4815   1.1      haad 	vdev_t *vd;
   4816   1.1      haad 	int error;
   4817   1.1      haad 
   4818   1.1      haad 	/*
   4819   1.1      haad 	 * On zpool clear we also fix up missing slogs
   4820   1.1      haad 	 */
   4821   1.1      haad 	mutex_enter(&spa_namespace_lock);
   4822   1.1      haad 	spa = spa_lookup(zc->zc_name);
   4823   1.1      haad 	if (spa == NULL) {
   4824   1.1      haad 		mutex_exit(&spa_namespace_lock);
   4825  1.11       chs 		return (SET_ERROR(EIO));
   4826   1.1      haad 	}
   4827   1.4      haad 	if (spa_get_log_state(spa) == SPA_LOG_MISSING) {
   4828   1.1      haad 		/* we need to let spa_open/spa_load clear the chains */
   4829   1.4      haad 		spa_set_log_state(spa, SPA_LOG_CLEAR);
   4830   1.1      haad 	}
   4831   1.4      haad 	spa->spa_last_open_failed = 0;
   4832   1.1      haad 	mutex_exit(&spa_namespace_lock);
   4833   1.1      haad 
   4834   1.4      haad 	if (zc->zc_cookie & ZPOOL_NO_REWIND) {
   4835   1.4      haad 		error = spa_open(zc->zc_name, &spa, FTAG);
   4836   1.4      haad 	} else {
   4837   1.4      haad 		nvlist_t *policy;
   4838   1.4      haad 		nvlist_t *config = NULL;
   4839   1.4      haad 
   4840   1.8  christos 		if (zc->zc_nvlist_src == 0)
   4841  1.11       chs 			return (SET_ERROR(EINVAL));
   4842   1.4      haad 
   4843   1.4      haad 		if ((error = get_nvlist(zc->zc_nvlist_src,
   4844   1.4      haad 		    zc->zc_nvlist_src_size, zc->zc_iflags, &policy)) == 0) {
   4845   1.4      haad 			error = spa_open_rewind(zc->zc_name, &spa, FTAG,
   4846   1.4      haad 			    policy, &config);
   4847   1.4      haad 			if (config != NULL) {
   4848  1.11       chs 				int err;
   4849  1.11       chs 
   4850  1.11       chs 				if ((err = put_nvlist(zc, config)) != 0)
   4851  1.11       chs 					error = err;
   4852   1.4      haad 				nvlist_free(config);
   4853   1.4      haad 			}
   4854   1.4      haad 			nvlist_free(policy);
   4855   1.4      haad 		}
   4856   1.4      haad 	}
   4857   1.4      haad 
   4858  1.11       chs 	if (error != 0)
   4859   1.1      haad 		return (error);
   4860   1.1      haad 
   4861   1.4      haad 	spa_vdev_state_enter(spa, SCL_NONE);
   4862   1.1      haad 
   4863   1.1      haad 	if (zc->zc_guid == 0) {
   4864   1.1      haad 		vd = NULL;
   4865   1.1      haad 	} else {
   4866   1.1      haad 		vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE);
   4867   1.1      haad 		if (vd == NULL) {
   4868   1.1      haad 			(void) spa_vdev_state_exit(spa, NULL, ENODEV);
   4869   1.1      haad 			spa_close(spa, FTAG);
   4870  1.11       chs 			return (SET_ERROR(ENODEV));
   4871   1.1      haad 		}
   4872   1.1      haad 	}
   4873   1.1      haad 
   4874   1.1      haad 	vdev_clear(spa, vd);
   4875   1.1      haad 
   4876   1.1      haad 	(void) spa_vdev_state_exit(spa, NULL, 0);
   4877   1.1      haad 
   4878   1.1      haad 	/*
   4879   1.1      haad 	 * Resume any suspended I/Os.
   4880   1.1      haad 	 */
   4881   1.4      haad 	if (zio_resume(spa) != 0)
   4882  1.11       chs 		error = SET_ERROR(EIO);
   4883   1.1      haad 
   4884   1.1      haad 	spa_close(spa, FTAG);
   4885   1.1      haad 
   4886   1.4      haad 	return (error);
   4887   1.1      haad }
   4888   1.1      haad 
   4889  1.11       chs static int
   4890  1.11       chs zfs_ioc_pool_reopen(zfs_cmd_t *zc)
   4891  1.11       chs {
   4892  1.11       chs 	spa_t *spa;
   4893  1.11       chs 	int error;
   4894  1.11       chs 
   4895  1.11       chs 	error = spa_open(zc->zc_name, &spa, FTAG);
   4896  1.11       chs 	if (error != 0)
   4897  1.11       chs 		return (error);
   4898  1.11       chs 
   4899  1.11       chs 	spa_vdev_state_enter(spa, SCL_NONE);
   4900  1.11       chs 
   4901  1.11       chs 	/*
   4902  1.11       chs 	 * If a resilver is already in progress then set the
   4903  1.11       chs 	 * spa_scrub_reopen flag to B_TRUE so that we don't restart
   4904  1.11       chs 	 * the scan as a side effect of the reopen. Otherwise, let
   4905  1.11       chs 	 * vdev_open() decided if a resilver is required.
   4906  1.11       chs 	 */
   4907  1.11       chs 	spa->spa_scrub_reopen = dsl_scan_resilvering(spa->spa_dsl_pool);
   4908  1.11       chs 	vdev_reopen(spa->spa_root_vdev);
   4909  1.11       chs 	spa->spa_scrub_reopen = B_FALSE;
   4910  1.11       chs 
   4911  1.11       chs 	(void) spa_vdev_state_exit(spa, NULL, 0);
   4912  1.11       chs 	spa_close(spa, FTAG);
   4913  1.11       chs 	return (0);
   4914  1.11       chs }
   4915   1.1      haad /*
   4916   1.1      haad  * inputs:
   4917   1.1      haad  * zc_name	name of filesystem
   4918   1.1      haad  * zc_value	name of origin snapshot
   4919   1.1      haad  *
   4920   1.4      haad  * outputs:
   4921   1.4      haad  * zc_string	name of conflicting snapshot, if there is one
   4922   1.1      haad  */
   4923   1.1      haad static int
   4924   1.1      haad zfs_ioc_promote(zfs_cmd_t *zc)
   4925   1.1      haad {
   4926   1.1      haad 	char *cp;
   4927   1.1      haad 
   4928   1.1      haad 	/*
   4929   1.1      haad 	 * We don't need to unmount *all* the origin fs's snapshots, but
   4930   1.1      haad 	 * it's easier.
   4931   1.1      haad 	 */
   4932   1.1      haad 	cp = strchr(zc->zc_value, '@');
   4933   1.1      haad 	if (cp)
   4934   1.1      haad 		*cp = '\0';
   4935   1.1      haad 	(void) dmu_objset_find(zc->zc_value,
   4936  1.11       chs 	    zfs_unmount_snap_cb, NULL, DS_FIND_SNAPSHOTS);
   4937   1.4      haad 	return (dsl_dataset_promote(zc->zc_name, zc->zc_string));
   4938   1.4      haad }
   4939   1.4      haad 
   4940   1.4      haad /*
   4941   1.4      haad  * Retrieve a single {user|group}{used|quota}@... property.
   4942   1.4      haad  *
   4943   1.4      haad  * inputs:
   4944   1.4      haad  * zc_name	name of filesystem
   4945   1.4      haad  * zc_objset_type zfs_userquota_prop_t
   4946   1.4      haad  * zc_value	domain name (eg. "S-1-234-567-89")
   4947   1.4      haad  * zc_guid	RID/UID/GID
   4948   1.4      haad  *
   4949   1.4      haad  * outputs:
   4950   1.4      haad  * zc_cookie	property value
   4951   1.4      haad  */
   4952   1.4      haad static int
   4953   1.4      haad zfs_ioc_userspace_one(zfs_cmd_t *zc)
   4954   1.4      haad {
   4955   1.4      haad 	zfsvfs_t *zfsvfs;
   4956   1.4      haad 	int error;
   4957   1.4      haad 
   4958   1.4      haad 	if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
   4959  1.11       chs 		return (SET_ERROR(EINVAL));
   4960   1.4      haad 
   4961  1.11       chs 	error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
   4962  1.11       chs 	if (error != 0)
   4963   1.4      haad 		return (error);
   4964   1.4      haad 
   4965   1.4      haad 	error = zfs_userspace_one(zfsvfs,
   4966   1.4      haad 	    zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie);
   4967   1.4      haad 	zfsvfs_rele(zfsvfs, FTAG);
   4968   1.4      haad 
   4969   1.4      haad 	return (error);
   4970   1.4      haad }
   4971   1.4      haad 
   4972   1.4      haad /*
   4973   1.4      haad  * inputs:
   4974   1.4      haad  * zc_name		name of filesystem
   4975   1.4      haad  * zc_cookie		zap cursor
   4976   1.4      haad  * zc_objset_type	zfs_userquota_prop_t
   4977   1.4      haad  * zc_nvlist_dst[_size] buffer to fill (not really an nvlist)
   4978   1.4      haad  *
   4979   1.4      haad  * outputs:
   4980   1.4      haad  * zc_nvlist_dst[_size]	data buffer (array of zfs_useracct_t)
   4981   1.4      haad  * zc_cookie	zap cursor
   4982   1.4      haad  */
   4983   1.4      haad static int
   4984   1.4      haad zfs_ioc_userspace_many(zfs_cmd_t *zc)
   4985   1.4      haad {
   4986   1.4      haad 	zfsvfs_t *zfsvfs;
   4987  1.11       chs 	int bufsize = zc->zc_nvlist_dst_size;
   4988  1.11       chs 
   4989  1.11       chs 	if (bufsize <= 0)
   4990  1.11       chs 		return (SET_ERROR(ENOMEM));
   4991   1.4      haad 
   4992  1.11       chs 	int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
   4993  1.11       chs 	if (error != 0)
   4994   1.4      haad 		return (error);
   4995   1.4      haad 
   4996   1.4      haad 	void *buf = kmem_alloc(bufsize, KM_SLEEP);
   4997   1.4      haad 
   4998   1.4      haad 	error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie,
   4999   1.4      haad 	    buf, &zc->zc_nvlist_dst_size);
   5000   1.4      haad 
   5001   1.4      haad 	if (error == 0) {
   5002  1.11       chs 		error = ddi_copyout(buf,
   5003   1.4      haad 		    (void *)(uintptr_t)zc->zc_nvlist_dst,
   5004  1.11       chs 		    zc->zc_nvlist_dst_size, zc->zc_iflags);
   5005   1.4      haad 	}
   5006   1.4      haad 	kmem_free(buf, bufsize);
   5007   1.4      haad 	zfsvfs_rele(zfsvfs, FTAG);
   5008   1.4      haad 
   5009   1.4      haad 	return (error);
   5010   1.4      haad }
   5011   1.4      haad 
   5012   1.4      haad /*
   5013   1.4      haad  * inputs:
   5014   1.4      haad  * zc_name		name of filesystem
   5015   1.4      haad  *
   5016   1.4      haad  * outputs:
   5017   1.4      haad  * none
   5018   1.4      haad  */
   5019   1.4      haad static int
   5020   1.4      haad zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
   5021   1.4      haad {
   5022   1.4      haad 	objset_t *os;
   5023   1.4      haad 	int error = 0;
   5024   1.4      haad 	zfsvfs_t *zfsvfs;
   5025   1.4      haad 
   5026   1.4      haad 	if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
   5027   1.4      haad 		if (!dmu_objset_userused_enabled(zfsvfs->z_os)) {
   5028   1.4      haad 			/*
   5029   1.4      haad 			 * If userused is not enabled, it may be because the
   5030   1.4      haad 			 * objset needs to be closed & reopened (to grow the
   5031   1.4      haad 			 * objset_phys_t).  Suspend/resume the fs will do that.
   5032   1.4      haad 			 */
   5033  1.11       chs 			dsl_dataset_t *ds;
   5034  1.11       chs 
   5035  1.11       chs 			ds = dmu_objset_ds(zfsvfs->z_os);
   5036   1.4      haad 			error = zfs_suspend_fs(zfsvfs);
   5037  1.11       chs 			if (error == 0) {
   5038  1.11       chs 				dmu_objset_refresh_ownership(zfsvfs->z_os,
   5039  1.11       chs 				    zfsvfs);
   5040  1.11       chs 				error = zfs_resume_fs(zfsvfs, ds);
   5041  1.11       chs 			}
   5042   1.4      haad 		}
   5043   1.4      haad 		if (error == 0)
   5044   1.4      haad 			error = dmu_objset_userspace_upgrade(zfsvfs->z_os);
   5045  1.11       chs #ifdef illumos
   5046   1.4      haad 		VFS_RELE(zfsvfs->z_vfs);
   5047  1.11       chs #else
   5048  1.11       chs 		vfs_unbusy(zfsvfs->z_vfs);
   5049  1.11       chs #endif
   5050   1.4      haad 	} else {
   5051   1.4      haad 		/* XXX kind of reading contents without owning */
   5052   1.4      haad 		error = dmu_objset_hold(zc->zc_name, FTAG, &os);
   5053  1.11       chs 		if (error != 0)
   5054   1.4      haad 			return (error);
   5055   1.4      haad 
   5056   1.4      haad 		error = dmu_objset_userspace_upgrade(os);
   5057   1.4      haad 		dmu_objset_rele(os, FTAG);
   5058   1.4      haad 	}
   5059   1.4      haad 
   5060   1.4      haad 	return (error);
   5061   1.1      haad }
   5062   1.1      haad 
   5063  1.11       chs #ifdef illumos
   5064   1.1      haad /*
   5065   1.1      haad  * We don't want to have a hard dependency
   5066   1.1      haad  * against some special symbols in sharefs
   5067   1.1      haad  * nfs, and smbsrv.  Determine them if needed when
   5068   1.1      haad  * the first file system is shared.
   5069   1.1      haad  * Neither sharefs, nfs or smbsrv are unloadable modules.
   5070   1.1      haad  */
   5071   1.1      haad int (*znfsexport_fs)(void *arg);
   5072   1.1      haad int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t);
   5073   1.1      haad int (*zsmbexport_fs)(void *arg, boolean_t add_share);
   5074   1.1      haad 
   5075   1.1      haad int zfs_nfsshare_inited;
   5076   1.1      haad int zfs_smbshare_inited;
   5077   1.1      haad 
   5078   1.1      haad ddi_modhandle_t nfs_mod;
   5079   1.1      haad ddi_modhandle_t sharefs_mod;
   5080   1.1      haad ddi_modhandle_t smbsrv_mod;
   5081  1.11       chs #endif	/* illumos */
   5082   1.1      haad kmutex_t zfs_share_lock;
   5083   1.1      haad 
   5084  1.11       chs #ifdef illumos
   5085   1.1      haad static int
   5086   1.1      haad zfs_init_sharefs()
   5087   1.1      haad {
   5088   1.1      haad 	int error;
   5089   1.1      haad 
   5090   1.1      haad 	ASSERT(MUTEX_HELD(&zfs_share_lock));
   5091   1.1      haad 	/* Both NFS and SMB shares also require sharetab support. */
   5092   1.1      haad 	if (sharefs_mod == NULL && ((sharefs_mod =
   5093   1.1      haad 	    ddi_modopen("fs/sharefs",
   5094   1.1      haad 	    KRTLD_MODE_FIRST, &error)) == NULL)) {
   5095  1.11       chs 		return (SET_ERROR(ENOSYS));
   5096   1.1      haad 	}
   5097   1.1      haad 	if (zshare_fs == NULL && ((zshare_fs =
   5098   1.1      haad 	    (int (*)(enum sharefs_sys_op, share_t *, uint32_t))
   5099   1.1      haad 	    ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) {
   5100  1.11       chs 		return (SET_ERROR(ENOSYS));
   5101   1.1      haad 	}
   5102   1.1      haad 	return (0);
   5103   1.1      haad }
   5104  1.11       chs #endif	/* illumos */
   5105   1.1      haad 
   5106   1.1      haad static int
   5107   1.1      haad zfs_ioc_share(zfs_cmd_t *zc)
   5108   1.1      haad {
   5109  1.11       chs #ifdef illumos
   5110   1.1      haad 	int error;
   5111   1.1      haad 	int opcode;
   5112   1.1      haad 
   5113   1.1      haad 	switch (zc->zc_share.z_sharetype) {
   5114   1.1      haad 	case ZFS_SHARE_NFS:
   5115   1.1      haad 	case ZFS_UNSHARE_NFS:
   5116   1.1      haad 		if (zfs_nfsshare_inited == 0) {
   5117   1.1      haad 			mutex_enter(&zfs_share_lock);
   5118   1.1      haad 			if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs",
   5119   1.1      haad 			    KRTLD_MODE_FIRST, &error)) == NULL)) {
   5120   1.1      haad 				mutex_exit(&zfs_share_lock);
   5121  1.11       chs 				return (SET_ERROR(ENOSYS));
   5122   1.1      haad 			}
   5123   1.1      haad 			if (znfsexport_fs == NULL &&
   5124   1.1      haad 			    ((znfsexport_fs = (int (*)(void *))
   5125   1.1      haad 			    ddi_modsym(nfs_mod,
   5126   1.1      haad 			    "nfs_export", &error)) == NULL)) {
   5127   1.1      haad 				mutex_exit(&zfs_share_lock);
   5128  1.11       chs 				return (SET_ERROR(ENOSYS));
   5129   1.1      haad 			}
   5130   1.1      haad 			error = zfs_init_sharefs();
   5131  1.11       chs 			if (error != 0) {
   5132   1.1      haad 				mutex_exit(&zfs_share_lock);
   5133  1.11       chs 				return (SET_ERROR(ENOSYS));
   5134   1.1      haad 			}
   5135   1.1      haad 			zfs_nfsshare_inited = 1;
   5136   1.1      haad 			mutex_exit(&zfs_share_lock);
   5137   1.1      haad 		}
   5138   1.1      haad 		break;
   5139   1.1      haad 	case ZFS_SHARE_SMB:
   5140   1.1      haad 	case ZFS_UNSHARE_SMB:
   5141   1.1      haad 		if (zfs_smbshare_inited == 0) {
   5142   1.1      haad 			mutex_enter(&zfs_share_lock);
   5143   1.1      haad 			if (smbsrv_mod == NULL && ((smbsrv_mod =
   5144   1.1      haad 			    ddi_modopen("drv/smbsrv",
   5145   1.1      haad 			    KRTLD_MODE_FIRST, &error)) == NULL)) {
   5146   1.1      haad 				mutex_exit(&zfs_share_lock);
   5147  1.11       chs 				return (SET_ERROR(ENOSYS));
   5148   1.1      haad 			}
   5149   1.1      haad 			if (zsmbexport_fs == NULL && ((zsmbexport_fs =
   5150   1.1      haad 			    (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod,
   5151   1.1      haad 			    "smb_server_share", &error)) == NULL)) {
   5152   1.1      haad 				mutex_exit(&zfs_share_lock);
   5153  1.11       chs 				return (SET_ERROR(ENOSYS));
   5154   1.1      haad 			}
   5155   1.1      haad 			error = zfs_init_sharefs();
   5156  1.11       chs 			if (error != 0) {
   5157   1.1      haad 				mutex_exit(&zfs_share_lock);
   5158  1.11       chs 				return (SET_ERROR(ENOSYS));
   5159   1.1      haad 			}
   5160   1.1      haad 			zfs_smbshare_inited = 1;
   5161   1.1      haad 			mutex_exit(&zfs_share_lock);
   5162   1.1      haad 		}
   5163   1.1      haad 		break;
   5164   1.1      haad 	default:
   5165  1.11       chs 		return (SET_ERROR(EINVAL));
   5166   1.1      haad 	}
   5167   1.1      haad 
   5168   1.1      haad 	switch (zc->zc_share.z_sharetype) {
   5169   1.1      haad 	case ZFS_SHARE_NFS:
   5170   1.1      haad 	case ZFS_UNSHARE_NFS:
   5171   1.1      haad 		if (error =
   5172   1.1      haad 		    znfsexport_fs((void *)
   5173   1.1      haad 		    (uintptr_t)zc->zc_share.z_exportdata))
   5174   1.1      haad 			return (error);
   5175   1.1      haad 		break;
   5176   1.1      haad 	case ZFS_SHARE_SMB:
   5177   1.1      haad 	case ZFS_UNSHARE_SMB:
   5178   1.1      haad 		if (error = zsmbexport_fs((void *)
   5179   1.1      haad 		    (uintptr_t)zc->zc_share.z_exportdata,
   5180   1.1      haad 		    zc->zc_share.z_sharetype == ZFS_SHARE_SMB ?
   5181   1.4      haad 		    B_TRUE: B_FALSE)) {
   5182   1.1      haad 			return (error);
   5183   1.1      haad 		}
   5184   1.1      haad 		break;
   5185   1.1      haad 	}
   5186   1.1      haad 
   5187   1.1      haad 	opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS ||
   5188   1.1      haad 	    zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ?
   5189   1.1      haad 	    SHAREFS_ADD : SHAREFS_REMOVE;
   5190   1.1      haad 
   5191   1.1      haad 	/*
   5192   1.1      haad 	 * Add or remove share from sharetab
   5193   1.1      haad 	 */
   5194   1.1      haad 	error = zshare_fs(opcode,
   5195   1.1      haad 	    (void *)(uintptr_t)zc->zc_share.z_sharedata,
   5196   1.1      haad 	    zc->zc_share.z_sharemax);
   5197   1.1      haad 
   5198   1.1      haad 	return (error);
   5199   1.1      haad 
   5200  1.11       chs #else	/* !illumos */
   5201  1.11       chs 	return (ENOSYS);
   5202  1.11       chs #endif	/* illumos */
   5203   1.1      haad }
   5204   1.4      haad 
   5205   1.4      haad ace_t full_access[] = {
   5206   1.4      haad 	{(uid_t)-1, ACE_ALL_PERMS, ACE_EVERYONE, 0}
   5207   1.4      haad };
   5208   1.4      haad 
   5209   1.4      haad /*
   5210  1.11       chs  * inputs:
   5211  1.11       chs  * zc_name		name of containing filesystem
   5212  1.11       chs  * zc_obj		object # beyond which we want next in-use object #
   5213  1.11       chs  *
   5214  1.11       chs  * outputs:
   5215  1.11       chs  * zc_obj		next in-use object #
   5216  1.11       chs  */
   5217  1.11       chs static int
   5218  1.11       chs zfs_ioc_next_obj(zfs_cmd_t *zc)
   5219  1.11       chs {
   5220  1.11       chs 	objset_t *os = NULL;
   5221  1.11       chs 	int error;
   5222  1.11       chs 
   5223  1.11       chs 	error = dmu_objset_hold(zc->zc_name, FTAG, &os);
   5224  1.11       chs 	if (error != 0)
   5225  1.11       chs 		return (error);
   5226  1.11       chs 
   5227  1.11       chs 	error = dmu_object_next(os, &zc->zc_obj, B_FALSE,
   5228  1.11       chs 	    dsl_dataset_phys(os->os_dsl_dataset)->ds_prev_snap_txg);
   5229  1.11       chs 
   5230  1.11       chs 	dmu_objset_rele(os, FTAG);
   5231  1.11       chs 	return (error);
   5232  1.11       chs }
   5233  1.11       chs 
   5234  1.11       chs /*
   5235  1.11       chs  * inputs:
   5236  1.11       chs  * zc_name		name of filesystem
   5237  1.11       chs  * zc_value		prefix name for snapshot
   5238  1.11       chs  * zc_cleanup_fd	cleanup-on-exit file descriptor for calling process
   5239  1.11       chs  *
   5240  1.11       chs  * outputs:
   5241  1.11       chs  * zc_value		short name of new snapshot
   5242  1.11       chs  */
   5243  1.11       chs static int
   5244  1.11       chs zfs_ioc_tmp_snapshot(zfs_cmd_t *zc)
   5245  1.11       chs {
   5246  1.11       chs 	char *snap_name;
   5247  1.11       chs 	char *hold_name;
   5248  1.11       chs 	int error;
   5249  1.11       chs 	minor_t minor;
   5250  1.11       chs 
   5251  1.11       chs 	error = zfs_onexit_fd_hold(zc->zc_cleanup_fd, &minor);
   5252  1.11       chs 	if (error != 0)
   5253  1.11       chs 		return (error);
   5254  1.11       chs 
   5255  1.11       chs 	snap_name = kmem_asprintf("%s-%016llx", zc->zc_value,
   5256  1.11       chs 	    (u_longlong_t)ddi_get_lbolt64());
   5257  1.11       chs 	hold_name = kmem_asprintf("%%%s", zc->zc_value);
   5258  1.11       chs 
   5259  1.11       chs 	error = dsl_dataset_snapshot_tmp(zc->zc_name, snap_name, minor,
   5260  1.11       chs 	    hold_name);
   5261  1.11       chs 	if (error == 0)
   5262  1.11       chs 		(void) strcpy(zc->zc_value, snap_name);
   5263  1.11       chs 	strfree(snap_name);
   5264  1.11       chs 	strfree(hold_name);
   5265  1.11       chs 	zfs_onexit_fd_rele(zc->zc_cleanup_fd);
   5266  1.11       chs 	return (error);
   5267  1.11       chs }
   5268  1.11       chs 
   5269  1.11       chs /*
   5270  1.11       chs  * inputs:
   5271  1.11       chs  * zc_name		name of "to" snapshot
   5272  1.11       chs  * zc_value		name of "from" snapshot
   5273  1.11       chs  * zc_cookie		file descriptor to write diff data on
   5274  1.11       chs  *
   5275  1.11       chs  * outputs:
   5276  1.11       chs  * dmu_diff_record_t's to the file descriptor
   5277  1.11       chs  */
   5278  1.11       chs static int
   5279  1.11       chs zfs_ioc_diff(zfs_cmd_t *zc)
   5280  1.11       chs {
   5281  1.11       chs 	file_t *fp;
   5282  1.11       chs 	offset_t off;
   5283  1.11       chs 	int error;
   5284  1.11       chs 
   5285  1.11       chs #ifdef __FreeBSD__
   5286  1.11       chs 	cap_rights_t rights;
   5287  1.11       chs 
   5288  1.11       chs 	fget_write(curthread, zc->zc_cookie,
   5289  1.11       chs 		    cap_rights_init(&rights, CAP_WRITE), &fp);
   5290  1.11       chs #else
   5291  1.11       chs 	fp = getf(zc->zc_cookie);
   5292  1.11       chs #endif
   5293  1.11       chs 	if (fp == NULL)
   5294  1.11       chs 		return (SET_ERROR(EBADF));
   5295  1.11       chs 
   5296  1.11       chs 	off = fp->f_offset;
   5297  1.11       chs 
   5298  1.11       chs 	error = dmu_diff(zc->zc_name, zc->zc_value, fp, &off);
   5299  1.11       chs 
   5300  1.11       chs 	if (off >= 0 && off <= MAXOFFSET_T)
   5301  1.11       chs 		fp->f_offset = off;
   5302  1.11       chs 	releasef(zc->zc_cookie);
   5303  1.11       chs 
   5304  1.11       chs 	return (error);
   5305  1.11       chs }
   5306  1.11       chs 
   5307  1.11       chs #ifdef illumos
   5308  1.11       chs /*
   5309   1.4      haad  * Remove all ACL files in shares dir
   5310   1.4      haad  */
   5311   1.4      haad static int
   5312   1.4      haad zfs_smb_acl_purge(znode_t *dzp)
   5313   1.4      haad {
   5314   1.4      haad 	zap_cursor_t	zc;
   5315   1.4      haad 	zap_attribute_t	zap;
   5316   1.4      haad 	zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
   5317   1.4      haad 	int error;
   5318   1.4      haad 
   5319   1.4      haad 	for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
   5320   1.4      haad 	    (error = zap_cursor_retrieve(&zc, &zap)) == 0;
   5321   1.4      haad 	    zap_cursor_advance(&zc)) {
   5322   1.4      haad 		if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred,
   5323   1.4      haad 		    NULL, 0)) != 0)
   5324   1.4      haad 			break;
   5325   1.4      haad 	}
   5326   1.4      haad 	zap_cursor_fini(&zc);
   5327   1.4      haad 	return (error);
   5328   1.4      haad }
   5329  1.11       chs #endif	/* illumos */
   5330   1.4      haad 
   5331   1.4      haad static int
   5332   1.4      haad zfs_ioc_smb_acl(zfs_cmd_t *zc)
   5333   1.4      haad {
   5334  1.11       chs #ifdef illumos
   5335   1.4      haad 	vnode_t *vp;
   5336   1.4      haad 	znode_t *dzp;
   5337   1.4      haad 	vnode_t *resourcevp = NULL;
   5338   1.4      haad 	znode_t *sharedir;
   5339   1.4      haad 	zfsvfs_t *zfsvfs;
   5340   1.4      haad 	nvlist_t *nvlist;
   5341   1.4      haad 	char *src, *target;
   5342   1.4      haad 	vattr_t vattr;
   5343   1.4      haad 	vsecattr_t vsec;
   5344   1.4      haad 	int error = 0;
   5345   1.4      haad 
   5346   1.4      haad 	if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
   5347  1.11       chs 	    NO_FOLLOW, NULL, &vp)) != 0)
   5348   1.4      haad 		return (error);
   5349   1.4      haad 
   5350   1.4      haad 	/* Now make sure mntpnt and dataset are ZFS */
   5351  1.11       chs 
   5352  1.11       chs 	if (strcmp(vp->v_vfsp->mnt_stat.f_fstypename, "zfs") != 0 ||
   5353   1.4      haad 	    (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
   5354   1.4      haad 	    zc->zc_name) != 0)) {
   5355   1.4      haad 		VN_RELE(vp);
   5356  1.11       chs 		return (SET_ERROR(EINVAL));
   5357   1.4      haad 	}
   5358  1.11       chs 
   5359   1.4      haad 	dzp = VTOZ(vp);
   5360   1.4      haad 	zfsvfs = dzp->z_zfsvfs;
   5361   1.4      haad 	ZFS_ENTER(zfsvfs);
   5362   1.4      haad 
   5363   1.4      haad 	/*
   5364   1.4      haad 	 * Create share dir if its missing.
   5365   1.4      haad 	 */
   5366   1.4      haad 	mutex_enter(&zfsvfs->z_lock);
   5367   1.4      haad 	if (zfsvfs->z_shares_dir == 0) {
   5368   1.4      haad 		dmu_tx_t *tx;
   5369   1.4      haad 
   5370   1.4      haad 		tx = dmu_tx_create(zfsvfs->z_os);
   5371   1.4      haad 		dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE,
   5372   1.4      haad 		    ZFS_SHARES_DIR);
   5373   1.4      haad 		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
   5374   1.4      haad 		error = dmu_tx_assign(tx, TXG_WAIT);
   5375  1.11       chs 		if (error != 0) {
   5376   1.4      haad 			dmu_tx_abort(tx);
   5377   1.4      haad 		} else {
   5378   1.4      haad 			error = zfs_create_share_dir(zfsvfs, tx);
   5379   1.4      haad 			dmu_tx_commit(tx);
   5380   1.4      haad 		}
   5381  1.11       chs 		if (error != 0) {
   5382   1.4      haad 			mutex_exit(&zfsvfs->z_lock);
   5383   1.4      haad 			VN_RELE(vp);
   5384   1.4      haad 			ZFS_EXIT(zfsvfs);
   5385   1.4      haad 			return (error);
   5386   1.4      haad 		}
   5387   1.4      haad 	}
   5388   1.4      haad 	mutex_exit(&zfsvfs->z_lock);
   5389   1.4      haad 
   5390   1.4      haad 	ASSERT(zfsvfs->z_shares_dir);
   5391   1.4      haad 	if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &sharedir)) != 0) {
   5392   1.4      haad 		VN_RELE(vp);
   5393   1.4      haad 		ZFS_EXIT(zfsvfs);
   5394   1.4      haad 		return (error);
   5395   1.4      haad 	}
   5396   1.4      haad 
   5397   1.4      haad 	switch (zc->zc_cookie) {
   5398   1.4      haad 	case ZFS_SMB_ACL_ADD:
   5399   1.4      haad 		vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
   5400   1.4      haad 		vattr.va_type = VREG;
   5401   1.4      haad 		vattr.va_mode = S_IFREG|0777;
   5402   1.4      haad 		vattr.va_uid = 0;
   5403   1.4      haad 		vattr.va_gid = 0;
   5404   1.4      haad 
   5405   1.4      haad 		vsec.vsa_mask = VSA_ACE;
   5406   1.4      haad 		vsec.vsa_aclentp = &full_access;
   5407   1.4      haad 		vsec.vsa_aclentsz = sizeof (full_access);
   5408   1.4      haad 		vsec.vsa_aclcnt = 1;
   5409   1.4      haad 
   5410   1.4      haad 		error = VOP_CREATE(ZTOV(sharedir), zc->zc_string,
   5411   1.4      haad 		    &vattr, EXCL, 0, &resourcevp, kcred, 0, NULL, &vsec);
   5412   1.4      haad 		if (resourcevp)
   5413   1.4      haad 			VN_RELE(resourcevp);
   5414   1.4      haad 		break;
   5415   1.4      haad 
   5416   1.4      haad 	case ZFS_SMB_ACL_REMOVE:
   5417   1.4      haad 		error = VOP_REMOVE(ZTOV(sharedir), zc->zc_string, kcred,
   5418   1.4      haad 		    NULL, 0);
   5419   1.4      haad 		break;
   5420   1.4      haad 
   5421   1.4      haad 	case ZFS_SMB_ACL_RENAME:
   5422   1.4      haad 		if ((error = get_nvlist(zc->zc_nvlist_src,
   5423   1.4      haad 		    zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) {
   5424   1.4      haad 			VN_RELE(vp);
   5425  1.11       chs 			VN_RELE(ZTOV(sharedir));
   5426   1.4      haad 			ZFS_EXIT(zfsvfs);
   5427   1.4      haad 			return (error);
   5428   1.4      haad 		}
   5429   1.4      haad 		if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
   5430   1.4      haad 		    nvlist_lookup_string(nvlist, ZFS_SMB_ACL_TARGET,
   5431   1.4      haad 		    &target)) {
   5432   1.4      haad 			VN_RELE(vp);
   5433   1.4      haad 			VN_RELE(ZTOV(sharedir));
   5434   1.4      haad 			ZFS_EXIT(zfsvfs);
   5435   1.4      haad 			nvlist_free(nvlist);
   5436   1.4      haad 			return (error);
   5437   1.4      haad 		}
   5438   1.4      haad 		error = VOP_RENAME(ZTOV(sharedir), src, ZTOV(sharedir), target,
   5439   1.4      haad 		    kcred, NULL, 0);
   5440   1.4      haad 		nvlist_free(nvlist);
   5441   1.4      haad 		break;
   5442   1.4      haad 
   5443   1.4      haad 	case ZFS_SMB_ACL_PURGE:
   5444   1.4      haad 		error = zfs_smb_acl_purge(sharedir);
   5445   1.4      haad 		break;
   5446   1.4      haad 
   5447   1.4      haad 	default:
   5448  1.11       chs 		error = SET_ERROR(EINVAL);
   5449   1.4      haad 		break;
   5450   1.4      haad 	}
   5451   1.4      haad 
   5452   1.4      haad 	VN_RELE(vp);
   5453   1.4      haad 	VN_RELE(ZTOV(sharedir));
   5454   1.4      haad 
   5455   1.4      haad 	ZFS_EXIT(zfsvfs);
   5456   1.4      haad 
   5457   1.4      haad 	return (error);
   5458  1.11       chs #else	/* !illumos */
   5459  1.11       chs 	return (EOPNOTSUPP);
   5460  1.11       chs #endif	/* illumos */
   5461   1.4      haad }
   5462   1.1      haad 
   5463   1.1      haad /*
   5464  1.11       chs  * innvl: {
   5465  1.11       chs  *     "holds" -> { snapname -> holdname (string), ... }
   5466  1.11       chs  *     (optional) "cleanup_fd" -> fd (int32)
   5467  1.11       chs  * }
   5468   1.4      haad  *
   5469  1.11       chs  * outnvl: {
   5470  1.11       chs  *     snapname -> error value (int32)
   5471  1.11       chs  *     ...
   5472  1.11       chs  * }
   5473   1.4      haad  */
   5474  1.11       chs /* ARGSUSED */
   5475   1.4      haad static int
   5476  1.11       chs zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
   5477   1.4      haad {
   5478  1.11       chs 	nvpair_t *pair;
   5479  1.11       chs 	nvlist_t *holds;
   5480  1.11       chs 	int cleanup_fd = -1;
   5481  1.11       chs 	int error;
   5482  1.11       chs 	minor_t minor = 0;
   5483  1.11       chs 
   5484  1.11       chs 	error = nvlist_lookup_nvlist(args, "holds", &holds);
   5485  1.11       chs 	if (error != 0)
   5486  1.11       chs 		return (SET_ERROR(EINVAL));
   5487  1.11       chs 
   5488  1.11       chs 	/* make sure the user didn't pass us any invalid (empty) tags */
   5489  1.11       chs 	for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
   5490  1.11       chs 	    pair = nvlist_next_nvpair(holds, pair)) {
   5491  1.11       chs 		char *htag;
   5492  1.11       chs 
   5493  1.11       chs 		error = nvpair_value_string(pair, &htag);
   5494  1.11       chs 		if (error != 0)
   5495  1.11       chs 			return (SET_ERROR(error));
   5496  1.11       chs 
   5497  1.11       chs 		if (strlen(htag) == 0)
   5498  1.11       chs 			return (SET_ERROR(EINVAL));
   5499  1.11       chs 	}
   5500   1.4      haad 
   5501  1.11       chs 	if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) {
   5502  1.11       chs 		error = zfs_onexit_fd_hold(cleanup_fd, &minor);
   5503  1.11       chs 		if (error != 0)
   5504  1.11       chs 			return (error);
   5505  1.11       chs 	}
   5506   1.4      haad 
   5507  1.11       chs 	error = dsl_dataset_user_hold(holds, minor, errlist);
   5508  1.11       chs 	if (minor != 0)
   5509  1.11       chs 		zfs_onexit_fd_rele(cleanup_fd);
   5510  1.11       chs 	return (error);
   5511   1.4      haad }
   5512   1.4      haad 
   5513   1.4      haad /*
   5514  1.11       chs  * innvl is not used.
   5515   1.4      haad  *
   5516  1.11       chs  * outnvl: {
   5517  1.11       chs  *    holdname -> time added (uint64 seconds since epoch)
   5518  1.11       chs  *    ...
   5519  1.11       chs  * }
   5520   1.4      haad  */
   5521  1.11       chs /* ARGSUSED */
   5522   1.4      haad static int
   5523  1.11       chs zfs_ioc_get_holds(const char *snapname, nvlist_t *args, nvlist_t *outnvl)
   5524   1.4      haad {
   5525  1.11       chs 	return (dsl_dataset_get_holds(snapname, outnvl));
   5526   1.4      haad }
   5527   1.4      haad 
   5528   1.4      haad /*
   5529  1.11       chs  * innvl: {
   5530  1.11       chs  *     snapname -> { holdname, ... }
   5531  1.11       chs  *     ...
   5532  1.11       chs  * }
   5533   1.4      haad  *
   5534  1.11       chs  * outnvl: {
   5535  1.11       chs  *     snapname -> error value (int32)
   5536  1.11       chs  *     ...
   5537  1.11       chs  * }
   5538   1.4      haad  */
   5539  1.11       chs /* ARGSUSED */
   5540   1.4      haad static int
   5541  1.11       chs zfs_ioc_release(const char *pool, nvlist_t *holds, nvlist_t *errlist)
   5542  1.11       chs {
   5543  1.11       chs 	return (dsl_dataset_user_release(holds, errlist));
   5544  1.11       chs }
   5545  1.11       chs 
   5546  1.11       chs /*
   5547  1.11       chs  * inputs:
   5548  1.11       chs  * zc_name		name of new filesystem or snapshot
   5549  1.11       chs  * zc_value		full name of old snapshot
   5550  1.11       chs  *
   5551  1.11       chs  * outputs:
   5552  1.11       chs  * zc_cookie		space in bytes
   5553  1.11       chs  * zc_objset_type	compressed space in bytes
   5554  1.11       chs  * zc_perm_action	uncompressed space in bytes
   5555  1.11       chs  */
   5556  1.11       chs static int
   5557  1.11       chs zfs_ioc_space_written(zfs_cmd_t *zc)
   5558   1.4      haad {
   5559   1.4      haad 	int error;
   5560  1.11       chs 	dsl_pool_t *dp;
   5561  1.11       chs 	dsl_dataset_t *new, *old;
   5562   1.4      haad 
   5563  1.11       chs 	error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
   5564  1.11       chs 	if (error != 0)
   5565  1.11       chs 		return (error);
   5566  1.11       chs 	error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &new);
   5567  1.11       chs 	if (error != 0) {
   5568  1.11       chs 		dsl_pool_rele(dp, FTAG);
   5569  1.11       chs 		return (error);
   5570  1.11       chs 	}
   5571  1.11       chs 	error = dsl_dataset_hold(dp, zc->zc_value, FTAG, &old);
   5572  1.11       chs 	if (error != 0) {
   5573  1.11       chs 		dsl_dataset_rele(new, FTAG);
   5574  1.11       chs 		dsl_pool_rele(dp, FTAG);
   5575  1.11       chs 		return (error);
   5576   1.4      haad 	}
   5577   1.4      haad 
   5578  1.11       chs 	error = dsl_dataset_space_written(old, new, &zc->zc_cookie,
   5579  1.11       chs 	    &zc->zc_objset_type, &zc->zc_perm_action);
   5580  1.11       chs 	dsl_dataset_rele(old, FTAG);
   5581  1.11       chs 	dsl_dataset_rele(new, FTAG);
   5582  1.11       chs 	dsl_pool_rele(dp, FTAG);
   5583   1.4      haad 	return (error);
   5584   1.4      haad }
   5585   1.4      haad 
   5586   1.4      haad /*
   5587  1.11       chs  * innvl: {
   5588  1.11       chs  *     "firstsnap" -> snapshot name
   5589  1.11       chs  * }
   5590  1.11       chs  *
   5591  1.11       chs  * outnvl: {
   5592  1.11       chs  *     "used" -> space in bytes
   5593  1.11       chs  *     "compressed" -> compressed space in bytes
   5594  1.11       chs  *     "uncompressed" -> uncompressed space in bytes
   5595  1.11       chs  * }
   5596  1.11       chs  */
   5597  1.11       chs static int
   5598  1.11       chs zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t *outnvl)
   5599   1.4      haad {
   5600   1.4      haad 	int error;
   5601  1.11       chs 	dsl_pool_t *dp;
   5602  1.11       chs 	dsl_dataset_t *new, *old;
   5603  1.11       chs 	char *firstsnap;
   5604  1.11       chs 	uint64_t used, comp, uncomp;
   5605   1.4      haad 
   5606  1.11       chs 	if (nvlist_lookup_string(innvl, "firstsnap", &firstsnap) != 0)
   5607  1.11       chs 		return (SET_ERROR(EINVAL));
   5608  1.11       chs 
   5609  1.11       chs 	error = dsl_pool_hold(lastsnap, FTAG, &dp);
   5610  1.11       chs 	if (error != 0)
   5611  1.11       chs 		return (error);
   5612   1.4      haad 
   5613  1.11       chs 	error = dsl_dataset_hold(dp, lastsnap, FTAG, &new);
   5614  1.11       chs 	if (error == 0 && !new->ds_is_snapshot) {
   5615  1.11       chs 		dsl_dataset_rele(new, FTAG);
   5616  1.11       chs 		error = SET_ERROR(EINVAL);
   5617  1.11       chs 	}
   5618  1.11       chs 	if (error != 0) {
   5619  1.11       chs 		dsl_pool_rele(dp, FTAG);
   5620  1.11       chs 		return (error);
   5621  1.11       chs 	}
   5622  1.11       chs 	error = dsl_dataset_hold(dp, firstsnap, FTAG, &old);
   5623  1.11       chs 	if (error == 0 && !old->ds_is_snapshot) {
   5624  1.11       chs 		dsl_dataset_rele(old, FTAG);
   5625  1.11       chs 		error = SET_ERROR(EINVAL);
   5626  1.11       chs 	}
   5627  1.11       chs 	if (error != 0) {
   5628  1.11       chs 		dsl_dataset_rele(new, FTAG);
   5629  1.11       chs 		dsl_pool_rele(dp, FTAG);
   5630  1.11       chs 		return (error);
   5631   1.4      haad 	}
   5632  1.11       chs 
   5633  1.11       chs 	error = dsl_dataset_space_wouldfree(old, new, &used, &comp, &uncomp);
   5634  1.11       chs 	dsl_dataset_rele(old, FTAG);
   5635  1.11       chs 	dsl_dataset_rele(new, FTAG);
   5636  1.11       chs 	dsl_pool_rele(dp, FTAG);
   5637  1.11       chs 	fnvlist_add_uint64(outnvl, "used", used);
   5638  1.11       chs 	fnvlist_add_uint64(outnvl, "compressed", comp);
   5639  1.11       chs 	fnvlist_add_uint64(outnvl, "uncompressed", uncomp);
   5640   1.4      haad 	return (error);
   5641   1.4      haad }
   5642   1.4      haad 
   5643  1.11       chs #ifdef __FreeBSD__
   5644  1.11       chs 
   5645  1.11       chs static int
   5646  1.11       chs zfs_ioc_jail(zfs_cmd_t *zc)
   5647  1.11       chs {
   5648  1.11       chs 
   5649  1.11       chs 	return (zone_dataset_attach(curthread->td_ucred, zc->zc_name,
   5650  1.11       chs 	    (int)zc->zc_jailid));
   5651  1.11       chs }
   5652  1.11       chs 
   5653  1.11       chs static int
   5654  1.11       chs zfs_ioc_unjail(zfs_cmd_t *zc)
   5655  1.11       chs {
   5656  1.11       chs 
   5657  1.11       chs 	return (zone_dataset_detach(curthread->td_ucred, zc->zc_name,
   5658  1.11       chs 	    (int)zc->zc_jailid));
   5659  1.11       chs }
   5660  1.11       chs 
   5661  1.11       chs #endif
   5662  1.11       chs 
   5663  1.11       chs /*
   5664  1.11       chs  * innvl: {
   5665  1.11       chs  *     "fd" -> file descriptor to write stream to (int32)
   5666  1.11       chs  *     (optional) "fromsnap" -> full snap name to send an incremental from
   5667  1.11       chs  *     (optional) "largeblockok" -> (value ignored)
   5668  1.11       chs  *         indicates that blocks > 128KB are permitted
   5669  1.11       chs  *     (optional) "embedok" -> (value ignored)
   5670  1.11       chs  *         presence indicates DRR_WRITE_EMBEDDED records are permitted
   5671  1.11       chs  *     (optional) "resume_object" and "resume_offset" -> (uint64)
   5672  1.11       chs  *         if present, resume send stream from specified object and offset.
   5673  1.11       chs  * }
   5674  1.11       chs  *
   5675  1.11       chs  * outnvl is unused
   5676  1.11       chs  */
   5677  1.11       chs /* ARGSUSED */
   5678   1.1      haad static int
   5679  1.11       chs zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
   5680   1.1      haad {
   5681  1.11       chs 	int error;
   5682  1.11       chs 	offset_t off;
   5683  1.11       chs 	char *fromname = NULL;
   5684  1.11       chs 	int fd;
   5685  1.11       chs 	boolean_t largeblockok;
   5686  1.11       chs 	boolean_t embedok;
   5687  1.11       chs 	uint64_t resumeobj = 0;
   5688  1.11       chs 	uint64_t resumeoff = 0;
   5689  1.11       chs 
   5690  1.11       chs 	error = nvlist_lookup_int32(innvl, "fd", &fd);
   5691  1.11       chs 	if (error != 0)
   5692  1.11       chs 		return (SET_ERROR(EINVAL));
   5693  1.11       chs 
   5694  1.11       chs 	(void) nvlist_lookup_string(innvl, "fromsnap", &fromname);
   5695  1.11       chs 
   5696  1.11       chs 	largeblockok = nvlist_exists(innvl, "largeblockok");
   5697  1.11       chs 	embedok = nvlist_exists(innvl, "embedok");
   5698  1.11       chs 
   5699  1.11       chs 	(void) nvlist_lookup_uint64(innvl, "resume_object", &resumeobj);
   5700  1.11       chs 	(void) nvlist_lookup_uint64(innvl, "resume_offset", &resumeoff);
   5701   1.1      haad 
   5702  1.11       chs #ifdef __FreeBSD__
   5703  1.11       chs 	cap_rights_t rights;
   5704   1.2      haad 
   5705  1.11       chs 	fget_write(curthread, fd, cap_rights_init(&rights, CAP_WRITE), &fp);
   5706  1.11       chs #else
   5707  1.11       chs 	file_t *fp = getf(fd);
   5708  1.11       chs #endif
   5709  1.11       chs 	if (fp == NULL)
   5710  1.11       chs 		return (SET_ERROR(EBADF));
   5711   1.1      haad 
   5712  1.11       chs 	off = fp->f_offset;
   5713  1.11       chs 	error = dmu_send(snapname, fromname, embedok, largeblockok, fd,
   5714  1.11       chs #ifdef illumos
   5715  1.11       chs 	    resumeobj, resumeoff, fp->f_vnode, &off);
   5716  1.11       chs #else
   5717  1.11       chs 	    resumeobj, resumeoff, fp, &off);
   5718  1.11       chs #endif
   5719   1.1      haad 
   5720  1.11       chs #ifdef illumos
   5721  1.11       chs 	if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
   5722  1.11       chs 		fp->f_offset = off;
   5723  1.11       chs #else
   5724  1.11       chs 	fp->f_offset = off;
   5725  1.11       chs #endif
   5726   1.1      haad 
   5727  1.11       chs 	releasef(fd);
   5728  1.11       chs 	return (error);
   5729  1.11       chs }
   5730   1.1      haad 
   5731  1.11       chs /*
   5732  1.11       chs  * Determine approximately how large a zfs send stream will be -- the number
   5733  1.11       chs  * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
   5734  1.11       chs  *
   5735  1.11       chs  * innvl: {
   5736  1.11       chs  *     (optional) "from" -> full snap or bookmark name to send an incremental
   5737  1.11       chs  *                          from
   5738  1.11       chs  * }
   5739  1.11       chs  *
   5740  1.11       chs  * outnvl: {
   5741  1.11       chs  *     "space" -> bytes of space (uint64)
   5742  1.11       chs  * }
   5743  1.11       chs  */
   5744  1.11       chs static int
   5745  1.11       chs zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
   5746  1.11       chs {
   5747  1.11       chs 	dsl_pool_t *dp;
   5748  1.11       chs 	dsl_dataset_t *tosnap;
   5749  1.11       chs 	int error;
   5750  1.11       chs 	char *fromname;
   5751  1.11       chs 	uint64_t space;
   5752   1.1      haad 
   5753  1.11       chs 	error = dsl_pool_hold(snapname, FTAG, &dp);
   5754  1.11       chs 	if (error != 0)
   5755  1.11       chs 		return (error);
   5756   1.1      haad 
   5757  1.11       chs 	error = dsl_dataset_hold(dp, snapname, FTAG, &tosnap);
   5758  1.11       chs 	if (error != 0) {
   5759  1.11       chs 		dsl_pool_rele(dp, FTAG);
   5760  1.11       chs 		return (error);
   5761   1.1      haad 	}
   5762   1.1      haad 
   5763  1.11       chs 	error = nvlist_lookup_string(innvl, "from", &fromname);
   5764  1.11       chs 	if (error == 0) {
   5765  1.11       chs 		if (strchr(fromname, '@') != NULL) {
   5766  1.11       chs 			/*
   5767  1.11       chs 			 * If from is a snapshot, hold it and use the more
   5768  1.11       chs 			 * efficient dmu_send_estimate to estimate send space
   5769  1.11       chs 			 * size using deadlists.
   5770  1.11       chs 			 */
   5771  1.11       chs 			dsl_dataset_t *fromsnap;
   5772  1.11       chs 			error = dsl_dataset_hold(dp, fromname, FTAG, &fromsnap);
   5773  1.11       chs 			if (error != 0)
   5774  1.11       chs 				goto out;
   5775  1.11       chs 			error = dmu_send_estimate(tosnap, fromsnap, &space);
   5776  1.11       chs 			dsl_dataset_rele(fromsnap, FTAG);
   5777  1.11       chs 		} else if (strchr(fromname, '#') != NULL) {
   5778  1.11       chs 			/*
   5779  1.11       chs 			 * If from is a bookmark, fetch the creation TXG of the
   5780  1.11       chs 			 * snapshot it was created from and use that to find
   5781  1.11       chs 			 * blocks that were born after it.
   5782  1.11       chs 			 */
   5783  1.11       chs 			zfs_bookmark_phys_t frombm;
   5784   1.1      haad 
   5785  1.11       chs 			error = dsl_bookmark_lookup(dp, fromname, tosnap,
   5786  1.11       chs 			    &frombm);
   5787  1.11       chs 			if (error != 0)
   5788  1.11       chs 				goto out;
   5789  1.11       chs 			error = dmu_send_estimate_from_txg(tosnap,
   5790  1.11       chs 			    frombm.zbm_creation_txg, &space);
   5791  1.11       chs 		} else {
   5792  1.11       chs 			/*
   5793  1.11       chs 			 * from is not properly formatted as a snapshot or
   5794  1.11       chs 			 * bookmark
   5795  1.11       chs 			 */
   5796  1.11       chs 			error = SET_ERROR(EINVAL);
   5797  1.11       chs 			goto out;
   5798  1.11       chs 		}
   5799  1.11       chs 	} else {
   5800  1.11       chs 		// If estimating the size of a full send, use dmu_send_estimate
   5801  1.11       chs 		error = dmu_send_estimate(tosnap, NULL, &space);
   5802   1.1      haad 	}
   5803   1.1      haad 
   5804  1.11       chs 	fnvlist_add_uint64(outnvl, "space", space);
   5805  1.11       chs 
   5806  1.11       chs out:
   5807  1.11       chs 	dsl_dataset_rele(tosnap, FTAG);
   5808  1.11       chs 	dsl_pool_rele(dp, FTAG);
   5809   1.1      haad 	return (error);
   5810   1.1      haad }
   5811   1.1      haad 
   5812  1.11       chs static zfs_ioc_vec_t zfs_ioc_vec[ZFS_IOC_LAST - ZFS_IOC_FIRST];
   5813  1.11       chs 
   5814  1.11       chs static void
   5815  1.11       chs zfs_ioctl_register_legacy(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
   5816  1.11       chs     zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
   5817  1.11       chs     boolean_t log_history, zfs_ioc_poolcheck_t pool_check)
   5818  1.11       chs {
   5819  1.11       chs 	zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
   5820  1.11       chs 
   5821  1.11       chs 	ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
   5822  1.11       chs 	ASSERT3U(ioc, <, ZFS_IOC_LAST);
   5823  1.11       chs 	ASSERT3P(vec->zvec_legacy_func, ==, NULL);
   5824  1.11       chs 	ASSERT3P(vec->zvec_func, ==, NULL);
   5825  1.11       chs 
   5826  1.11       chs 	vec->zvec_legacy_func = func;
   5827  1.11       chs 	vec->zvec_secpolicy = secpolicy;
   5828  1.11       chs 	vec->zvec_namecheck = namecheck;
   5829  1.11       chs 	vec->zvec_allow_log = log_history;
   5830  1.11       chs 	vec->zvec_pool_check = pool_check;
   5831  1.11       chs }
   5832  1.11       chs 
   5833  1.11       chs /*
   5834  1.11       chs  * See the block comment at the beginning of this file for details on
   5835  1.11       chs  * each argument to this function.
   5836  1.11       chs  */
   5837  1.11       chs static void
   5838  1.11       chs zfs_ioctl_register(const char *name, zfs_ioc_t ioc, zfs_ioc_func_t *func,
   5839  1.11       chs     zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
   5840  1.11       chs     zfs_ioc_poolcheck_t pool_check, boolean_t smush_outnvlist,
   5841  1.11       chs     boolean_t allow_log)
   5842  1.11       chs {
   5843  1.11       chs 	zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
   5844  1.11       chs 
   5845  1.11       chs 	ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
   5846  1.11       chs 	ASSERT3U(ioc, <, ZFS_IOC_LAST);
   5847  1.11       chs 	ASSERT3P(vec->zvec_legacy_func, ==, NULL);
   5848  1.11       chs 	ASSERT3P(vec->zvec_func, ==, NULL);
   5849  1.11       chs 
   5850  1.11       chs 	/* if we are logging, the name must be valid */
   5851  1.11       chs 	ASSERT(!allow_log || namecheck != NO_NAME);
   5852  1.11       chs 
   5853  1.11       chs 	vec->zvec_name = name;
   5854  1.11       chs 	vec->zvec_func = func;
   5855  1.11       chs 	vec->zvec_secpolicy = secpolicy;
   5856  1.11       chs 	vec->zvec_namecheck = namecheck;
   5857  1.11       chs 	vec->zvec_pool_check = pool_check;
   5858  1.11       chs 	vec->zvec_smush_outnvlist = smush_outnvlist;
   5859  1.11       chs 	vec->zvec_allow_log = allow_log;
   5860  1.11       chs }
   5861  1.11       chs 
   5862  1.11       chs static void
   5863  1.11       chs zfs_ioctl_register_pool(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
   5864  1.11       chs     zfs_secpolicy_func_t *secpolicy, boolean_t log_history,
   5865  1.11       chs     zfs_ioc_poolcheck_t pool_check)
   5866  1.11       chs {
   5867  1.11       chs 	zfs_ioctl_register_legacy(ioc, func, secpolicy,
   5868  1.11       chs 	    POOL_NAME, log_history, pool_check);
   5869  1.11       chs }
   5870  1.11       chs 
   5871  1.11       chs static void
   5872  1.11       chs zfs_ioctl_register_dataset_nolog(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
   5873  1.11       chs     zfs_secpolicy_func_t *secpolicy, zfs_ioc_poolcheck_t pool_check)
   5874  1.11       chs {
   5875  1.11       chs 	zfs_ioctl_register_legacy(ioc, func, secpolicy,
   5876  1.11       chs 	    DATASET_NAME, B_FALSE, pool_check);
   5877  1.11       chs }
   5878  1.11       chs 
   5879  1.11       chs static void
   5880  1.11       chs zfs_ioctl_register_pool_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
   5881  1.11       chs {
   5882  1.11       chs 	zfs_ioctl_register_legacy(ioc, func, zfs_secpolicy_config,
   5883  1.11       chs 	    POOL_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
   5884  1.11       chs }
   5885  1.11       chs 
   5886  1.11       chs static void
   5887  1.11       chs zfs_ioctl_register_pool_meta(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
   5888  1.11       chs     zfs_secpolicy_func_t *secpolicy)
   5889  1.11       chs {
   5890  1.11       chs 	zfs_ioctl_register_legacy(ioc, func, secpolicy,
   5891  1.11       chs 	    NO_NAME, B_FALSE, POOL_CHECK_NONE);
   5892  1.11       chs }
   5893   1.2      haad 
   5894  1.11       chs static void
   5895  1.11       chs zfs_ioctl_register_dataset_read_secpolicy(zfs_ioc_t ioc,
   5896  1.11       chs     zfs_ioc_legacy_func_t *func, zfs_secpolicy_func_t *secpolicy)
   5897  1.11       chs {
   5898  1.11       chs 	zfs_ioctl_register_legacy(ioc, func, secpolicy,
   5899  1.11       chs 	    DATASET_NAME, B_FALSE, POOL_CHECK_SUSPENDED);
   5900  1.11       chs }
   5901   1.2      haad 
   5902  1.11       chs static void
   5903  1.11       chs zfs_ioctl_register_dataset_read(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
   5904  1.11       chs {
   5905  1.11       chs 	zfs_ioctl_register_dataset_read_secpolicy(ioc, func,
   5906  1.11       chs 	    zfs_secpolicy_read);
   5907  1.11       chs }
   5908   1.2      haad 
   5909  1.11       chs static void
   5910  1.11       chs zfs_ioctl_register_dataset_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
   5911  1.11       chs     zfs_secpolicy_func_t *secpolicy)
   5912   1.2      haad {
   5913  1.11       chs 	zfs_ioctl_register_legacy(ioc, func, secpolicy,
   5914  1.11       chs 	    DATASET_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
   5915  1.11       chs }
   5916   1.2      haad 
   5917  1.11       chs static void
   5918  1.11       chs zfs_ioctl_init(void)
   5919  1.11       chs {
   5920  1.11       chs 	zfs_ioctl_register("snapshot", ZFS_IOC_SNAPSHOT,
   5921  1.11       chs 	    zfs_ioc_snapshot, zfs_secpolicy_snapshot, POOL_NAME,
   5922  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
   5923  1.11       chs 
   5924  1.11       chs 	zfs_ioctl_register("log_history", ZFS_IOC_LOG_HISTORY,
   5925  1.11       chs 	    zfs_ioc_log_history, zfs_secpolicy_log_history, NO_NAME,
   5926  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE);
   5927  1.11       chs 
   5928  1.11       chs 	zfs_ioctl_register("space_snaps", ZFS_IOC_SPACE_SNAPS,
   5929  1.11       chs 	    zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME,
   5930  1.11       chs 	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
   5931  1.11       chs 
   5932  1.11       chs 	zfs_ioctl_register("send", ZFS_IOC_SEND_NEW,
   5933  1.11       chs 	    zfs_ioc_send_new, zfs_secpolicy_send_new, DATASET_NAME,
   5934  1.11       chs 	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
   5935  1.11       chs 
   5936  1.11       chs 	zfs_ioctl_register("send_space", ZFS_IOC_SEND_SPACE,
   5937  1.11       chs 	    zfs_ioc_send_space, zfs_secpolicy_read, DATASET_NAME,
   5938  1.11       chs 	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
   5939  1.11       chs 
   5940  1.11       chs 	zfs_ioctl_register("create", ZFS_IOC_CREATE,
   5941  1.11       chs 	    zfs_ioc_create, zfs_secpolicy_create_clone, DATASET_NAME,
   5942  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
   5943  1.11       chs 
   5944  1.11       chs 	zfs_ioctl_register("clone", ZFS_IOC_CLONE,
   5945  1.11       chs 	    zfs_ioc_clone, zfs_secpolicy_create_clone, DATASET_NAME,
   5946  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
   5947  1.11       chs 
   5948  1.11       chs 	zfs_ioctl_register("destroy_snaps", ZFS_IOC_DESTROY_SNAPS,
   5949  1.11       chs 	    zfs_ioc_destroy_snaps, zfs_secpolicy_destroy_snaps, POOL_NAME,
   5950  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
   5951  1.11       chs 
   5952  1.11       chs 	zfs_ioctl_register("hold", ZFS_IOC_HOLD,
   5953  1.11       chs 	    zfs_ioc_hold, zfs_secpolicy_hold, POOL_NAME,
   5954  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
   5955  1.11       chs 	zfs_ioctl_register("release", ZFS_IOC_RELEASE,
   5956  1.11       chs 	    zfs_ioc_release, zfs_secpolicy_release, POOL_NAME,
   5957  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
   5958  1.11       chs 
   5959  1.11       chs 	zfs_ioctl_register("get_holds", ZFS_IOC_GET_HOLDS,
   5960  1.11       chs 	    zfs_ioc_get_holds, zfs_secpolicy_read, DATASET_NAME,
   5961  1.11       chs 	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
   5962  1.11       chs 
   5963  1.11       chs 	zfs_ioctl_register("rollback", ZFS_IOC_ROLLBACK,
   5964  1.11       chs 	    zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME,
   5965  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE);
   5966  1.11       chs 
   5967  1.11       chs 	zfs_ioctl_register("bookmark", ZFS_IOC_BOOKMARK,
   5968  1.11       chs 	    zfs_ioc_bookmark, zfs_secpolicy_bookmark, POOL_NAME,
   5969  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
   5970  1.11       chs 
   5971  1.11       chs 	zfs_ioctl_register("get_bookmarks", ZFS_IOC_GET_BOOKMARKS,
   5972  1.11       chs 	    zfs_ioc_get_bookmarks, zfs_secpolicy_read, DATASET_NAME,
   5973  1.11       chs 	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
   5974  1.11       chs 
   5975  1.11       chs 	zfs_ioctl_register("destroy_bookmarks", ZFS_IOC_DESTROY_BOOKMARKS,
   5976  1.11       chs 	    zfs_ioc_destroy_bookmarks, zfs_secpolicy_destroy_bookmarks,
   5977  1.11       chs 	    POOL_NAME,
   5978  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
   5979  1.11       chs 
   5980  1.11       chs 	/* IOCTLS that use the legacy function signature */
   5981  1.11       chs 
   5982  1.11       chs 	zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
   5983  1.11       chs 	    zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_READONLY);
   5984  1.11       chs 
   5985  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_POOL_CREATE, zfs_ioc_pool_create,
   5986  1.11       chs 	    zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
   5987  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SCAN,
   5988  1.11       chs 	    zfs_ioc_pool_scan);
   5989  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_UPGRADE,
   5990  1.11       chs 	    zfs_ioc_pool_upgrade);
   5991  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ADD,
   5992  1.11       chs 	    zfs_ioc_vdev_add);
   5993  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_REMOVE,
   5994  1.11       chs 	    zfs_ioc_vdev_remove);
   5995  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SET_STATE,
   5996  1.11       chs 	    zfs_ioc_vdev_set_state);
   5997  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ATTACH,
   5998  1.11       chs 	    zfs_ioc_vdev_attach);
   5999  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_DETACH,
   6000  1.11       chs 	    zfs_ioc_vdev_detach);
   6001  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETPATH,
   6002  1.11       chs 	    zfs_ioc_vdev_setpath);
   6003  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETFRU,
   6004  1.11       chs 	    zfs_ioc_vdev_setfru);
   6005  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SET_PROPS,
   6006  1.11       chs 	    zfs_ioc_pool_set_props);
   6007  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SPLIT,
   6008  1.11       chs 	    zfs_ioc_vdev_split);
   6009  1.11       chs 	zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_REGUID,
   6010  1.11       chs 	    zfs_ioc_pool_reguid);
   6011  1.11       chs 
   6012  1.11       chs 	zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_CONFIGS,
   6013  1.11       chs 	    zfs_ioc_pool_configs, zfs_secpolicy_none);
   6014  1.11       chs 	zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_TRYIMPORT,
   6015  1.11       chs 	    zfs_ioc_pool_tryimport, zfs_secpolicy_config);
   6016  1.11       chs 	zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_FAULT,
   6017  1.11       chs 	    zfs_ioc_inject_fault, zfs_secpolicy_inject);
   6018  1.11       chs 	zfs_ioctl_register_pool_meta(ZFS_IOC_CLEAR_FAULT,
   6019  1.11       chs 	    zfs_ioc_clear_fault, zfs_secpolicy_inject);
   6020  1.11       chs 	zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_LIST_NEXT,
   6021  1.11       chs 	    zfs_ioc_inject_list_next, zfs_secpolicy_inject);
   6022  1.11       chs 
   6023  1.11       chs 	/*
   6024  1.11       chs 	 * pool destroy, and export don't log the history as part of
   6025  1.11       chs 	 * zfsdev_ioctl, but rather zfs_ioc_pool_export
   6026  1.11       chs 	 * does the logging of those commands.
   6027  1.11       chs 	 */
   6028  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_POOL_DESTROY, zfs_ioc_pool_destroy,
   6029  1.11       chs 	    zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
   6030  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_POOL_EXPORT, zfs_ioc_pool_export,
   6031  1.11       chs 	    zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
   6032  1.11       chs 
   6033  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_POOL_STATS, zfs_ioc_pool_stats,
   6034  1.11       chs 	    zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
   6035  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_PROPS, zfs_ioc_pool_get_props,
   6036  1.11       chs 	    zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
   6037  1.11       chs 
   6038  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_ERROR_LOG, zfs_ioc_error_log,
   6039  1.11       chs 	    zfs_secpolicy_inject, B_FALSE, POOL_CHECK_NONE);
   6040  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_DSOBJ_TO_DSNAME,
   6041  1.11       chs 	    zfs_ioc_dsobj_to_dsname,
   6042  1.11       chs 	    zfs_secpolicy_diff, B_FALSE, POOL_CHECK_NONE);
   6043  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_HISTORY,
   6044  1.11       chs 	    zfs_ioc_pool_get_history,
   6045  1.11       chs 	    zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
   6046  1.11       chs 
   6047  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_POOL_IMPORT, zfs_ioc_pool_import,
   6048  1.11       chs 	    zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
   6049  1.11       chs 
   6050  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_CLEAR, zfs_ioc_clear,
   6051  1.11       chs 	    zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
   6052  1.11       chs 	zfs_ioctl_register_pool(ZFS_IOC_POOL_REOPEN, zfs_ioc_pool_reopen,
   6053  1.11       chs 	    zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
   6054  1.11       chs 
   6055  1.11       chs 	zfs_ioctl_register_dataset_read(ZFS_IOC_SPACE_WRITTEN,
   6056  1.11       chs 	    zfs_ioc_space_written);
   6057  1.11       chs 	zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_RECVD_PROPS,
   6058  1.11       chs 	    zfs_ioc_objset_recvd_props);
   6059  1.11       chs 	zfs_ioctl_register_dataset_read(ZFS_IOC_NEXT_OBJ,
   6060  1.11       chs 	    zfs_ioc_next_obj);
   6061  1.11       chs 	zfs_ioctl_register_dataset_read(ZFS_IOC_GET_FSACL,
   6062  1.11       chs 	    zfs_ioc_get_fsacl);
   6063  1.11       chs 	zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_STATS,
   6064  1.11       chs 	    zfs_ioc_objset_stats);
   6065  1.11       chs 	zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_ZPLPROPS,
   6066  1.11       chs 	    zfs_ioc_objset_zplprops);
   6067  1.11       chs 	zfs_ioctl_register_dataset_read(ZFS_IOC_DATASET_LIST_NEXT,
   6068  1.11       chs 	    zfs_ioc_dataset_list_next);
   6069  1.11       chs 	zfs_ioctl_register_dataset_read(ZFS_IOC_SNAPSHOT_LIST_NEXT,
   6070  1.11       chs 	    zfs_ioc_snapshot_list_next);
   6071  1.11       chs 	zfs_ioctl_register_dataset_read(ZFS_IOC_SEND_PROGRESS,
   6072  1.11       chs 	    zfs_ioc_send_progress);
   6073  1.11       chs 
   6074  1.11       chs 	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_DIFF,
   6075  1.11       chs 	    zfs_ioc_diff, zfs_secpolicy_diff);
   6076  1.11       chs 	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_STATS,
   6077  1.11       chs 	    zfs_ioc_obj_to_stats, zfs_secpolicy_diff);
   6078  1.11       chs 	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_PATH,
   6079  1.11       chs 	    zfs_ioc_obj_to_path, zfs_secpolicy_diff);
   6080  1.11       chs 	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_ONE,
   6081  1.11       chs 	    zfs_ioc_userspace_one, zfs_secpolicy_userspace_one);
   6082  1.11       chs 	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_MANY,
   6083  1.11       chs 	    zfs_ioc_userspace_many, zfs_secpolicy_userspace_many);
   6084  1.11       chs 	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_SEND,
   6085  1.11       chs 	    zfs_ioc_send, zfs_secpolicy_send);
   6086  1.11       chs 
   6087  1.11       chs 	zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_PROP, zfs_ioc_set_prop,
   6088  1.11       chs 	    zfs_secpolicy_none);
   6089  1.11       chs 	zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy,
   6090  1.11       chs 	    zfs_secpolicy_destroy);
   6091  1.11       chs 	zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename,
   6092  1.11       chs 	    zfs_secpolicy_rename);
   6093  1.11       chs 	zfs_ioctl_register_dataset_modify(ZFS_IOC_RECV, zfs_ioc_recv,
   6094  1.11       chs 	    zfs_secpolicy_recv);
   6095  1.11       chs 	zfs_ioctl_register_dataset_modify(ZFS_IOC_PROMOTE, zfs_ioc_promote,
   6096  1.11       chs 	    zfs_secpolicy_promote);
   6097  1.11       chs 	zfs_ioctl_register_dataset_modify(ZFS_IOC_INHERIT_PROP,
   6098  1.11       chs 	    zfs_ioc_inherit_prop, zfs_secpolicy_inherit_prop);
   6099  1.11       chs 	zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_FSACL, zfs_ioc_set_fsacl,
   6100  1.11       chs 	    zfs_secpolicy_set_fsacl);
   6101  1.11       chs 
   6102  1.11       chs 	zfs_ioctl_register_dataset_nolog(ZFS_IOC_SHARE, zfs_ioc_share,
   6103  1.11       chs 	    zfs_secpolicy_share, POOL_CHECK_NONE);
   6104  1.11       chs 	zfs_ioctl_register_dataset_nolog(ZFS_IOC_SMB_ACL, zfs_ioc_smb_acl,
   6105  1.11       chs 	    zfs_secpolicy_smb_acl, POOL_CHECK_NONE);
   6106  1.11       chs 	zfs_ioctl_register_dataset_nolog(ZFS_IOC_USERSPACE_UPGRADE,
   6107  1.11       chs 	    zfs_ioc_userspace_upgrade, zfs_secpolicy_userspace_upgrade,
   6108  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
   6109  1.11       chs 	zfs_ioctl_register_dataset_nolog(ZFS_IOC_TMP_SNAPSHOT,
   6110  1.11       chs 	    zfs_ioc_tmp_snapshot, zfs_secpolicy_tmp_snapshot,
   6111  1.11       chs 	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
   6112  1.11       chs 
   6113  1.11       chs #ifdef __FreeBSD__
   6114  1.11       chs 	zfs_ioctl_register_dataset_nolog(ZFS_IOC_JAIL, zfs_ioc_jail,
   6115  1.11       chs 	    zfs_secpolicy_config, POOL_CHECK_NONE);
   6116  1.11       chs 	zfs_ioctl_register_dataset_nolog(ZFS_IOC_UNJAIL, zfs_ioc_unjail,
   6117  1.11       chs 	    zfs_secpolicy_config, POOL_CHECK_NONE);
   6118  1.11       chs 	zfs_ioctl_register("fbsd_nextboot", ZFS_IOC_NEXTBOOT,
   6119  1.11       chs 	    zfs_ioc_nextboot, zfs_secpolicy_config, NO_NAME,
   6120  1.11       chs 	    POOL_CHECK_NONE, B_FALSE, B_FALSE);
   6121  1.11       chs #endif
   6122   1.2      haad }
   6123   1.2      haad 
   6124  1.11       chs int
   6125  1.11       chs pool_status_check(const char *name, zfs_ioc_namecheck_t type,
   6126  1.11       chs     zfs_ioc_poolcheck_t check)
   6127   1.2      haad {
   6128  1.11       chs 	spa_t *spa;
   6129  1.11       chs 	int error;
   6130  1.11       chs 
   6131  1.11       chs 	ASSERT(type == POOL_NAME || type == DATASET_NAME);
   6132  1.11       chs 
   6133  1.11       chs 	if (check & POOL_CHECK_NONE)
   6134  1.11       chs 		return (0);
   6135   1.2      haad 
   6136  1.11       chs 	error = spa_open(name, &spa, FTAG);
   6137  1.11       chs 	if (error == 0) {
   6138  1.11       chs 		if ((check & POOL_CHECK_SUSPENDED) && spa_suspended(spa))
   6139  1.11       chs 			error = SET_ERROR(EAGAIN);
   6140  1.11       chs 		else if ((check & POOL_CHECK_READONLY) && !spa_writeable(spa))
   6141  1.11       chs 			error = SET_ERROR(EROFS);
   6142  1.11       chs 		spa_close(spa, FTAG);
   6143  1.11       chs 	}
   6144  1.11       chs 	return (error);
   6145   1.2      haad }
   6146   1.2      haad 
   6147  1.11       chs /*
   6148  1.11       chs  * Find a free minor number.
   6149  1.11       chs  */
   6150  1.11       chs minor_t
   6151  1.11       chs zfsdev_minor_alloc(void)
   6152   1.2      haad {
   6153  1.11       chs 	static minor_t last_minor;
   6154  1.11       chs 	minor_t m;
   6155  1.11       chs 
   6156  1.19   hannken #ifndef __NetBSD__
   6157  1.11       chs 	ASSERT(MUTEX_HELD(&spa_namespace_lock));
   6158  1.19   hannken #endif
   6159  1.11       chs 
   6160  1.11       chs 	for (m = last_minor + 1; m != last_minor; m++) {
   6161  1.11       chs 		if (m > ZFSDEV_MAX_MINOR)
   6162  1.11       chs 			m = 1;
   6163  1.11       chs 		if (ddi_get_soft_state(zfsdev_state, m) == NULL) {
   6164  1.11       chs 			last_minor = m;
   6165  1.11       chs 			return (m);
   6166  1.11       chs 		}
   6167  1.11       chs 	}
   6168   1.2      haad 
   6169  1.11       chs 	return (0);
   6170   1.2      haad }
   6171   1.2      haad 
   6172  1.11       chs #ifdef __FreeBSD__
   6173   1.2      haad static int
   6174  1.11       chs zfs_ctldev_init(struct cdev *devp)
   6175  1.11       chs #else
   6176  1.11       chs static int
   6177  1.11       chs zfs_ctldev_init(dev_t *devp)
   6178  1.11       chs #endif
   6179   1.2      haad {
   6180  1.11       chs 	minor_t minor;
   6181  1.11       chs 	zfs_soft_state_t *zs;
   6182  1.11       chs 
   6183  1.11       chs 	ASSERT(MUTEX_HELD(&spa_namespace_lock));
   6184   1.2      haad 
   6185  1.11       chs 	minor = zfsdev_minor_alloc();
   6186  1.11       chs 	if (minor == 0)
   6187  1.11       chs 		return (SET_ERROR(ENXIO));
   6188  1.11       chs 
   6189  1.11       chs 	if (ddi_soft_state_zalloc(zfsdev_state, minor) != DDI_SUCCESS)
   6190  1.11       chs 		return (SET_ERROR(EAGAIN));
   6191  1.11       chs 
   6192  1.11       chs #ifdef __FreeBSD__
   6193  1.11       chs 	devfs_set_cdevpriv((void *)(uintptr_t)minor, zfsdev_close);
   6194  1.15   hannken #else
   6195  1.15   hannken 	*devp = makedev(major(*devp), minor);
   6196  1.11       chs #endif
   6197  1.11       chs 
   6198  1.11       chs 	zs = ddi_get_soft_state(zfsdev_state, minor);
   6199  1.11       chs 	zs->zss_type = ZSST_CTLDEV;
   6200  1.11       chs 	zfs_onexit_init((zfs_onexit_t **)&zs->zss_data);
   6201  1.11       chs 
   6202  1.11       chs 	return (0);
   6203   1.2      haad }
   6204   1.2      haad 
   6205  1.11       chs static void
   6206  1.11       chs zfs_ctldev_destroy(zfs_onexit_t *zo, minor_t minor)
   6207   1.2      haad {
   6208  1.11       chs 	ASSERT(MUTEX_HELD(&spa_namespace_lock));
   6209   1.2      haad 
   6210  1.11       chs 	zfs_onexit_destroy(zo);
   6211  1.11       chs 	ddi_soft_state_free(zfsdev_state, minor);
   6212   1.2      haad }
   6213   1.2      haad 
   6214  1.11       chs void *
   6215  1.11       chs zfsdev_get_soft_state(minor_t minor, enum zfs_soft_state_type which)
   6216   1.2      haad {
   6217  1.11       chs 	zfs_soft_state_t *zp;
   6218   1.2      haad 
   6219  1.11       chs 	zp = ddi_get_soft_state(zfsdev_state, minor);
   6220  1.11       chs 	if (zp == NULL || zp->zss_type != which)
   6221  1.11       chs 		return (NULL);
   6222  1.11       chs 
   6223  1.11       chs 	return (zp->zss_data);
   6224   1.2      haad }
   6225   1.2      haad 
   6226  1.11       chs #ifdef __FreeBSD__
   6227   1.2      haad static int
   6228  1.11       chs zfsdev_open(struct cdev *devp, int flag, int mode, struct thread *td)
   6229  1.11       chs #endif
   6230  1.11       chs #ifdef __NetBSD__
   6231  1.11       chs static int
   6232  1.11       chs zfsdev_open(dev_t *devp, int flag, int otyp, cred_t *cr)
   6233  1.11       chs #endif
   6234   1.2      haad {
   6235  1.11       chs 	int error = 0;
   6236  1.11       chs 
   6237  1.11       chs #ifndef __FreeBSD__
   6238  1.11       chs 	if (getminor(*devp) != 0)
   6239  1.11       chs 		return (zvol_open(devp, flag, otyp, cr));
   6240  1.11       chs #endif
   6241  1.11       chs 
   6242  1.11       chs 	/* This is the control device. Allocate a new minor if requested. */
   6243  1.11       chs 	if (flag & FEXCL) {
   6244  1.11       chs 		mutex_enter(&spa_namespace_lock);
   6245  1.11       chs 		error = zfs_ctldev_init(devp);
   6246  1.11       chs 		mutex_exit(&spa_namespace_lock);
   6247  1.11       chs 	}
   6248   1.2      haad 
   6249  1.11       chs 	return (error);
   6250   1.2      haad }
   6251   1.2      haad 
   6252  1.11       chs #ifdef __FreeBSD__
   6253  1.11       chs static void
   6254  1.11       chs zfsdev_close(void *data)
   6255  1.11       chs #endif
   6256  1.11       chs #ifdef __NetBSD__
   6257  1.11       chs static int
   6258  1.11       chs zfsdev_close(dev_t dev, int flag, int otyp, cred_t *cr)
   6259  1.11       chs #endif
   6260  1.11       chs {
   6261  1.11       chs 	zfs_onexit_t *zo;
   6262  1.11       chs #ifdef __FreeBSD__
   6263  1.11       chs 	minor_t minor = (minor_t)(uintptr_t)data;
   6264  1.11       chs #endif
   6265  1.11       chs #ifdef __NetBSD__
   6266  1.11       chs 	minor_t minor = getminor(dev);
   6267  1.11       chs #endif
   6268   1.2      haad 
   6269  1.11       chs 	if (minor == 0)
   6270  1.11       chs #ifdef __FreeBSD__
   6271  1.11       chs 		return;
   6272  1.11       chs #else
   6273  1.11       chs 		return (0);
   6274  1.11       chs #endif
   6275   1.2      haad 
   6276  1.11       chs 	mutex_enter(&spa_namespace_lock);
   6277  1.11       chs 	zo = zfsdev_get_soft_state(minor, ZSST_CTLDEV);
   6278  1.11       chs 	if (zo == NULL) {
   6279  1.11       chs 		mutex_exit(&spa_namespace_lock);
   6280  1.11       chs #ifdef __FreeBSD__
   6281  1.11       chs 		return;
   6282  1.11       chs #else
   6283  1.20   hannken 		return zvol_close(dev, flag, otyp, cr);
   6284  1.11       chs 		return 0;
   6285  1.11       chs #endif
   6286  1.11       chs 	}
   6287  1.11       chs 	zfs_ctldev_destroy(zo, minor);
   6288  1.11       chs 	mutex_exit(&spa_namespace_lock);
   6289   1.2      haad 
   6290  1.11       chs #ifndef __FreeBSD__
   6291  1.11       chs 	return (0);
   6292  1.11       chs #endif
   6293  1.11       chs }
   6294   1.2      haad 
   6295  1.11       chs #ifdef __FreeBSD__
   6296  1.11       chs static int
   6297  1.11       chs zfsdev_ioctl(struct cdev *dev, u_long zcmd, caddr_t arg, int flag,
   6298  1.11       chs     struct thread *td)
   6299  1.11       chs #endif
   6300  1.11       chs #ifdef __NetBSD__
   6301   1.2      haad static int
   6302  1.20   hannken zfsdev_ioctl(dev_t dev, u_long zcmd, intptr_t iarg, int flag, cred_t *cr, int *rvalp)
   6303  1.11       chs #endif
   6304   1.2      haad {
   6305  1.11       chs 	zfs_cmd_t *zc;
   6306  1.11       chs 	uint_t vecnum;
   6307  1.11       chs 	int error, rc, len;
   6308  1.11       chs 	zfs_iocparm_t *zc_iocparm;
   6309  1.11       chs 	int cflag, cmd, oldvecnum;
   6310  1.11       chs 	boolean_t newioc, compat;
   6311  1.11       chs 	void *compat_zc = NULL;
   6312  1.11       chs #ifdef __FreeBSD__
   6313  1.11       chs 	cred_t *cr = td->td_ucred;
   6314  1.11       chs #endif
   6315  1.11       chs 	const zfs_ioc_vec_t *vec;
   6316  1.11       chs 	char *saved_poolname = NULL;
   6317  1.11       chs 	nvlist_t *innvl = NULL;
   6318  1.11       chs #ifdef __NetBSD__
   6319  1.11       chs 	caddr_t arg = (caddr_t)iarg;
   6320  1.11       chs #endif
   6321  1.11       chs 
   6322  1.11       chs #if defined(illumos) || defined(__NetBSD__)
   6323  1.11       chs 	minor_t minor = getminor(dev);
   6324  1.11       chs 
   6325  1.11       chs 	if (minor != 0 &&
   6326  1.11       chs 	    zfsdev_get_soft_state(minor, ZSST_CTLDEV) == NULL)
   6327  1.11       chs 		return (zvol_ioctl(dev, zcmd, iarg, flag, cr, rvalp));
   6328  1.11       chs #endif
   6329  1.11       chs #ifdef illumos
   6330  1.11       chs 	vecnum = cmd - ZFS_IOC_FIRST;
   6331  1.11       chs 	ASSERT3U(getmajor(dev), ==, ddi_driver_major(zfs_dip));
   6332  1.11       chs #endif
   6333  1.11       chs 
   6334  1.11       chs 	cflag = ZFS_CMD_COMPAT_NONE;
   6335  1.11       chs 	compat = B_FALSE;
   6336  1.11       chs 	newioc = B_TRUE;	/* "new" style (zfs_iocparm_t) ioctl */
   6337  1.11       chs 	len = IOCPARM_LEN(zcmd);
   6338  1.11       chs 	vecnum = cmd = zcmd & 0xff;
   6339  1.11       chs 
   6340  1.11       chs 	/*
   6341  1.11       chs 	 * Check if we are talking to supported older binaries
   6342  1.11       chs 	 * and translate zfs_cmd if necessary
   6343  1.11       chs 	 */
   6344  1.11       chs 	if (len != sizeof(zfs_iocparm_t)) {
   6345  1.11       chs 		newioc = B_FALSE;
   6346  1.11       chs 		compat = B_TRUE;
   6347  1.11       chs 
   6348  1.11       chs 		vecnum = cmd;
   6349  1.11       chs 
   6350  1.11       chs 		switch (len) {
   6351  1.11       chs 		case sizeof(zfs_cmd_zcmd_t):
   6352  1.11       chs 			cflag = ZFS_CMD_COMPAT_LZC;
   6353  1.11       chs 			break;
   6354  1.11       chs 		case sizeof(zfs_cmd_deadman_t):
   6355  1.11       chs 			cflag = ZFS_CMD_COMPAT_DEADMAN;
   6356  1.11       chs 			break;
   6357  1.11       chs 		case sizeof(zfs_cmd_v28_t):
   6358  1.11       chs 			cflag = ZFS_CMD_COMPAT_V28;
   6359  1.11       chs 			break;
   6360  1.11       chs 		case sizeof(zfs_cmd_v15_t):
   6361  1.11       chs 			cflag = ZFS_CMD_COMPAT_V15;
   6362  1.11       chs 			vecnum = zfs_ioctl_v15_to_v28[cmd];
   6363   1.7     pooka 
   6364  1.11       chs 			/*
   6365  1.11       chs 			 * Return without further handling
   6366  1.11       chs 			 * if the command is blacklisted.
   6367  1.11       chs 			 */
   6368  1.11       chs 			if (vecnum == ZFS_IOC_COMPAT_PASS)
   6369  1.11       chs 				return (0);
   6370  1.11       chs 			else if (vecnum == ZFS_IOC_COMPAT_FAIL)
   6371  1.11       chs 				return (ENOTSUP);
   6372  1.11       chs 			break;
   6373  1.11       chs 		default:
   6374  1.11       chs 			return (EINVAL);
   6375   1.2      haad 		}
   6376  1.11       chs 	}
   6377  1.11       chs 
   6378  1.11       chs 	if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
   6379  1.11       chs 		return (SET_ERROR(EINVAL));
   6380  1.11       chs 	vec = &zfs_ioc_vec[vecnum];
   6381  1.11       chs 
   6382  1.11       chs 	zc = kmem_zalloc(sizeof(zfs_cmd_t), KM_SLEEP);
   6383  1.11       chs 
   6384  1.11       chs #ifdef illumos
   6385  1.11       chs 	error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag);
   6386  1.11       chs 	if (error != 0) {
   6387  1.11       chs 		error = SET_ERROR(EFAULT);
   6388  1.11       chs 		goto out;
   6389  1.11       chs 	}
   6390  1.11       chs #else	/* !illumos */
   6391  1.11       chs 
   6392  1.11       chs 	bzero(zc, sizeof(zfs_cmd_t));
   6393  1.11       chs 
   6394  1.11       chs 	if (newioc) {
   6395  1.11       chs 		zc_iocparm = (void *)arg;
   6396  1.11       chs 
   6397  1.11       chs 		switch (zc_iocparm->zfs_ioctl_version) {
   6398  1.11       chs 		case ZFS_IOCVER_CURRENT:
   6399  1.11       chs 			if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_t)) {
   6400  1.11       chs 				error = SET_ERROR(EINVAL);
   6401  1.11       chs 				goto out;
   6402  1.11       chs 			}
   6403  1.11       chs 			break;
   6404  1.11       chs 		case ZFS_IOCVER_INLANES:
   6405  1.11       chs 			if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_inlanes_t)) {
   6406  1.11       chs 				error = SET_ERROR(EFAULT);
   6407  1.11       chs 				goto out;
   6408  1.11       chs 			}
   6409  1.11       chs 			compat = B_TRUE;
   6410  1.11       chs 			cflag = ZFS_CMD_COMPAT_INLANES;
   6411  1.11       chs 			break;
   6412  1.11       chs 		case ZFS_IOCVER_RESUME:
   6413  1.11       chs 			if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_resume_t)) {
   6414  1.11       chs 				error = SET_ERROR(EFAULT);
   6415  1.11       chs 				goto out;
   6416  1.11       chs 			}
   6417  1.11       chs 			compat = B_TRUE;
   6418  1.11       chs 			cflag = ZFS_CMD_COMPAT_RESUME;
   6419  1.11       chs 			break;
   6420  1.11       chs 		case ZFS_IOCVER_EDBP:
   6421  1.11       chs 			if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_edbp_t)) {
   6422  1.11       chs 				error = SET_ERROR(EFAULT);
   6423  1.11       chs 				goto out;
   6424  1.11       chs 			}
   6425  1.11       chs 			compat = B_TRUE;
   6426  1.11       chs 			cflag = ZFS_CMD_COMPAT_EDBP;
   6427  1.11       chs 			break;
   6428  1.11       chs 		case ZFS_IOCVER_ZCMD:
   6429  1.11       chs 			if (zc_iocparm->zfs_cmd_size > sizeof(zfs_cmd_t) ||
   6430  1.11       chs 			    zc_iocparm->zfs_cmd_size < sizeof(zfs_cmd_zcmd_t)) {
   6431  1.11       chs 				error = SET_ERROR(EFAULT);
   6432  1.11       chs 				goto out;
   6433  1.11       chs 			}
   6434  1.11       chs 			compat = B_TRUE;
   6435  1.11       chs 			cflag = ZFS_CMD_COMPAT_ZCMD;
   6436  1.11       chs 			break;
   6437  1.11       chs 		default:
   6438  1.11       chs 			error = SET_ERROR(EINVAL);
   6439  1.11       chs 			goto out;
   6440  1.11       chs 			/* NOTREACHED */
   6441   1.2      haad 		}
   6442  1.11       chs 
   6443  1.11       chs 		if (compat) {
   6444  1.11       chs 			ASSERT(sizeof(zfs_cmd_t) >= zc_iocparm->zfs_cmd_size);
   6445  1.11       chs 			compat_zc = kmem_zalloc(sizeof(zfs_cmd_t), KM_SLEEP);
   6446  1.11       chs 			bzero(compat_zc, sizeof(zfs_cmd_t));
   6447  1.11       chs 
   6448  1.11       chs 			error = ddi_copyin((void *)(uintptr_t)zc_iocparm->zfs_cmd,
   6449  1.11       chs 			    compat_zc, zc_iocparm->zfs_cmd_size, flag);
   6450  1.11       chs 			if (error != 0) {
   6451  1.11       chs 				error = SET_ERROR(EFAULT);
   6452  1.11       chs 				goto out;
   6453  1.11       chs 			}
   6454  1.11       chs 		} else {
   6455  1.11       chs 			error = ddi_copyin((void *)(uintptr_t)zc_iocparm->zfs_cmd,
   6456  1.11       chs 			    zc, zc_iocparm->zfs_cmd_size, flag);
   6457  1.11       chs 			if (error != 0) {
   6458  1.11       chs 				error = SET_ERROR(EFAULT);
   6459  1.11       chs 				goto out;
   6460  1.11       chs 			}
   6461   1.2      haad 		}
   6462  1.13  christos 	} else
   6463  1.13  christos 		zc_iocparm = NULL;
   6464  1.11       chs 
   6465  1.11       chs 	if (compat) {
   6466  1.11       chs 		if (newioc) {
   6467  1.11       chs 			ASSERT(compat_zc != NULL);
   6468  1.11       chs 			zfs_cmd_compat_get(zc, compat_zc, cflag);
   6469  1.11       chs 		} else {
   6470  1.11       chs 			ASSERT(compat_zc == NULL);
   6471  1.11       chs 			zfs_cmd_compat_get(zc, arg, cflag);
   6472   1.2      haad 		}
   6473  1.11       chs 		oldvecnum = vecnum;
   6474  1.11       chs 		error = zfs_ioctl_compat_pre(zc, &vecnum, cflag);
   6475  1.11       chs 		if (error != 0)
   6476  1.11       chs 			goto out;
   6477  1.11       chs 		if (oldvecnum != vecnum)
   6478  1.11       chs 			vec = &zfs_ioc_vec[vecnum];
   6479  1.11       chs 	}
   6480  1.11       chs #endif	/* !illumos */
   6481  1.11       chs 
   6482  1.11       chs 	zc->zc_iflags = flag & FKIOCTL;
   6483  1.11       chs 	if (zc->zc_nvlist_src_size != 0) {
   6484  1.11       chs 		error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
   6485  1.11       chs 		    zc->zc_iflags, &innvl);
   6486  1.11       chs 		if (error != 0)
   6487  1.11       chs 			goto out;
   6488  1.11       chs 	}
   6489  1.11       chs 
   6490  1.11       chs 	/* rewrite innvl for backwards compatibility */
   6491  1.11       chs 	if (compat)
   6492  1.11       chs 		innvl = zfs_ioctl_compat_innvl(zc, innvl, vecnum, cflag);
   6493  1.11       chs 
   6494  1.11       chs 	/*
   6495  1.11       chs 	 * Ensure that all pool/dataset names are valid before we pass down to
   6496  1.11       chs 	 * the lower layers.
   6497  1.11       chs 	 */
   6498  1.11       chs 	zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
   6499  1.11       chs 	switch (vec->zvec_namecheck) {
   6500  1.11       chs 	case POOL_NAME:
   6501  1.11       chs 		if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
   6502  1.11       chs 			error = SET_ERROR(EINVAL);
   6503  1.11       chs 		else
   6504  1.11       chs 			error = pool_status_check(zc->zc_name,
   6505  1.11       chs 			    vec->zvec_namecheck, vec->zvec_pool_check);
   6506  1.11       chs 		break;
   6507  1.11       chs 
   6508  1.11       chs 	case DATASET_NAME:
   6509  1.11       chs 		if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
   6510  1.11       chs 			error = SET_ERROR(EINVAL);
   6511  1.11       chs 		else
   6512  1.11       chs 			error = pool_status_check(zc->zc_name,
   6513  1.11       chs 			    vec->zvec_namecheck, vec->zvec_pool_check);
   6514  1.11       chs 		break;
   6515  1.11       chs 
   6516  1.11       chs 	case NO_NAME:
   6517  1.11       chs 		break;
   6518  1.11       chs 	}
   6519  1.11       chs 
   6520  1.11       chs 	if (error == 0)
   6521  1.11       chs 		error = vec->zvec_secpolicy(zc, innvl, cr);
   6522  1.11       chs 
   6523  1.11       chs 	if (error != 0)
   6524  1.11       chs 		goto out;
   6525  1.11       chs 
   6526  1.11       chs 	/* legacy ioctls can modify zc_name */
   6527  1.11       chs 	len = strcspn(zc->zc_name, "/@#") + 1;
   6528  1.11       chs 	saved_poolname = kmem_alloc(len, KM_SLEEP);
   6529  1.11       chs 	(void) strlcpy(saved_poolname, zc->zc_name, len);
   6530  1.11       chs 
   6531  1.11       chs 	if (vec->zvec_func != NULL) {
   6532  1.11       chs 		nvlist_t *outnvl;
   6533  1.11       chs 		int puterror = 0;
   6534  1.11       chs 		spa_t *spa;
   6535  1.11       chs 		nvlist_t *lognv = NULL;
   6536   1.2      haad 
   6537  1.11       chs 		ASSERT(vec->zvec_legacy_func == NULL);
   6538   1.2      haad 
   6539   1.2      haad 		/*
   6540  1.11       chs 		 * Add the innvl to the lognv before calling the func,
   6541  1.11       chs 		 * in case the func changes the innvl.
   6542   1.2      haad 		 */
   6543  1.11       chs 		if (vec->zvec_allow_log) {
   6544  1.11       chs 			lognv = fnvlist_alloc();
   6545  1.11       chs 			fnvlist_add_string(lognv, ZPOOL_HIST_IOCTL,
   6546  1.11       chs 			    vec->zvec_name);
   6547  1.11       chs 			if (!nvlist_empty(innvl)) {
   6548  1.11       chs 				fnvlist_add_nvlist(lognv, ZPOOL_HIST_INPUT_NVL,
   6549  1.11       chs 				    innvl);
   6550  1.11       chs 			}
   6551  1.11       chs 		}
   6552  1.11       chs 
   6553  1.11       chs 		outnvl = fnvlist_alloc();
   6554  1.11       chs 		error = vec->zvec_func(zc->zc_name, innvl, outnvl);
   6555   1.2      haad 
   6556  1.11       chs 		if (error == 0 && vec->zvec_allow_log &&
   6557  1.11       chs 		    spa_open(zc->zc_name, &spa, FTAG) == 0) {
   6558  1.11       chs 			if (!nvlist_empty(outnvl)) {
   6559  1.11       chs 				fnvlist_add_nvlist(lognv, ZPOOL_HIST_OUTPUT_NVL,
   6560  1.11       chs 				    outnvl);
   6561  1.11       chs 			}
   6562  1.11       chs 			(void) spa_history_log_nvl(spa, lognv);
   6563  1.11       chs 			spa_close(spa, FTAG);
   6564  1.11       chs 		}
   6565  1.11       chs 		fnvlist_free(lognv);
   6566   1.2      haad 
   6567  1.11       chs 		/* rewrite outnvl for backwards compatibility */
   6568  1.11       chs 		if (compat)
   6569  1.11       chs 			outnvl = zfs_ioctl_compat_outnvl(zc, outnvl, vecnum,
   6570  1.11       chs 			    cflag);
   6571  1.11       chs 
   6572  1.11       chs 		if (!nvlist_empty(outnvl) || zc->zc_nvlist_dst_size != 0) {
   6573  1.11       chs 			int smusherror = 0;
   6574  1.11       chs 			if (vec->zvec_smush_outnvlist) {
   6575  1.11       chs 				smusherror = nvlist_smush(outnvl,
   6576  1.11       chs 				    zc->zc_nvlist_dst_size);
   6577  1.11       chs 			}
   6578  1.11       chs 			if (smusherror == 0)
   6579  1.11       chs 				puterror = put_nvlist(zc, outnvl);
   6580  1.11       chs 		}
   6581   1.2      haad 
   6582  1.11       chs 		if (puterror != 0)
   6583  1.11       chs 			error = puterror;
   6584   1.2      haad 
   6585  1.11       chs 		nvlist_free(outnvl);
   6586  1.11       chs 	} else {
   6587  1.11       chs 		error = vec->zvec_legacy_func(zc);
   6588  1.11       chs 	}
   6589   1.2      haad 
   6590  1.11       chs out:
   6591  1.11       chs 	nvlist_free(innvl);
   6592   1.2      haad 
   6593  1.11       chs #ifdef illumos
   6594  1.11       chs 	rc = ddi_copyout(zc, (void *)arg, sizeof (zfs_cmd_t), flag);
   6595  1.11       chs 	if (error == 0 && rc != 0)
   6596  1.11       chs 		error = SET_ERROR(EFAULT);
   6597  1.11       chs #else
   6598  1.11       chs 	if (compat) {
   6599  1.11       chs 		zfs_ioctl_compat_post(zc, cmd, cflag);
   6600  1.11       chs 		if (newioc) {
   6601  1.11       chs 			ASSERT(compat_zc != NULL);
   6602  1.11       chs 			ASSERT(sizeof(zfs_cmd_t) >= zc_iocparm->zfs_cmd_size);
   6603  1.11       chs 
   6604  1.11       chs 			zfs_cmd_compat_put(zc, compat_zc, vecnum, cflag);
   6605  1.11       chs 			rc = ddi_copyout(compat_zc,
   6606  1.11       chs 			    (void *)(uintptr_t)zc_iocparm->zfs_cmd,
   6607  1.11       chs 			    zc_iocparm->zfs_cmd_size, flag);
   6608  1.11       chs 			if (error == 0 && rc != 0)
   6609  1.11       chs 				error = SET_ERROR(EFAULT);
   6610  1.11       chs 			kmem_free(compat_zc, sizeof (zfs_cmd_t));
   6611  1.11       chs 		} else {
   6612  1.11       chs 			zfs_cmd_compat_put(zc, arg, vecnum, cflag);
   6613  1.11       chs 		}
   6614  1.11       chs 	} else {
   6615  1.11       chs 		ASSERT(newioc);
   6616   1.2      haad 
   6617  1.11       chs 		rc = ddi_copyout(zc, (void *)(uintptr_t)zc_iocparm->zfs_cmd,
   6618  1.11       chs 		    sizeof (zfs_cmd_t), flag);
   6619  1.11       chs 		if (error == 0 && rc != 0)
   6620  1.11       chs 			error = SET_ERROR(EFAULT);
   6621  1.11       chs 	}
   6622  1.11       chs #endif
   6623  1.11       chs 	if (error == 0 && vec->zvec_allow_log) {
   6624  1.11       chs 		char *s = tsd_get(zfs_allow_log_key);
   6625  1.11       chs 		if (s != NULL)
   6626  1.11       chs 			strfree(s);
   6627  1.11       chs 		(void) tsd_set(zfs_allow_log_key, saved_poolname);
   6628  1.11       chs 	} else {
   6629  1.11       chs 		if (saved_poolname != NULL)
   6630  1.11       chs 			strfree(saved_poolname);
   6631  1.11       chs 	}
   6632   1.2      haad 
   6633  1.11       chs 	kmem_free(zc, sizeof (zfs_cmd_t));
   6634   1.2      haad 	return (error);
   6635   1.2      haad }
   6636   1.2      haad 
   6637  1.11       chs static void
   6638  1.11       chs zfs_allow_log_destroy(void *arg)
   6639  1.11       chs {
   6640  1.11       chs 	char *poolname = arg;
   6641  1.11       chs 	strfree(poolname);
   6642  1.11       chs }
   6643  1.11       chs 
   6644  1.11       chs #ifdef illumos
   6645   1.1      haad static int
   6646   1.1      haad zfs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
   6647   1.1      haad {
   6648   1.1      haad 	if (cmd != DDI_ATTACH)
   6649   1.1      haad 		return (DDI_FAILURE);
   6650   1.1      haad 
   6651   1.1      haad 	if (ddi_create_minor_node(dip, "zfs", S_IFCHR, 0,
   6652   1.1      haad 	    DDI_PSEUDO, 0) == DDI_FAILURE)
   6653   1.1      haad 		return (DDI_FAILURE);
   6654   1.1      haad 
   6655   1.1      haad 	zfs_dip = dip;
   6656   1.1      haad 
   6657   1.1      haad 	ddi_report_dev(dip);
   6658   1.1      haad 
   6659   1.1      haad 	return (DDI_SUCCESS);
   6660   1.1      haad }
   6661   1.1      haad 
   6662   1.1      haad static int
   6663   1.1      haad zfs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
   6664   1.1      haad {
   6665   1.1      haad 	if (spa_busy() || zfs_busy() || zvol_busy())
   6666   1.1      haad 		return (DDI_FAILURE);
   6667   1.1      haad 
   6668   1.1      haad 	if (cmd != DDI_DETACH)
   6669   1.1      haad 		return (DDI_FAILURE);
   6670   1.1      haad 
   6671   1.1      haad 	zfs_dip = NULL;
   6672   1.1      haad 
   6673   1.1      haad 	ddi_prop_remove_all(dip);
   6674   1.1      haad 	ddi_remove_minor_node(dip, NULL);
   6675   1.1      haad 
   6676   1.1      haad 	return (DDI_SUCCESS);
   6677   1.1      haad }
   6678   1.1      haad 
   6679   1.1      haad /*ARGSUSED*/
   6680   1.1      haad static int
   6681   1.1      haad zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
   6682   1.1      haad {
   6683   1.1      haad 	switch (infocmd) {
   6684   1.1      haad 	case DDI_INFO_DEVT2DEVINFO:
   6685   1.1      haad 		*result = zfs_dip;
   6686   1.1      haad 		return (DDI_SUCCESS);
   6687   1.1      haad 
   6688   1.1      haad 	case DDI_INFO_DEVT2INSTANCE:
   6689   1.1      haad 		*result = (void *)0;
   6690   1.1      haad 		return (DDI_SUCCESS);
   6691   1.1      haad 	}
   6692   1.1      haad 
   6693   1.1      haad 	return (DDI_FAILURE);
   6694   1.1      haad }
   6695   1.1      haad 
   6696   1.1      haad /*
   6697   1.1      haad  * OK, so this is a little weird.
   6698   1.1      haad  *
   6699   1.1      haad  * /dev/zfs is the control node, i.e. minor 0.
   6700   1.1      haad  * /dev/zvol/[r]dsk/pool/dataset are the zvols, minor > 0.
   6701   1.1      haad  *
   6702   1.1      haad  * /dev/zfs has basically nothing to do except serve up ioctls,
   6703   1.1      haad  * so most of the standard driver entry points are in zvol.c.
   6704   1.1      haad  */
   6705   1.1      haad static struct cb_ops zfs_cb_ops = {
   6706  1.11       chs 	zfsdev_open,	/* open */
   6707  1.11       chs 	zfsdev_close,	/* close */
   6708   1.1      haad 	zvol_strategy,	/* strategy */
   6709   1.1      haad 	nodev,		/* print */
   6710   1.1      haad 	zvol_dump,	/* dump */
   6711   1.1      haad 	zvol_read,	/* read */
   6712   1.1      haad 	zvol_write,	/* write */
   6713   1.1      haad 	zfsdev_ioctl,	/* ioctl */
   6714   1.1      haad 	nodev,		/* devmap */
   6715   1.1      haad 	nodev,		/* mmap */
   6716   1.1      haad 	nodev,		/* segmap */
   6717   1.1      haad 	nochpoll,	/* poll */
   6718   1.1      haad 	ddi_prop_op,	/* prop_op */
   6719   1.1      haad 	NULL,		/* streamtab */
   6720   1.1      haad 	D_NEW | D_MP | D_64BIT,		/* Driver compatibility flag */
   6721   1.1      haad 	CB_REV,		/* version */
   6722   1.1      haad 	nodev,		/* async read */
   6723   1.1      haad 	nodev,		/* async write */
   6724   1.1      haad };
   6725   1.1      haad 
   6726   1.1      haad static struct dev_ops zfs_dev_ops = {
   6727   1.1      haad 	DEVO_REV,	/* version */
   6728   1.1      haad 	0,		/* refcnt */
   6729   1.1      haad 	zfs_info,	/* info */
   6730   1.1      haad 	nulldev,	/* identify */
   6731   1.1      haad 	nulldev,	/* probe */
   6732   1.1      haad 	zfs_attach,	/* attach */
   6733   1.1      haad 	zfs_detach,	/* detach */
   6734   1.1      haad 	nodev,		/* reset */
   6735   1.1      haad 	&zfs_cb_ops,	/* driver operations */
   6736   1.1      haad 	NULL,		/* no bus operations */
   6737   1.1      haad 	NULL,		/* power */
   6738   1.1      haad 	ddi_quiesce_not_needed,	/* quiesce */
   6739   1.1      haad };
   6740   1.1      haad 
   6741   1.1      haad static struct modldrv zfs_modldrv = {
   6742   1.1      haad 	&mod_driverops,
   6743   1.1      haad 	"ZFS storage pool",
   6744   1.1      haad 	&zfs_dev_ops
   6745   1.1      haad };
   6746   1.1      haad 
   6747   1.1      haad static struct modlinkage modlinkage = {
   6748   1.1      haad 	MODREV_1,
   6749   1.1      haad 	(void *)&zfs_modlfs,
   6750   1.1      haad 	(void *)&zfs_modldrv,
   6751   1.1      haad 	NULL
   6752   1.1      haad };
   6753   1.1      haad 
   6754   1.1      haad int
   6755   1.1      haad _init(void)
   6756   1.1      haad {
   6757   1.1      haad 	int error;
   6758   1.1      haad 
   6759   1.1      haad 	spa_init(FREAD | FWRITE);
   6760   1.1      haad 	zfs_init();
   6761   1.1      haad 	zvol_init();
   6762  1.11       chs 	zfs_ioctl_init();
   6763   1.1      haad 
   6764   1.1      haad 	if ((error = mod_install(&modlinkage)) != 0) {
   6765   1.1      haad 		zvol_fini();
   6766   1.1      haad 		zfs_fini();
   6767   1.1      haad 		spa_fini();
   6768   1.1      haad 		return (error);
   6769   1.1      haad 	}
   6770   1.1      haad 
   6771  1.11       chs 	tsd_create(&zfs_putpages_key, NULL);
   6772  1.11       chs 	tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
   6773  1.11       chs 	tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
   6774   1.1      haad 
   6775   1.1      haad 	error = ldi_ident_from_mod(&modlinkage, &zfs_li);
   6776   1.1      haad 	ASSERT(error == 0);
   6777   1.1      haad 	mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
   6778   1.1      haad 
   6779   1.1      haad 	return (0);
   6780   1.1      haad }
   6781   1.1      haad 
   6782   1.1      haad int
   6783   1.1      haad _fini(void)
   6784   1.1      haad {
   6785   1.1      haad 	int error;
   6786   1.1      haad 
   6787   1.1      haad 	if (spa_busy() || zfs_busy() || zvol_busy() || zio_injection_enabled)
   6788  1.11       chs 		return (SET_ERROR(EBUSY));
   6789   1.1      haad 
   6790   1.1      haad 	if ((error = mod_remove(&modlinkage)) != 0)
   6791   1.1      haad 		return (error);
   6792   1.1      haad 
   6793   1.1      haad 	zvol_fini();
   6794   1.1      haad 	zfs_fini();
   6795   1.1      haad 	spa_fini();
   6796   1.1      haad 	if (zfs_nfsshare_inited)
   6797   1.1      haad 		(void) ddi_modclose(nfs_mod);
   6798   1.1      haad 	if (zfs_smbshare_inited)
   6799   1.1      haad 		(void) ddi_modclose(smbsrv_mod);
   6800   1.1      haad 	if (zfs_nfsshare_inited || zfs_smbshare_inited)
   6801   1.1      haad 		(void) ddi_modclose(sharefs_mod);
   6802   1.1      haad 
   6803   1.1      haad 	ldi_ident_release(zfs_li);
   6804   1.1      haad 	zfs_li = NULL;
   6805   1.1      haad 	mutex_destroy(&zfs_share_lock);
   6806   1.1      haad 
   6807   1.1      haad 	return (error);
   6808   1.1      haad }
   6809   1.1      haad 
   6810   1.1      haad int
   6811   1.1      haad _info(struct modinfo *modinfop)
   6812   1.1      haad {
   6813   1.1      haad 	return (mod_info(&modlinkage, modinfop));
   6814   1.1      haad }
   6815  1.11       chs #endif	/* illumos */
   6816  1.11       chs 
   6817  1.11       chs #ifdef __FreeBSD__
   6818  1.11       chs static struct cdevsw zfs_cdevsw = {
   6819  1.11       chs 	.d_version =	D_VERSION,
   6820  1.11       chs 	.d_open =	zfsdev_open,
   6821  1.11       chs 	.d_ioctl =	zfsdev_ioctl,
   6822  1.11       chs 	.d_name =	ZFS_DEV_NAME
   6823  1.11       chs };
   6824  1.11       chs 
   6825  1.11       chs static void
   6826  1.11       chs zfsdev_init(void)
   6827  1.11       chs {
   6828  1.11       chs 	zfsdev = make_dev(&zfs_cdevsw, 0x0, UID_ROOT, GID_OPERATOR, 0666,
   6829  1.11       chs 	    ZFS_DEV_NAME);
   6830  1.11       chs }
   6831  1.11       chs 
   6832  1.11       chs static void
   6833  1.11       chs zfsdev_fini(void)
   6834  1.11       chs {
   6835  1.11       chs 	if (zfsdev != NULL)
   6836  1.11       chs 		destroy_dev(zfsdev);
   6837  1.11       chs }
   6838  1.11       chs 
   6839  1.11       chs static struct root_hold_token *zfs_root_token;
   6840  1.11       chs struct proc *zfsproc;
   6841  1.11       chs 
   6842  1.11       chs static int zfs__init(void);
   6843  1.11       chs static int zfs__fini(void);
   6844  1.11       chs static void zfs_shutdown(void *, int);
   6845  1.11       chs 
   6846  1.11       chs static eventhandler_tag zfs_shutdown_event_tag;
   6847  1.11       chs 
   6848  1.11       chs #define ZFS_MIN_KSTACK_PAGES 4
   6849  1.11       chs 
   6850  1.11       chs int
   6851  1.11       chs zfs__init(void)
   6852  1.11       chs {
   6853  1.11       chs 
   6854  1.11       chs #if KSTACK_PAGES < ZFS_MIN_KSTACK_PAGES
   6855  1.11       chs 	printf("ZFS NOTICE: KSTACK_PAGES is %d which could result in stack "
   6856  1.11       chs 	    "overflow panic!\nPlease consider adding "
   6857  1.11       chs 	    "'options KSTACK_PAGES=%d' to your kernel config\n", KSTACK_PAGES,
   6858  1.11       chs 	    ZFS_MIN_KSTACK_PAGES);
   6859  1.11       chs #endif
   6860  1.11       chs 	zfs_root_token = root_mount_hold("ZFS");
   6861  1.11       chs 
   6862  1.11       chs 	mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
   6863  1.11       chs 
   6864  1.11       chs 	spa_init(FREAD | FWRITE);
   6865  1.11       chs 	zfs_init();
   6866  1.11       chs 	zvol_init();
   6867  1.11       chs 	zfs_ioctl_init();
   6868  1.11       chs 
   6869  1.11       chs 	tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
   6870  1.11       chs 	tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
   6871  1.11       chs 	tsd_create(&zfs_geom_probe_vdev_key, NULL);
   6872  1.11       chs 
   6873  1.11       chs 	printf("ZFS storage pool version: features support (" SPA_VERSION_STRING ")\n");
   6874  1.11       chs 	root_mount_rel(zfs_root_token);
   6875  1.11       chs 
   6876  1.11       chs 	zfsdev_init();
   6877  1.11       chs 
   6878  1.11       chs 	return (0);
   6879  1.11       chs }
   6880  1.11       chs 
   6881  1.11       chs int
   6882  1.11       chs zfs__fini(void)
   6883  1.11       chs {
   6884  1.11       chs 	if (spa_busy() || zfs_busy() || zvol_busy() ||
   6885  1.11       chs 	    zio_injection_enabled) {
   6886  1.11       chs 		return (EBUSY);
   6887  1.11       chs 	}
   6888  1.11       chs 
   6889  1.11       chs 	zfsdev_fini();
   6890  1.11       chs 	zvol_fini();
   6891  1.11       chs 	zfs_fini();
   6892  1.11       chs 	spa_fini();
   6893  1.11       chs 
   6894  1.11       chs 	tsd_destroy(&rrw_tsd_key);
   6895  1.11       chs 	tsd_destroy(&zfs_allow_log_key);
   6896  1.11       chs 
   6897  1.11       chs 	mutex_destroy(&zfs_share_lock);
   6898  1.11       chs 
   6899  1.11       chs 	return (0);
   6900  1.11       chs }
   6901  1.11       chs 
   6902  1.11       chs static void
   6903  1.11       chs zfs_shutdown(void *arg __unused, int howto __unused)
   6904  1.11       chs {
   6905  1.11       chs 
   6906  1.11       chs 	/*
   6907  1.11       chs 	 * ZFS fini routines can not properly work in a panic-ed system.
   6908  1.11       chs 	 */
   6909  1.11       chs 	if (panicstr == NULL)
   6910  1.11       chs 		(void)zfs__fini();
   6911  1.11       chs }
   6912  1.11       chs 
   6913  1.11       chs 
   6914  1.11       chs static int
   6915  1.11       chs zfs_modevent(module_t mod, int type, void *unused __unused)
   6916  1.11       chs {
   6917  1.11       chs 	int err;
   6918  1.11       chs 
   6919  1.11       chs 	switch (type) {
   6920  1.11       chs 	case MOD_LOAD:
   6921  1.11       chs 		err = zfs__init();
   6922  1.11       chs 		if (err == 0)
   6923  1.11       chs 			zfs_shutdown_event_tag = EVENTHANDLER_REGISTER(
   6924  1.11       chs 			    shutdown_post_sync, zfs_shutdown, NULL,
   6925  1.11       chs 			    SHUTDOWN_PRI_FIRST);
   6926  1.11       chs 		return (err);
   6927  1.11       chs 	case MOD_UNLOAD:
   6928  1.11       chs 		err = zfs__fini();
   6929  1.11       chs 		if (err == 0 && zfs_shutdown_event_tag != NULL)
   6930  1.11       chs 			EVENTHANDLER_DEREGISTER(shutdown_post_sync,
   6931  1.11       chs 			    zfs_shutdown_event_tag);
   6932  1.11       chs 		return (err);
   6933  1.11       chs 	case MOD_SHUTDOWN:
   6934  1.11       chs 		return (0);
   6935  1.11       chs 	default:
   6936  1.11       chs 		break;
   6937  1.11       chs 	}
   6938  1.11       chs 	return (EOPNOTSUPP);
   6939  1.11       chs }
   6940  1.11       chs 
   6941  1.11       chs static moduledata_t zfs_mod = {
   6942  1.11       chs 	"zfsctrl",
   6943  1.11       chs 	zfs_modevent,
   6944  1.11       chs 	0
   6945  1.11       chs };
   6946  1.11       chs DECLARE_MODULE(zfsctrl, zfs_mod, SI_SUB_VFS, SI_ORDER_ANY);
   6947  1.11       chs MODULE_VERSION(zfsctrl, 1);
   6948  1.11       chs MODULE_DEPEND(zfsctrl, opensolaris, 1, 1, 1);
   6949  1.11       chs MODULE_DEPEND(zfsctrl, krpc, 1, 1, 1);
   6950  1.11       chs MODULE_DEPEND(zfsctrl, acl_nfs4, 1, 1, 1);
   6951  1.11       chs 
   6952  1.11       chs #endif /* __FreeBSD__ */
   6953  1.11       chs 
   6954  1.11       chs #ifdef __NetBSD__
   6955  1.11       chs 
   6956  1.11       chs #include <sys/module.h>
   6957  1.11       chs #include <uvm/uvm_extern.h>
   6958  1.11       chs 
   6959  1.17   hannken MODULE(MODULE_CLASS_VFS, zfs, "solaris");
   6960  1.11       chs 
   6961  1.15   hannken static const struct fileops zfs_fileops;
   6962  1.15   hannken 
   6963  1.15   hannken static int
   6964  1.15   hannken nb_zfsdev_fioctl(struct file *fp,  u_long cmd, void *argp)
   6965  1.15   hannken {
   6966  1.15   hannken 	dev_t dev = (dev_t)(uintptr_t)fp->f_data;
   6967  1.15   hannken 	int rval;
   6968  1.15   hannken 
   6969  1.15   hannken 	return zfsdev_ioctl(dev, cmd, (intptr_t)argp, fp->f_flag,
   6970  1.15   hannken 	    kauth_cred_get(), &rval);
   6971  1.15   hannken }
   6972  1.15   hannken 
   6973  1.15   hannken static int
   6974  1.15   hannken nb_zfsdev_fclose(struct file *fp)
   6975  1.15   hannken {
   6976  1.15   hannken 	dev_t dev = (dev_t)(uintptr_t)fp->f_data;
   6977  1.15   hannken 	int error;
   6978  1.15   hannken 
   6979  1.15   hannken 	return zfsdev_close(dev, fp->f_flag, OTYPCHR, fp->f_cred);
   6980  1.15   hannken }
   6981  1.15   hannken 
   6982  1.11       chs static int
   6983  1.11       chs nb_zfsdev_copen(dev_t dev, int flag, int mode, lwp_t *l)
   6984  1.11       chs {
   6985  1.15   hannken 	const bool must_clone = (getminor(dev) == 0 && (flag & FEXCL) != 0);
   6986  1.15   hannken 	struct file *fp;
   6987  1.15   hannken 	int error, fd;
   6988  1.15   hannken 
   6989  1.15   hannken 	if (must_clone) {
   6990  1.15   hannken 		error = fd_allocfile(&fp, &fd);
   6991  1.15   hannken 		if (error)
   6992  1.15   hannken 			return error;
   6993  1.15   hannken 	}
   6994  1.15   hannken 
   6995  1.15   hannken 	error = zfsdev_open(&dev, flag, OTYPCHR, kauth_cred_get());
   6996  1.11       chs 
   6997  1.15   hannken 	if (must_clone) {
   6998  1.15   hannken 		if (error) {
   6999  1.15   hannken 			fd_abort(curproc, fp, fd);
   7000  1.15   hannken 			return error;
   7001  1.15   hannken 		}
   7002  1.15   hannken 		return fd_clone(fp, fd, flag, &zfs_fileops,
   7003  1.15   hannken 		    (void *)(uintptr_t)dev);
   7004  1.15   hannken 	}
   7005  1.15   hannken 
   7006  1.15   hannken 	return error;
   7007  1.11       chs }
   7008  1.11       chs 
   7009  1.11       chs static int
   7010  1.11       chs nb_zfsdev_cclose(dev_t dev, int flag, int mode, lwp_t *l)
   7011  1.11       chs {
   7012  1.11       chs 
   7013  1.11       chs 	return zfsdev_close(dev, flag, OTYPCHR, kauth_cred_get());
   7014  1.11       chs }
   7015  1.11       chs 
   7016  1.11       chs static int
   7017  1.11       chs nb_zfsdev_bopen(dev_t dev, int flag, int mode, lwp_t *l)
   7018  1.11       chs {
   7019  1.11       chs 
   7020  1.11       chs 	return zfsdev_open(&dev, flag, OTYPBLK, kauth_cred_get());
   7021  1.11       chs }
   7022  1.11       chs 
   7023  1.11       chs static int
   7024  1.11       chs nb_zfsdev_bclose(dev_t dev, int flag, int mode, lwp_t *l)
   7025  1.11       chs {
   7026  1.11       chs 
   7027  1.11       chs 	return zfsdev_close(dev, flag, OTYPBLK, kauth_cred_get());
   7028  1.11       chs }
   7029  1.11       chs 
   7030  1.11       chs static int
   7031  1.11       chs nb_zvol_read(dev_t dev, struct uio *uio, int flag)
   7032  1.11       chs {
   7033  1.11       chs 
   7034  1.11       chs 	return zvol_read(dev, uio, kauth_cred_get());
   7035  1.11       chs }
   7036  1.11       chs 
   7037  1.11       chs static int
   7038  1.11       chs nb_zvol_write(dev_t dev, struct uio *uio, int flag)
   7039  1.11       chs {
   7040  1.11       chs 
   7041  1.11       chs 	return zvol_write(dev, uio, kauth_cred_get());
   7042  1.11       chs }
   7043  1.11       chs 
   7044  1.11       chs static int
   7045  1.11       chs nb_zfsdev_ioctl(dev_t dev, u_long cmd, void *argp, int flag, lwp_t *l)
   7046  1.11       chs {
   7047  1.11       chs 	int rval;
   7048  1.11       chs 
   7049  1.11       chs 	return zfsdev_ioctl(dev, cmd, (intptr_t)argp, flag, kauth_cred_get(),
   7050  1.11       chs 	    &rval);
   7051  1.11       chs }
   7052  1.11       chs 
   7053  1.11       chs static void
   7054  1.11       chs nb_zvol_strategy(struct buf *bp)
   7055  1.11       chs {
   7056  1.11       chs 
   7057  1.11       chs 	(void) zvol_strategy(bp);
   7058  1.11       chs }
   7059  1.11       chs 
   7060  1.15   hannken static const struct fileops zfs_fileops = {
   7061  1.15   hannken 	.fo_name = "zfs",
   7062  1.15   hannken 	.fo_read = fbadop_read,
   7063  1.15   hannken 	.fo_write = fbadop_write,
   7064  1.15   hannken 	.fo_ioctl = nb_zfsdev_fioctl,
   7065  1.15   hannken 	.fo_fcntl = fnullop_fcntl,
   7066  1.15   hannken 	.fo_poll = fnullop_poll,
   7067  1.15   hannken 	.fo_stat = fbadop_stat,
   7068  1.15   hannken 	.fo_close = nb_zfsdev_fclose,
   7069  1.15   hannken 	.fo_kqfilter = fnullop_kqfilter,
   7070  1.15   hannken 	.fo_restart = fnullop_restart,
   7071  1.15   hannken };
   7072  1.15   hannken 
   7073  1.11       chs const struct bdevsw zfs_bdevsw = {
   7074  1.11       chs 	.d_open = nb_zfsdev_bopen,
   7075  1.11       chs 	.d_close = nb_zfsdev_bclose,
   7076  1.11       chs 	.d_strategy = nb_zvol_strategy,
   7077  1.11       chs 	.d_ioctl = nb_zfsdev_ioctl,
   7078  1.11       chs 	.d_dump = nodump,
   7079  1.26  riastrad 	.d_psize = nosize,
   7080  1.11       chs 	.d_flag = D_DISK | D_MPSAFE
   7081  1.11       chs };
   7082  1.11       chs 
   7083  1.11       chs const struct cdevsw zfs_cdevsw = {
   7084  1.11       chs 	.d_open = nb_zfsdev_copen,
   7085  1.11       chs 	.d_close = nb_zfsdev_cclose,
   7086  1.11       chs 	.d_read = nb_zvol_read,
   7087  1.11       chs 	.d_write = nb_zvol_write,
   7088  1.11       chs 	.d_ioctl = nb_zfsdev_ioctl,
   7089  1.11       chs 	.d_stop = nostop,
   7090  1.11       chs 	.d_tty = notty,
   7091  1.11       chs 	.d_poll = nopoll,
   7092  1.11       chs 	.d_mmap = nommap,
   7093  1.11       chs 	.d_kqfilter = nokqfilter,
   7094  1.11       chs 	.d_flag = D_DISK | D_MPSAFE
   7095  1.11       chs };
   7096  1.11       chs 
   7097  1.11       chs /* ZFS should only be used on systems with enough memory. */
   7098  1.11       chs #define ZFS_MIN_MEGS 512
   7099  1.11       chs 
   7100  1.11       chs static int zfs_version_ioctl = ZFS_IOCVER_CURRENT;
   7101  1.11       chs static int zfs_version_spa = SPA_VERSION;
   7102  1.11       chs static struct sysctllog *zfs_sysctl_log;
   7103  1.11       chs 
   7104  1.11       chs static void
   7105  1.11       chs zfs_sysctl_init(void)
   7106  1.11       chs {
   7107  1.11       chs 	const struct sysctlnode *rnode;
   7108  1.11       chs 
   7109  1.11       chs 	sysctl_createv(&zfs_sysctl_log, 0, NULL, &rnode,
   7110  1.11       chs 		       CTLFLAG_PERMANENT,
   7111  1.11       chs 		       CTLTYPE_NODE, "zfs",
   7112  1.11       chs 		       SYSCTL_DESCR("zfs"),
   7113  1.11       chs 		       NULL, 0, NULL, 0,
   7114  1.11       chs 		       CTL_VFS, CTL_CREATE, CTL_EOL);
   7115  1.11       chs 
   7116  1.11       chs 	sysctl_createv(&zfs_sysctl_log, 0, &rnode, &rnode,
   7117  1.11       chs 		       CTLFLAG_PERMANENT,
   7118  1.11       chs 		       CTLTYPE_NODE, "version",
   7119  1.11       chs 		       SYSCTL_DESCR("version"),
   7120  1.11       chs 		       NULL, 0, NULL, 0,
   7121  1.11       chs 		       CTL_CREATE, CTL_EOL);
   7122  1.11       chs 
   7123  1.11       chs 	sysctl_createv(&zfs_sysctl_log, 0, &rnode, NULL,
   7124  1.11       chs 		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
   7125  1.11       chs 		       CTLTYPE_INT, "ioctl",
   7126  1.11       chs 		       SYSCTL_DESCR("ZFS ioctl version"),
   7127  1.11       chs 		       NULL, 0, &zfs_version_ioctl, 0,
   7128  1.11       chs 		       CTL_CREATE, CTL_EOL);
   7129  1.11       chs 
   7130  1.11       chs 	sysctl_createv(&zfs_sysctl_log, 0, &rnode, NULL,
   7131  1.11       chs 		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
   7132  1.11       chs 		       CTLTYPE_INT, "spa",
   7133  1.11       chs 		       SYSCTL_DESCR("ZFS SPA version"),
   7134  1.11       chs 		       NULL, 0, &zfs_version_spa, 0,
   7135  1.11       chs 		       CTL_CREATE, CTL_EOL);
   7136  1.11       chs }
   7137  1.11       chs 
   7138  1.11       chs static void
   7139  1.11       chs zfs_sysctl_fini(void)
   7140  1.11       chs {
   7141  1.11       chs 
   7142  1.11       chs 	sysctl_teardown(&zfs_sysctl_log);
   7143  1.11       chs }
   7144  1.11       chs 
   7145  1.11       chs 
   7146  1.11       chs static void
   7147  1.11       chs zfs_loadvnode_destroy(void *arg)
   7148  1.11       chs {
   7149  1.11       chs 
   7150  1.11       chs 	if (arg != NULL)
   7151  1.11       chs 		panic("thread exiting with TSD loadvnode data %p", arg);
   7152  1.11       chs }
   7153  1.11       chs 
   7154  1.11       chs static int
   7155  1.11       chs zfs_modcmd(modcmd_t cmd, void *arg)
   7156  1.11       chs {
   7157  1.11       chs 	int error;
   7158  1.11       chs 	int active, inactive;
   7159  1.11       chs 	uint64_t availrmem;
   7160  1.11       chs 
   7161  1.11       chs 	extern struct vfsops zfs_vfsops;
   7162  1.11       chs 	extern uint_t zfs_putpage_key;
   7163  1.11       chs 
   7164  1.11       chs 	switch (cmd) {
   7165  1.11       chs 	case MODULE_CMD_INIT:
   7166  1.11       chs 		/* XXXNETBSD trim is not supported yet */
   7167  1.11       chs 		zfs_trim_enabled = B_FALSE;
   7168  1.11       chs 
   7169  1.11       chs 		availrmem = (uint64_t)physmem * PAGE_SIZE / 1048576;
   7170  1.11       chs 		if (availrmem < ZFS_MIN_MEGS * 80 / 100) {
   7171  1.12      gson 			printf("ERROR: at least %dMB of memory required to "
   7172  1.11       chs 			    "use ZFS\n", ZFS_MIN_MEGS);
   7173  1.11       chs 			return ENOMEM;
   7174  1.11       chs 		}
   7175  1.11       chs 		mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
   7176  1.11       chs 		mutex_init(&zfs_debug_mtx, NULL, MUTEX_DEFAULT, NULL);
   7177  1.11       chs 
   7178  1.11       chs 		tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
   7179  1.11       chs 		tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
   7180  1.11       chs 		tsd_create(&zfs_putpage_key, NULL);
   7181  1.11       chs 
   7182  1.11       chs 		spa_init(FREAD | FWRITE);
   7183  1.11       chs 		zfs_init();
   7184  1.11       chs 		zvol_init();
   7185  1.11       chs 		zfs_ioctl_init();
   7186  1.11       chs 		zfs_sysctl_init();
   7187  1.11       chs 
   7188  1.18   hannken 		error = devsw_attach("zfs", &zfs_bdevsw, &zfs_dip->di_bmajor,
   7189  1.18   hannken 		    &zfs_cdevsw, &zfs_dip->di_cmajor);
   7190  1.11       chs 		if (error != 0) {
   7191  1.11       chs 			goto attacherr;
   7192  1.11       chs 		}
   7193  1.11       chs 		(void) vfs_attach(&zfs_vfsops);
   7194  1.11       chs 		return error;
   7195  1.11       chs 
   7196  1.11       chs 	case MODULE_CMD_FINI:
   7197  1.11       chs 		if (spa_busy() || zfs_busy() || zvol_busy() ||
   7198  1.11       chs 		    zio_injection_enabled)
   7199  1.11       chs 			return EBUSY;
   7200  1.11       chs 
   7201  1.11       chs 		error = vfs_detach(&zfs_vfsops);
   7202  1.11       chs 		if (error)
   7203  1.11       chs 			return error;
   7204  1.11       chs 
   7205  1.24  riastrad 		devsw_detach(&zfs_bdevsw, &zfs_cdevsw);
   7206  1.11       chs 
   7207  1.11       chs attacherr:
   7208  1.11       chs 		zfs_sysctl_fini();
   7209  1.11       chs 		zvol_fini();
   7210  1.11       chs 		zfs_fini();
   7211  1.11       chs 		spa_fini();
   7212  1.11       chs 
   7213  1.11       chs 		tsd_destroy(&zfs_putpage_key);
   7214  1.11       chs 		tsd_destroy(&rrw_tsd_key);
   7215  1.11       chs 		tsd_destroy(&zfs_allow_log_key);
   7216  1.11       chs 
   7217  1.11       chs 		mutex_destroy(&zfs_debug_mtx);
   7218  1.11       chs 		mutex_destroy(&zfs_share_lock);
   7219  1.11       chs 
   7220  1.11       chs 		return error;
   7221  1.11       chs 
   7222  1.11       chs 	case MODULE_CMD_AUTOUNLOAD:
   7223  1.11       chs 		/*
   7224  1.11       chs 		 * We don't want to be autounloaded because unlike
   7225  1.11       chs 		 * other subsystems, we read our own configuration
   7226  1.11       chs 		 * from disk and provide things that might be used
   7227  1.11       chs 		 * later (zvols).
   7228  1.11       chs 		 */
   7229  1.11       chs 		return EBUSY;
   7230  1.11       chs 
   7231  1.11       chs 	default:
   7232  1.11       chs 		return ENOTTY;
   7233  1.11       chs 	}
   7234  1.11       chs }
   7235  1.11       chs 
   7236  1.11       chs #endif /* __NetBSD__ */
   7237