FreeBSD ZFS
The Zettabyte File System

zfs_ioctl.c

Go to the documentation of this file.
00001 /*
00002  * CDDL HEADER START
00003  *
00004  * The contents of this file are subject to the terms of the
00005  * Common Development and Distribution License (the "License").
00006  * You may not use this file except in compliance with the License.
00007  *
00008  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
00009  * or http://www.opensolaris.org/os/licensing.
00010  * See the License for the specific language governing permissions
00011  * and limitations under the License.
00012  *
00013  * When distributing Covered Code, include this CDDL HEADER in each
00014  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
00015  * If applicable, add the following below this CDDL HEADER, with the
00016  * fields enclosed by brackets "[]" replaced with your own identifying
00017  * information: Portions Copyright [yyyy] [name of copyright owner]
00018  *
00019  * CDDL HEADER END
00020  */
00021 
00022 /*
00023  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
00024  * Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
00025  * All rights reserved.
00026  * Portions Copyright 2011 Martin Matuska <mm@FreeBSD.org>
00027  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
00028  * Copyright (c) 2012 by Delphix. All rights reserved.
00029  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
00030  */
00031 
00032 #include <sys/types.h>
00033 #include <sys/param.h>
00034 #include <sys/systm.h>
00035 #include <sys/conf.h>
00036 #include <sys/kernel.h>
00037 #include <sys/lock.h>
00038 #include <sys/malloc.h>
00039 #include <sys/mutex.h>
00040 #include <sys/proc.h>
00041 #include <sys/errno.h>
00042 #include <sys/uio.h>
00043 #include <sys/buf.h>
00044 #include <sys/file.h>
00045 #include <sys/kmem.h>
00046 #include <sys/conf.h>
00047 #include <sys/cmn_err.h>
00048 #include <sys/stat.h>
00049 #include <sys/zfs_ioctl.h>
00050 #include <sys/zfs_vfsops.h>
00051 #include <sys/zfs_znode.h>
00052 #include <sys/zap.h>
00053 #include <sys/spa.h>
00054 #include <sys/spa_impl.h>
00055 #include <sys/vdev.h>
00056 #include <sys/dmu.h>
00057 #include <sys/dsl_dir.h>
00058 #include <sys/dsl_dataset.h>
00059 #include <sys/dsl_prop.h>
00060 #include <sys/dsl_deleg.h>
00061 #include <sys/dmu_objset.h>
00062 #include <sys/dmu_impl.h>
00063 #include <sys/sunddi.h>
00064 #include <sys/policy.h>
00065 #include <sys/zone.h>
00066 #include <sys/nvpair.h>
00067 #include <sys/mount.h>
00068 #include <sys/taskqueue.h>
00069 #include <sys/sdt.h>
00070 #include <sys/varargs.h>
00071 #include <sys/fs/zfs.h>
00072 #include <sys/zfs_ctldir.h>
00073 #include <sys/zfs_dir.h>
00074 #include <sys/zfs_onexit.h>
00075 #include <sys/zvol.h>
00076 #include <sys/dsl_scan.h>
00077 #include <sys/dmu_objset.h>
00078 
00079 #include "zfs_namecheck.h"
00080 #include "zfs_prop.h"
00081 #include "zfs_deleg.h"
00082 #include "zfs_comutil.h"
00083 #include "zfs_ioctl_compat.h"
00084 
00085 CTASSERT(sizeof(zfs_cmd_t) < IOCPARM_MAX);
00086 
00087 static int snapshot_list_prefetch;
00088 SYSCTL_DECL(_vfs_zfs);
00089 TUNABLE_INT("vfs.zfs.snapshot_list_prefetch", &snapshot_list_prefetch);
00090 SYSCTL_INT(_vfs_zfs, OID_AUTO, snapshot_list_prefetch, CTLFLAG_RW,
00091     &snapshot_list_prefetch, 0, "Prefetch data when listing snapshots");
00092 
00093 static struct cdev *zfsdev;
00094 
00095 extern void zfs_init(void);
00096 extern void zfs_fini(void);
00097 
00098 typedef int zfs_ioc_func_t(zfs_cmd_t *);
00099 typedef int zfs_secpolicy_func_t(zfs_cmd_t *, cred_t *);
00100 
00101 typedef enum {
00102         NO_NAME,
00103         POOL_NAME,
00104         DATASET_NAME
00105 } zfs_ioc_namecheck_t;
00106 
00107 typedef struct zfs_ioc_vec {
00108         zfs_ioc_func_t          *zvec_func;
00109         zfs_secpolicy_func_t    *zvec_secpolicy;
00110         zfs_ioc_namecheck_t     zvec_namecheck;
00111         boolean_t               zvec_his_log;
00112         boolean_t               zvec_pool_check;
00113 } zfs_ioc_vec_t;
00114 
00116 static const char *userquota_perms[] = {
00117         ZFS_DELEG_PERM_USERUSED,
00118         ZFS_DELEG_PERM_USERQUOTA,
00119         ZFS_DELEG_PERM_GROUPUSED,
00120         ZFS_DELEG_PERM_GROUPQUOTA,
00121 };
00122 
00123 static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
00124 static int zfs_check_settable(const char *name, nvpair_t *property,
00125     cred_t *cr);
00126 static int zfs_check_clearable(char *dataset, nvlist_t *props,
00127     nvlist_t **errors);
00128 static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
00129     boolean_t *);
00130 int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t **);
00131  
00132 static void zfsdev_close(void *data);
00133 
00134 /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
00135 void
00136 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
00137 {
00138         const char *newfile;
00139         char buf[512];
00140         va_list adx;
00141 
00142         /*
00143          * Get rid of annoying "../common/" prefix to filename.
00144          */
00145         newfile = strrchr(file, '/');
00146         if (newfile != NULL) {
00147                 newfile = newfile + 1; /* Get rid of leading / */
00148         } else {
00149                 newfile = file;
00150         }
00151 
00152         va_start(adx, fmt);
00153         (void) vsnprintf(buf, sizeof (buf), fmt, adx);
00154         va_end(adx);
00155 
00156         /*
00157          * To get this data, use the zfs-dprintf probe as so:
00158          * dtrace -q -n 'zfs-dprintf \
00159          *      /stringof(arg0) == "dbuf.c"/ \
00160          *      {printf("%s: %s", stringof(arg1), stringof(arg3))}'
00161          * arg0 = file name
00162          * arg1 = function name
00163          * arg2 = line number
00164          * arg3 = message
00165          */
00166         DTRACE_PROBE4(zfs__dprintf,
00167             char *, newfile, char *, func, int, line, char *, buf);
00168 }
00169 
00170 static void
00171 history_str_free(char *buf)
00172 {
00173         kmem_free(buf, HIS_MAX_RECORD_LEN);
00174 }
00175 
00176 static char *
00177 history_str_get(zfs_cmd_t *zc)
00178 {
00179         char *buf;
00180 
00181         if (zc->zc_history == 0)
00182                 return (NULL);
00183 
00184         buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP);
00185         if (copyinstr((void *)(uintptr_t)zc->zc_history,
00186             buf, HIS_MAX_RECORD_LEN, NULL) != 0) {
00187                 history_str_free(buf);
00188                 return (NULL);
00189         }
00190 
00191         buf[HIS_MAX_RECORD_LEN -1] = '\0';
00192 
00193         return (buf);
00194 }
00195 
00199 static boolean_t
00200 zfs_is_bootfs(const char *name)
00201 {
00202         objset_t *os;
00203 
00204         if (dmu_objset_hold(name, FTAG, &os) == 0) {
00205                 boolean_t ret;
00206                 ret = (dmu_objset_id(os) == spa_bootfs(dmu_objset_spa(os)));
00207                 dmu_objset_rele(os, FTAG);
00208                 return (ret);
00209         }
00210         return (B_FALSE);
00211 }
00212 
00216 static int
00217 zfs_earlier_version(const char *name, int version)
00218 {
00219         spa_t *spa;
00220 
00221         if (spa_open(name, &spa, FTAG) == 0) {
00222                 if (spa_version(spa) < version) {
00223                         spa_close(spa, FTAG);
00224                         return (1);
00225                 }
00226                 spa_close(spa, FTAG);
00227         }
00228         return (0);
00229 }
00230 
00234 static boolean_t
00235 zpl_earlier_version(const char *name, int version)
00236 {
00237         objset_t *os;
00238         boolean_t rc = B_TRUE;
00239 
00240         if (dmu_objset_hold(name, FTAG, &os) == 0) {
00241                 uint64_t zplversion;
00242 
00243                 if (dmu_objset_type(os) != DMU_OST_ZFS) {
00244                         dmu_objset_rele(os, FTAG);
00245                         return (B_TRUE);
00246                 }
00247                 /* XXX reading from non-owned objset */
00248                 if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0)
00249                         rc = zplversion < version;
00250                 dmu_objset_rele(os, FTAG);
00251         }
00252         return (rc);
00253 }
00254 
00255 static void
00256 zfs_log_history(zfs_cmd_t *zc)
00257 {
00258         spa_t *spa;
00259         char *buf;
00260 
00261         if ((buf = history_str_get(zc)) == NULL)
00262                 return;
00263 
00264         if (spa_open(zc->zc_name, &spa, FTAG) == 0) {
00265                 if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
00266                         (void) spa_history_log(spa, buf, LOG_CMD_NORMAL);
00267                 spa_close(spa, FTAG);
00268         }
00269         history_str_free(buf);
00270 }
00271 
00276 /* ARGSUSED */
00277 static int
00278 zfs_secpolicy_none(zfs_cmd_t *zc, cred_t *cr)
00279 {
00280         return (0);
00281 }
00282 
00287 /* ARGSUSED */
00288 static int
00289 zfs_secpolicy_read(zfs_cmd_t *zc, cred_t *cr)
00290 {
00291         if (INGLOBALZONE(curthread) ||
00292             zone_dataset_visible(zc->zc_name, NULL))
00293                 return (0);
00294 
00295         return (ENOENT);
00296 }
00297 
00298 static int
00299 zfs_dozonecheck_impl(const char *dataset, uint64_t zoned, cred_t *cr)
00300 {
00301         int writable = 1;
00302 
00303         /*
00304          * The dataset must be visible by this zone -- check this first
00305          * so they don't see EPERM on something they shouldn't know about.
00306          */
00307         if (!INGLOBALZONE(curthread) &&
00308             !zone_dataset_visible(dataset, &writable))
00309                 return (ENOENT);
00310 
00311         if (INGLOBALZONE(curthread)) {
00312                 /*
00313                  * If the fs is zoned, only root can access it from the
00314                  * global zone.
00315                  */
00316                 if (secpolicy_zfs(cr) && zoned)
00317                         return (EPERM);
00318         } else {
00319                 /*
00320                  * If we are in a local zone, the 'zoned' property must be set.
00321                  */
00322                 if (!zoned)
00323                         return (EPERM);
00324 
00325                 /* must be writable by this zone */
00326                 if (!writable)
00327                         return (EPERM);
00328         }
00329         return (0);
00330 }
00331 
00332 static int
00333 zfs_dozonecheck(const char *dataset, cred_t *cr)
00334 {
00335         uint64_t zoned;
00336 
00337         if (dsl_prop_get_integer(dataset, "jailed", &zoned, NULL))
00338                 return (ENOENT);
00339 
00340         return (zfs_dozonecheck_impl(dataset, zoned, cr));
00341 }
00342 
00343 static int
00344 zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr)
00345 {
00346         uint64_t zoned;
00347 
00348         rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER);
00349         if (dsl_prop_get_ds(ds, "jailed", 8, 1, &zoned, NULL)) {
00350                 rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock);
00351                 return (ENOENT);
00352         }
00353         rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock);
00354 
00355         return (zfs_dozonecheck_impl(dataset, zoned, cr));
00356 }
00357 
00358 /*
00359  * If name ends in a '@', then require recursive permissions.
00360  */
00361 int
00362 zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr)
00363 {
00364         int error;
00365         boolean_t descendent = B_FALSE;
00366         dsl_dataset_t *ds;
00367         char *at;
00368 
00369         at = strchr(name, '@');
00370         if (at != NULL && at[1] == '\0') {
00371                 *at = '\0';
00372                 descendent = B_TRUE;
00373         }
00374 
00375         error = dsl_dataset_hold(name, FTAG, &ds);
00376         if (at != NULL)
00377                 *at = '@';
00378         if (error != 0)
00379                 return (error);
00380 
00381         error = zfs_dozonecheck_ds(name, ds, cr);
00382         if (error == 0) {
00383                 error = secpolicy_zfs(cr);
00384                 if (error)
00385                         error = dsl_deleg_access_impl(ds, descendent, perm, cr);
00386         }
00387 
00388         dsl_dataset_rele(ds, FTAG);
00389         return (error);
00390 }
00391 
00392 int
00393 zfs_secpolicy_write_perms_ds(const char *name, dsl_dataset_t *ds,
00394     const char *perm, cred_t *cr)
00395 {
00396         int error;
00397 
00398         error = zfs_dozonecheck_ds(name, ds, cr);
00399         if (error == 0) {
00400                 error = secpolicy_zfs(cr);
00401                 if (error)
00402                         error = dsl_deleg_access_impl(ds, B_FALSE, perm, cr);
00403         }
00404         return (error);
00405 }
00406 
00407 #ifdef SECLABEL
00408 
00413 static int
00414 zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr)
00415 {
00416         char            ds_hexsl[MAXNAMELEN];
00417         bslabel_t       ds_sl, new_sl;
00418         boolean_t       new_default = FALSE;
00419         uint64_t        zoned;
00420         int             needed_priv = -1;
00421         int             error;
00422 
00423         /* First get the existing dataset label. */
00424         error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
00425             1, sizeof (ds_hexsl), &ds_hexsl, NULL);
00426         if (error)
00427                 return (EPERM);
00428 
00429         if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
00430                 new_default = TRUE;
00431 
00432         /* The label must be translatable */
00433         if (!new_default && (hexstr_to_label(strval, &new_sl) != 0))
00434                 return (EINVAL);
00435 
00436         /*
00437          * In a non-global zone, disallow attempts to set a label that
00438          * doesn't match that of the zone; otherwise no other checks
00439          * are needed.
00440          */
00441         if (!INGLOBALZONE(curproc)) {
00442                 if (new_default || !blequal(&new_sl, CR_SL(CRED())))
00443                         return (EPERM);
00444                 return (0);
00445         }
00446 
00447         /*
00448          * For global-zone datasets (i.e., those whose zoned property is
00449          * "off", verify that the specified new label is valid for the
00450          * global zone.
00451          */
00452         if (dsl_prop_get_integer(name,
00453             zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
00454                 return (EPERM);
00455         if (!zoned) {
00456                 if (zfs_check_global_label(name, strval) != 0)
00457                         return (EPERM);
00458         }
00459 
00460         /*
00461          * If the existing dataset label is nondefault, check if the
00462          * dataset is mounted (label cannot be changed while mounted).
00463          * Get the zfsvfs; if there isn't one, then the dataset isn't
00464          * mounted (or isn't a dataset, doesn't exist, ...).
00465          */
00466         if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) {
00467                 objset_t *os;
00468                 static char *setsl_tag = "setsl_tag";
00469 
00470                 /*
00471                  * Try to own the dataset; abort if there is any error,
00472                  * (e.g., already mounted, in use, or other error).
00473                  */
00474                 error = dmu_objset_own(name, DMU_OST_ZFS, B_TRUE,
00475                     setsl_tag, &os);
00476                 if (error)
00477                         return (EPERM);
00478 
00479                 dmu_objset_disown(os, setsl_tag);
00480 
00481                 if (new_default) {
00482                         needed_priv = PRIV_FILE_DOWNGRADE_SL;
00483                         goto out_check;
00484                 }
00485 
00486                 if (hexstr_to_label(strval, &new_sl) != 0)
00487                         return (EPERM);
00488 
00489                 if (blstrictdom(&ds_sl, &new_sl))
00490                         needed_priv = PRIV_FILE_DOWNGRADE_SL;
00491                 else if (blstrictdom(&new_sl, &ds_sl))
00492                         needed_priv = PRIV_FILE_UPGRADE_SL;
00493         } else {
00494                 /* dataset currently has a default label */
00495                 if (!new_default)
00496                         needed_priv = PRIV_FILE_UPGRADE_SL;
00497         }
00498 
00499 out_check:
00500         if (needed_priv != -1)
00501                 return (PRIV_POLICY(cr, needed_priv, B_FALSE, EPERM, NULL));
00502         return (0);
00503 }
00504 #endif  /* SECLABEL */
00505 
00506 static int
00507 zfs_secpolicy_setprop(const char *dsname, zfs_prop_t prop, nvpair_t *propval,
00508     cred_t *cr)
00509 {
00510         char *strval;
00511 
00512         /*
00513          * Check permissions for special properties.
00514          */
00515         switch (prop) {
00516         case ZFS_PROP_ZONED:
00517                 /*
00518                  * Disallow setting of 'zoned' from within a local zone.
00519                  */
00520                 if (!INGLOBALZONE(curthread))
00521                         return (EPERM);
00522                 break;
00523 
00524         case ZFS_PROP_QUOTA:
00525                 if (!INGLOBALZONE(curthread)) {
00526                         uint64_t zoned;
00527                         char setpoint[MAXNAMELEN];
00528                         /*
00529                          * Unprivileged users are allowed to modify the
00530                          * quota on things *under* (ie. contained by)
00531                          * the thing they own.
00532                          */
00533                         if (dsl_prop_get_integer(dsname, "jailed", &zoned,
00534                             setpoint))
00535                                 return (EPERM);
00536                         if (!zoned || strlen(dsname) <= strlen(setpoint))
00537                                 return (EPERM);
00538                 }
00539                 break;
00540 
00541         case ZFS_PROP_MLSLABEL:
00542 #ifdef SECLABEL
00543                 if (!is_system_labeled())
00544                         return (EPERM);
00545 
00546                 if (nvpair_value_string(propval, &strval) == 0) {
00547                         int err;
00548 
00549                         err = zfs_set_slabel_policy(dsname, strval, CRED());
00550                         if (err != 0)
00551                                 return (err);
00552                 }
00553 #else
00554                 return (EOPNOTSUPP);
00555 #endif
00556                 break;
00557         }
00558 
00559         return (zfs_secpolicy_write_perms(dsname, zfs_prop_to_name(prop), cr));
00560 }
00561 
00562 int
00563 zfs_secpolicy_fsacl(zfs_cmd_t *zc, cred_t *cr)
00564 {
00565         int error;
00566 
00567         error = zfs_dozonecheck(zc->zc_name, cr);
00568         if (error)
00569                 return (error);
00570 
00571         /*
00572          * permission to set permissions will be evaluated later in
00573          * dsl_deleg_can_allow()
00574          */
00575         return (0);
00576 }
00577 
00578 int
00579 zfs_secpolicy_rollback(zfs_cmd_t *zc, cred_t *cr)
00580 {
00581         return (zfs_secpolicy_write_perms(zc->zc_name,
00582             ZFS_DELEG_PERM_ROLLBACK, cr));
00583 }
00584 
00585 int
00586 zfs_secpolicy_send(zfs_cmd_t *zc, cred_t *cr)
00587 {
00588         spa_t *spa;
00589         dsl_pool_t *dp;
00590         dsl_dataset_t *ds;
00591         char *cp;
00592         int error;
00593 
00594         /*
00595          * Generate the current snapshot name from the given objsetid, then
00596          * use that name for the secpolicy/zone checks.
00597          */
00598         cp = strchr(zc->zc_name, '@');
00599         if (cp == NULL)
00600                 return (EINVAL);
00601         error = spa_open(zc->zc_name, &spa, FTAG);
00602         if (error)
00603                 return (error);
00604 
00605         dp = spa_get_dsl(spa);
00606         rw_enter(&dp->dp_config_rwlock, RW_READER);
00607         error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
00608         rw_exit(&dp->dp_config_rwlock);
00609         spa_close(spa, FTAG);
00610         if (error)
00611                 return (error);
00612 
00613         dsl_dataset_name(ds, zc->zc_name);
00614 
00615         error = zfs_secpolicy_write_perms_ds(zc->zc_name, ds,
00616             ZFS_DELEG_PERM_SEND, cr);
00617         dsl_dataset_rele(ds, FTAG);
00618 
00619         return (error);
00620 }
00621 
00622 static int
00623 zfs_secpolicy_deleg_share(zfs_cmd_t *zc, cred_t *cr)
00624 {
00625         vnode_t *vp;
00626         int error;
00627 
00628         if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
00629             NO_FOLLOW, NULL, &vp)) != 0)
00630                 return (error);
00631 
00632         /* Now make sure mntpnt and dataset are ZFS */
00633 
00634         if (strcmp(vp->v_vfsp->mnt_stat.f_fstypename, "zfs") != 0 ||
00635             (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
00636             zc->zc_name) != 0)) {
00637                 VN_RELE(vp);
00638                 return (EPERM);
00639         }
00640 
00641         VN_RELE(vp);
00642         return (dsl_deleg_access(zc->zc_name,
00643             ZFS_DELEG_PERM_SHARE, cr));
00644 }
00645 
00646 int
00647 zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr)
00648 {
00649         if (!INGLOBALZONE(curthread))
00650                 return (EPERM);
00651 
00652         if (secpolicy_nfs(cr) == 0) {
00653                 return (0);
00654         } else {
00655                 return (zfs_secpolicy_deleg_share(zc, cr));
00656         }
00657 }
00658 
00659 int
00660 zfs_secpolicy_smb_acl(zfs_cmd_t *zc, cred_t *cr)
00661 {
00662         if (!INGLOBALZONE(curthread))
00663                 return (EPERM);
00664 
00665         if (secpolicy_smb(cr) == 0) {
00666                 return (0);
00667         } else {
00668                 return (zfs_secpolicy_deleg_share(zc, cr));
00669         }
00670 }
00671 
00672 static int
00673 zfs_get_parent(const char *datasetname, char *parent, int parentsize)
00674 {
00675         char *cp;
00676 
00677         /*
00678          * Remove the @bla or /bla from the end of the name to get the parent.
00679          */
00680         (void) strncpy(parent, datasetname, parentsize);
00681         cp = strrchr(parent, '@');
00682         if (cp != NULL) {
00683                 cp[0] = '\0';
00684         } else {
00685                 cp = strrchr(parent, '/');
00686                 if (cp == NULL)
00687                         return (ENOENT);
00688                 cp[0] = '\0';
00689         }
00690 
00691         return (0);
00692 }
00693 
00694 int
00695 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
00696 {
00697         int error;
00698 
00699         if ((error = zfs_secpolicy_write_perms(name,
00700             ZFS_DELEG_PERM_MOUNT, cr)) != 0)
00701                 return (error);
00702 
00703         return (zfs_secpolicy_write_perms(name, ZFS_DELEG_PERM_DESTROY, cr));
00704 }
00705 
00706 static int
00707 zfs_secpolicy_destroy(zfs_cmd_t *zc, cred_t *cr)
00708 {
00709         return (zfs_secpolicy_destroy_perms(zc->zc_name, cr));
00710 }
00711 
00716 static int
00717 zfs_secpolicy_destroy_recursive(zfs_cmd_t *zc, cred_t *cr)
00718 {
00719         int error;
00720         char *dsname;
00721 
00722         dsname = kmem_asprintf("%s@", zc->zc_name);
00723 
00724         error = zfs_secpolicy_destroy_perms(dsname, cr);
00725 
00726         if (error == ENOENT)
00727                 error = zfs_secpolicy_destroy_perms(zc->zc_name, cr);
00728 
00729         strfree(dsname);
00730         return (error);
00731 }
00732 
00733 int
00734 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
00735 {
00736         char    parentname[MAXNAMELEN];
00737         int     error;
00738 
00739         if ((error = zfs_secpolicy_write_perms(from,
00740             ZFS_DELEG_PERM_RENAME, cr)) != 0)
00741                 return (error);
00742 
00743         if ((error = zfs_secpolicy_write_perms(from,
00744             ZFS_DELEG_PERM_MOUNT, cr)) != 0)
00745                 return (error);
00746 
00747         if ((error = zfs_get_parent(to, parentname,
00748             sizeof (parentname))) != 0)
00749                 return (error);
00750 
00751         if ((error = zfs_secpolicy_write_perms(parentname,
00752             ZFS_DELEG_PERM_CREATE, cr)) != 0)
00753                 return (error);
00754 
00755         if ((error = zfs_secpolicy_write_perms(parentname,
00756             ZFS_DELEG_PERM_MOUNT, cr)) != 0)
00757                 return (error);
00758 
00759         return (error);
00760 }
00761 
00762 static int
00763 zfs_secpolicy_rename(zfs_cmd_t *zc, cred_t *cr)
00764 {
00765         char *at = NULL;
00766         int error;
00767 
00768         if ((zc->zc_cookie & 1) != 0) {
00769                 /*
00770                  * This is recursive rename, so the starting snapshot might
00771                  * not exist. Check file system or volume permission instead.
00772                  */
00773                 at = strchr(zc->zc_name, '@');
00774                 if (at == NULL)
00775                         return (EINVAL);
00776                 *at = '\0';
00777         }
00778 
00779         error = zfs_secpolicy_rename_perms(zc->zc_name, zc->zc_value, cr);
00780 
00781         if (at != NULL)
00782                 *at = '@';
00783 
00784         return (error);
00785 }
00786 
00787 static int
00788 zfs_secpolicy_promote(zfs_cmd_t *zc, cred_t *cr)
00789 {
00790         char    parentname[MAXNAMELEN];
00791         objset_t *clone;
00792         int error;
00793 
00794         error = zfs_secpolicy_write_perms(zc->zc_name,
00795             ZFS_DELEG_PERM_PROMOTE, cr);
00796         if (error)
00797                 return (error);
00798 
00799         error = dmu_objset_hold(zc->zc_name, FTAG, &clone);
00800 
00801         if (error == 0) {
00802                 dsl_dataset_t *pclone = NULL;
00803                 dsl_dir_t *dd;
00804                 dd = clone->os_dsl_dataset->ds_dir;
00805 
00806                 rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER);
00807                 error = dsl_dataset_hold_obj(dd->dd_pool,
00808                     dd->dd_phys->dd_origin_obj, FTAG, &pclone);
00809                 rw_exit(&dd->dd_pool->dp_config_rwlock);
00810                 if (error) {
00811                         dmu_objset_rele(clone, FTAG);
00812                         return (error);
00813                 }
00814 
00815                 error = zfs_secpolicy_write_perms(zc->zc_name,
00816                     ZFS_DELEG_PERM_MOUNT, cr);
00817 
00818                 dsl_dataset_name(pclone, parentname);
00819                 dmu_objset_rele(clone, FTAG);
00820                 dsl_dataset_rele(pclone, FTAG);
00821                 if (error == 0)
00822                         error = zfs_secpolicy_write_perms(parentname,
00823                             ZFS_DELEG_PERM_PROMOTE, cr);
00824         }
00825         return (error);
00826 }
00827 
00828 static int
00829 zfs_secpolicy_receive(zfs_cmd_t *zc, cred_t *cr)
00830 {
00831         int error;
00832 
00833         if ((error = zfs_secpolicy_write_perms(zc->zc_name,
00834             ZFS_DELEG_PERM_RECEIVE, cr)) != 0)
00835                 return (error);
00836 
00837         if ((error = zfs_secpolicy_write_perms(zc->zc_name,
00838             ZFS_DELEG_PERM_MOUNT, cr)) != 0)
00839                 return (error);
00840 
00841         return (zfs_secpolicy_write_perms(zc->zc_name,
00842             ZFS_DELEG_PERM_CREATE, cr));
00843 }
00844 
00845 int
00846 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
00847 {
00848         return (zfs_secpolicy_write_perms(name,
00849             ZFS_DELEG_PERM_SNAPSHOT, cr));
00850 }
00851 
00852 static int
00853 zfs_secpolicy_snapshot(zfs_cmd_t *zc, cred_t *cr)
00854 {
00855 
00856         return (zfs_secpolicy_snapshot_perms(zc->zc_name, cr));
00857 }
00858 
00859 static int
00860 zfs_secpolicy_create(zfs_cmd_t *zc, cred_t *cr)
00861 {
00862         char    parentname[MAXNAMELEN];
00863         int     error;
00864 
00865         if ((error = zfs_get_parent(zc->zc_name, parentname,
00866             sizeof (parentname))) != 0)
00867                 return (error);
00868 
00869         if (zc->zc_value[0] != '\0') {
00870                 if ((error = zfs_secpolicy_write_perms(zc->zc_value,
00871                     ZFS_DELEG_PERM_CLONE, cr)) != 0)
00872                         return (error);
00873         }
00874 
00875         if ((error = zfs_secpolicy_write_perms(parentname,
00876             ZFS_DELEG_PERM_CREATE, cr)) != 0)
00877                 return (error);
00878 
00879         error = zfs_secpolicy_write_perms(parentname,
00880             ZFS_DELEG_PERM_MOUNT, cr);
00881 
00882         return (error);
00883 }
00884 
00885 static int
00886 zfs_secpolicy_umount(zfs_cmd_t *zc, cred_t *cr)
00887 {
00888         int error;
00889 
00890         error = secpolicy_fs_unmount(cr, NULL);
00891         if (error) {
00892                 error = dsl_deleg_access(zc->zc_name, ZFS_DELEG_PERM_MOUNT, cr);
00893         }
00894         return (error);
00895 }
00896 
00901 /* ARGSUSED */
00902 static int
00903 zfs_secpolicy_config(zfs_cmd_t *zc, cred_t *cr)
00904 {
00905         if (secpolicy_sys_config(cr, B_FALSE) != 0)
00906                 return (EPERM);
00907 
00908         return (0);
00909 }
00910 
00914 /* ARGSUSED */
00915 static int
00916 zfs_secpolicy_diff(zfs_cmd_t *zc, cred_t *cr)
00917 {
00918         int error;
00919 
00920         if ((error = secpolicy_sys_config(cr, B_FALSE)) == 0)
00921                 return (0);
00922 
00923         error = zfs_secpolicy_write_perms(zc->zc_name, ZFS_DELEG_PERM_DIFF, cr);
00924         return (error);
00925 }
00926 
00930 /* ARGSUSED */
00931 static int
00932 zfs_secpolicy_inject(zfs_cmd_t *zc, cred_t *cr)
00933 {
00934         return (secpolicy_zinject(cr));
00935 }
00936 
00937 static int
00938 zfs_secpolicy_inherit(zfs_cmd_t *zc, cred_t *cr)
00939 {
00940         zfs_prop_t prop = zfs_name_to_prop(zc->zc_value);
00941 
00942         if (prop == ZPROP_INVAL) {
00943                 if (!zfs_prop_user(zc->zc_value))
00944                         return (EINVAL);
00945                 return (zfs_secpolicy_write_perms(zc->zc_name,
00946                     ZFS_DELEG_PERM_USERPROP, cr));
00947         } else {
00948                 return (zfs_secpolicy_setprop(zc->zc_name, prop,
00949                     NULL, cr));
00950         }
00951 }
00952 
00953 static int
00954 zfs_secpolicy_userspace_one(zfs_cmd_t *zc, cred_t *cr)
00955 {
00956         int err = zfs_secpolicy_read(zc, cr);
00957         if (err)
00958                 return (err);
00959 
00960         if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
00961                 return (EINVAL);
00962 
00963         if (zc->zc_value[0] == 0) {
00964                 /*
00965                  * They are asking about a posix uid/gid.  If it's
00966                  * themself, allow it.
00967                  */
00968                 if (zc->zc_objset_type == ZFS_PROP_USERUSED ||
00969                     zc->zc_objset_type == ZFS_PROP_USERQUOTA) {
00970                         if (zc->zc_guid == crgetuid(cr))
00971                                 return (0);
00972                 } else {
00973                         if (groupmember(zc->zc_guid, cr))
00974                                 return (0);
00975                 }
00976         }
00977 
00978         return (zfs_secpolicy_write_perms(zc->zc_name,
00979             userquota_perms[zc->zc_objset_type], cr));
00980 }
00981 
00982 static int
00983 zfs_secpolicy_userspace_many(zfs_cmd_t *zc, cred_t *cr)
00984 {
00985         int err = zfs_secpolicy_read(zc, cr);
00986         if (err)
00987                 return (err);
00988 
00989         if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
00990                 return (EINVAL);
00991 
00992         return (zfs_secpolicy_write_perms(zc->zc_name,
00993             userquota_perms[zc->zc_objset_type], cr));
00994 }
00995 
00996 static int
00997 zfs_secpolicy_userspace_upgrade(zfs_cmd_t *zc, cred_t *cr)
00998 {
00999         return (zfs_secpolicy_setprop(zc->zc_name, ZFS_PROP_VERSION,
01000             NULL, cr));
01001 }
01002 
01003 static int
01004 zfs_secpolicy_hold(zfs_cmd_t *zc, cred_t *cr)
01005 {
01006         return (zfs_secpolicy_write_perms(zc->zc_name,
01007             ZFS_DELEG_PERM_HOLD, cr));
01008 }
01009 
01010 static int
01011 zfs_secpolicy_release(zfs_cmd_t *zc, cred_t *cr)
01012 {
01013         return (zfs_secpolicy_write_perms(zc->zc_name,
01014             ZFS_DELEG_PERM_RELEASE, cr));
01015 }
01016 
01020 static int
01021 zfs_secpolicy_tmp_snapshot(zfs_cmd_t *zc, cred_t *cr)
01022 {
01023         /*
01024          * A temporary snapshot is the same as a snapshot,
01025          * hold, destroy and release all rolled into one.
01026          * Delegated diff alone is sufficient that we allow this.
01027          */
01028         int error;
01029 
01030         if ((error = zfs_secpolicy_write_perms(zc->zc_name,
01031             ZFS_DELEG_PERM_DIFF, cr)) == 0)
01032                 return (0);
01033 
01034         error = zfs_secpolicy_snapshot(zc, cr);
01035         if (!error)
01036                 error = zfs_secpolicy_hold(zc, cr);
01037         if (!error)
01038                 error = zfs_secpolicy_release(zc, cr);
01039         if (!error)
01040                 error = zfs_secpolicy_destroy(zc, cr);
01041         return (error);
01042 }
01043 
01047 static int
01048 get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp)
01049 {
01050         char *packed;
01051         int error;
01052         nvlist_t *list = NULL;
01053 
01054         /*
01055          * Read in and unpack the user-supplied nvlist.
01056          */
01057         if (size == 0)
01058                 return (EINVAL);
01059 
01060         packed = kmem_alloc(size, KM_SLEEP);
01061 
01062         if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
01063             iflag)) != 0) {
01064                 kmem_free(packed, size);
01065                 return (error);
01066         }
01067 
01068         if ((error = nvlist_unpack(packed, size, &list, 0)) != 0) {
01069                 kmem_free(packed, size);
01070                 return (error);
01071         }
01072 
01073         kmem_free(packed, size);
01074 
01075         *nvp = list;
01076         return (0);
01077 }
01078 
01079 static int
01080 fit_error_list(zfs_cmd_t *zc, nvlist_t **errors)
01081 {
01082         size_t size;
01083 
01084         VERIFY(nvlist_size(*errors, &size, NV_ENCODE_NATIVE) == 0);
01085 
01086         if (size > zc->zc_nvlist_dst_size) {
01087                 nvpair_t *more_errors;
01088                 int n = 0;
01089 
01090                 if (zc->zc_nvlist_dst_size < 1024)
01091                         return (ENOMEM);
01092 
01093                 VERIFY(nvlist_add_int32(*errors, ZPROP_N_MORE_ERRORS, 0) == 0);
01094                 more_errors = nvlist_prev_nvpair(*errors, NULL);
01095 
01096                 do {
01097                         nvpair_t *pair = nvlist_prev_nvpair(*errors,
01098                             more_errors);
01099                         VERIFY(nvlist_remove_nvpair(*errors, pair) == 0);
01100                         n++;
01101                         VERIFY(nvlist_size(*errors, &size,
01102                             NV_ENCODE_NATIVE) == 0);
01103                 } while (size > zc->zc_nvlist_dst_size);
01104 
01105                 VERIFY(nvlist_remove_nvpair(*errors, more_errors) == 0);
01106                 VERIFY(nvlist_add_int32(*errors, ZPROP_N_MORE_ERRORS, n) == 0);
01107                 ASSERT(nvlist_size(*errors, &size, NV_ENCODE_NATIVE) == 0);
01108                 ASSERT(size <= zc->zc_nvlist_dst_size);
01109         }
01110 
01111         return (0);
01112 }
01113 
01114 static int
01115 put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
01116 {
01117         char *packed = NULL;
01118         int error = 0;
01119         size_t size;
01120 
01121         VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0);
01122 
01123         if (size > zc->zc_nvlist_dst_size) {
01124                 /*
01125                  * Solaris returns ENOMEM here, because even if an error is
01126                  * returned from an ioctl(2), new zc_nvlist_dst_size will be
01127                  * passed to the userland. This is not the case for FreeBSD.
01128                  * We need to return 0, so the kernel will copy the
01129                  * zc_nvlist_dst_size back and the userland can discover that a
01130                  * bigger buffer is needed.
01131                  */
01132                 error = 0;
01133         } else {
01134                 packed = kmem_alloc(size, KM_SLEEP);
01135                 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
01136                     KM_SLEEP) == 0);
01137                 if (ddi_copyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst,
01138                     size, zc->zc_iflags) != 0)
01139                         error = EFAULT;
01140                 kmem_free(packed, size);
01141         }
01142 
01143         zc->zc_nvlist_dst_size = size;
01144         return (error);
01145 }
01146 
01147 static int
01148 getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
01149 {
01150         objset_t *os;
01151         int error;
01152 
01153         error = dmu_objset_hold(dsname, FTAG, &os);
01154         if (error)
01155                 return (error);
01156         if (dmu_objset_type(os) != DMU_OST_ZFS) {
01157                 dmu_objset_rele(os, FTAG);
01158                 return (EINVAL);
01159         }
01160 
01161         mutex_enter(&os->os_user_ptr_lock);
01162         *zfvp = dmu_objset_get_user(os);
01163         if (*zfvp) {
01164                 VFS_HOLD((*zfvp)->z_vfs);
01165         } else {
01166                 error = ESRCH;
01167         }
01168         mutex_exit(&os->os_user_ptr_lock);
01169         dmu_objset_rele(os, FTAG);
01170         return (error);
01171 }
01172 
01179 static int
01180 zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer)
01181 {
01182         int error = 0;
01183 
01184         if (getzfsvfs(name, zfvp) != 0)
01185                 error = zfsvfs_create(name, zfvp);
01186         if (error == 0) {
01187                 rrw_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER :
01188                     RW_READER, tag);
01189                 if ((*zfvp)->z_unmounted) {
01190                         /*
01191                          * XXX we could probably try again, since the unmounting
01192                          * thread should be just about to disassociate the
01193                          * objset from the zfsvfs.
01194                          */
01195                         rrw_exit(&(*zfvp)->z_teardown_lock, tag);
01196                         return (EBUSY);
01197                 }
01198         }
01199         return (error);
01200 }
01201 
01202 static void
01203 zfsvfs_rele(zfsvfs_t *zfsvfs, void *tag)
01204 {
01205         rrw_exit(&zfsvfs->z_teardown_lock, tag);
01206 
01207         if (zfsvfs->z_vfs) {
01208                 VFS_RELE(zfsvfs->z_vfs);
01209         } else {
01210                 dmu_objset_disown(zfsvfs->z_os, zfsvfs);
01211                 zfsvfs_free(zfsvfs);
01212         }
01213 }
01214 
01215 static int
01216 zfs_ioc_pool_create(zfs_cmd_t *zc)
01217 {
01218         int error;
01219         nvlist_t *config, *props = NULL;
01220         nvlist_t *rootprops = NULL;
01221         nvlist_t *zplprops = NULL;
01222         char *buf;
01223 
01224         if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
01225             zc->zc_iflags, &config))
01226                 return (error);
01227 
01228         if (zc->zc_nvlist_src_size != 0 && (error =
01229             get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
01230             zc->zc_iflags, &props))) {
01231                 nvlist_free(config);
01232                 return (error);
01233         }
01234 
01235         if (props) {
01236                 nvlist_t *nvl = NULL;
01237                 uint64_t version = SPA_VERSION;
01238 
01239                 (void) nvlist_lookup_uint64(props,
01240                     zpool_prop_to_name(ZPOOL_PROP_VERSION), &version);
01241                 if (!SPA_VERSION_IS_SUPPORTED(version)) {
01242                         error = EINVAL;
01243                         goto pool_props_bad;
01244                 }
01245                 (void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl);
01246                 if (nvl) {
01247                         error = nvlist_dup(nvl, &rootprops, KM_SLEEP);
01248                         if (error != 0) {
01249                                 nvlist_free(config);
01250                                 nvlist_free(props);
01251                                 return (error);
01252                         }
01253                         (void) nvlist_remove_all(props, ZPOOL_ROOTFS_PROPS);
01254                 }
01255                 VERIFY(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
01256                 error = zfs_fill_zplprops_root(version, rootprops,
01257                     zplprops, NULL);
01258                 if (error)
01259                         goto pool_props_bad;
01260         }
01261 
01262         buf = history_str_get(zc);
01263 
01264         error = spa_create(zc->zc_name, config, props, buf, zplprops);
01265 
01266         /*
01267          * Set the remaining root properties
01268          */
01269         if (!error && (error = zfs_set_prop_nvlist(zc->zc_name,
01270             ZPROP_SRC_LOCAL, rootprops, NULL)) != 0)
01271                 (void) spa_destroy(zc->zc_name);
01272 
01273         if (buf != NULL)
01274                 history_str_free(buf);
01275 
01276 pool_props_bad:
01277         nvlist_free(rootprops);
01278         nvlist_free(zplprops);
01279         nvlist_free(config);
01280         nvlist_free(props);
01281 
01282         return (error);
01283 }
01284 
01285 static int
01286 zfs_ioc_pool_destroy(zfs_cmd_t *zc)
01287 {
01288         int error;
01289         zfs_log_history(zc);
01290         error = spa_destroy(zc->zc_name);
01291         if (error == 0)
01292                 zvol_remove_minors(zc->zc_name);
01293         return (error);
01294 }
01295 
01296 static int
01297 zfs_ioc_pool_import(zfs_cmd_t *zc)
01298 {
01299         nvlist_t *config, *props = NULL;
01300         uint64_t guid;
01301         int error;
01302 
01303         if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
01304             zc->zc_iflags, &config)) != 0)
01305                 return (error);
01306 
01307         if (zc->zc_nvlist_src_size != 0 && (error =
01308             get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
01309             zc->zc_iflags, &props))) {
01310                 nvlist_free(config);
01311                 return (error);
01312         }
01313 
01314         if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
01315             guid != zc->zc_guid)
01316                 error = EINVAL;
01317         else
01318                 error = spa_import(zc->zc_name, config, props, zc->zc_cookie);
01319 
01320         if (zc->zc_nvlist_dst != 0) {
01321                 int err;
01322 
01323                 if ((err = put_nvlist(zc, config)) != 0)
01324                         error = err;
01325         }
01326 
01327         nvlist_free(config);
01328 
01329         if (props)
01330                 nvlist_free(props);
01331 
01332         return (error);
01333 }
01334 
01335 static int
01336 zfs_ioc_pool_export(zfs_cmd_t *zc)
01337 {
01338         int error;
01339         boolean_t force = (boolean_t)zc->zc_cookie;
01340         boolean_t hardforce = (boolean_t)zc->zc_guid;
01341 
01342         zfs_log_history(zc);
01343         error = spa_export(zc->zc_name, NULL, force, hardforce);
01344         if (error == 0)
01345                 zvol_remove_minors(zc->zc_name);
01346         return (error);
01347 }
01348 
01349 static int
01350 zfs_ioc_pool_configs(zfs_cmd_t *zc)
01351 {
01352         nvlist_t *configs;
01353         int error;
01354 
01355         if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
01356                 return (EEXIST);
01357 
01358         error = put_nvlist(zc, configs);
01359 
01360         nvlist_free(configs);
01361 
01362         return (error);
01363 }
01364 
01365 /*
01366  * \param[in]   zc_name             name of the pool
01367  * \param[out]  zc_cookie           real errno
01368  * \param[out]  zc_nvlist_dst       config nvlist
01369  * \param[out]  zc_nvlist_dst_size  size of config nvlist
01370  */
01371 static int
01372 zfs_ioc_pool_stats(zfs_cmd_t *zc)
01373 {
01374         nvlist_t *config;
01375         int error;
01376         int ret = 0;
01377 
01378         error = spa_get_stats(zc->zc_name, &config, zc->zc_value,
01379             sizeof (zc->zc_value));
01380 
01381         if (config != NULL) {
01382                 ret = put_nvlist(zc, config);
01383                 nvlist_free(config);
01384 
01385                 /*
01386                  * The config may be present even if 'error' is non-zero.
01387                  * In this case we return success, and preserve the real errno
01388                  * in 'zc_cookie'.
01389                  */
01390                 zc->zc_cookie = error;
01391         } else {
01392                 ret = error;
01393         }
01394 
01395         return (ret);
01396 }
01397 
01402 static int
01403 zfs_ioc_pool_tryimport(zfs_cmd_t *zc)
01404 {
01405         nvlist_t *tryconfig, *config;
01406         int error;
01407 
01408         if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
01409             zc->zc_iflags, &tryconfig)) != 0)
01410                 return (error);
01411 
01412         config = spa_tryimport(tryconfig);
01413 
01414         nvlist_free(tryconfig);
01415 
01416         if (config == NULL)
01417                 return (EINVAL);
01418 
01419         error = put_nvlist(zc, config);
01420         nvlist_free(config);
01421 
01422         return (error);
01423 }
01424 
01430 static int
01431 zfs_ioc_pool_scan(zfs_cmd_t *zc)
01432 {
01433         spa_t *spa;
01434         int error;
01435 
01436         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
01437                 return (error);
01438 
01439         if (zc->zc_cookie == POOL_SCAN_NONE)
01440                 error = spa_scan_stop(spa);
01441         else
01442                 error = spa_scan(spa, zc->zc_cookie);
01443 
01444         spa_close(spa, FTAG);
01445 
01446         return (error);
01447 }
01448 
01449 static int
01450 zfs_ioc_pool_freeze(zfs_cmd_t *zc)
01451 {
01452         spa_t *spa;
01453         int error;
01454 
01455         error = spa_open(zc->zc_name, &spa, FTAG);
01456         if (error == 0) {
01457                 spa_freeze(spa);
01458                 spa_close(spa, FTAG);
01459         }
01460         return (error);
01461 }
01462 
01463 static int
01464 zfs_ioc_pool_upgrade(zfs_cmd_t *zc)
01465 {
01466         spa_t *spa;
01467         int error;
01468 
01469         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
01470                 return (error);
01471 
01472         if (zc->zc_cookie < spa_version(spa) ||
01473             !SPA_VERSION_IS_SUPPORTED(zc->zc_cookie)) {
01474                 spa_close(spa, FTAG);
01475                 return (EINVAL);
01476         }
01477 
01478         spa_upgrade(spa, zc->zc_cookie);
01479         spa_close(spa, FTAG);
01480 
01481         return (error);
01482 }
01483 
01484 static int
01485 zfs_ioc_pool_get_history(zfs_cmd_t *zc)
01486 {
01487         spa_t *spa;
01488         char *hist_buf;
01489         uint64_t size;
01490         int error;
01491 
01492         if ((size = zc->zc_history_len) == 0)
01493                 return (EINVAL);
01494 
01495         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
01496                 return (error);
01497 
01498         if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
01499                 spa_close(spa, FTAG);
01500                 return (ENOTSUP);
01501         }
01502 
01503         hist_buf = kmem_alloc(size, KM_SLEEP);
01504         if ((error = spa_history_get(spa, &zc->zc_history_offset,
01505             &zc->zc_history_len, hist_buf)) == 0) {
01506                 error = ddi_copyout(hist_buf,
01507                     (void *)(uintptr_t)zc->zc_history,
01508                     zc->zc_history_len, zc->zc_iflags);
01509         }
01510 
01511         spa_close(spa, FTAG);
01512         kmem_free(hist_buf, size);
01513         return (error);
01514 }
01515 
01516 static int
01517 zfs_ioc_pool_reguid(zfs_cmd_t *zc)
01518 {
01519         spa_t *spa;
01520         int error;
01521 
01522         error = spa_open(zc->zc_name, &spa, FTAG);
01523         if (error == 0) {
01524                 error = spa_change_guid(spa);
01525                 spa_close(spa, FTAG);
01526         }
01527         return (error);
01528 }
01529 
01530 static int
01531 zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc)
01532 {
01533         int error;
01534 
01535         if (error = dsl_dsobj_to_dsname(zc->zc_name, zc->zc_obj, zc->zc_value))
01536                 return (error);
01537 
01538         return (0);
01539 }
01540 
01549 static int
01550 zfs_ioc_obj_to_path(zfs_cmd_t *zc)
01551 {
01552         objset_t *os;
01553         int error;
01554 
01555         /* XXX reading from objset not owned */
01556         if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
01557                 return (error);
01558         if (dmu_objset_type(os) != DMU_OST_ZFS) {
01559                 dmu_objset_rele(os, FTAG);
01560                 return (EINVAL);
01561         }
01562         error = zfs_obj_to_path(os, zc->zc_obj, zc->zc_value,
01563             sizeof (zc->zc_value));
01564         dmu_objset_rele(os, FTAG);
01565 
01566         return (error);
01567 }
01568 
01578 static int
01579 zfs_ioc_obj_to_stats(zfs_cmd_t *zc)
01580 {
01581         objset_t *os;
01582         int error;
01583 
01584         /* XXX reading from objset not owned */
01585         if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
01586                 return (error);
01587         if (dmu_objset_type(os) != DMU_OST_ZFS) {
01588                 dmu_objset_rele(os, FTAG);
01589                 return (EINVAL);
01590         }
01591         error = zfs_obj_to_stats(os, zc->zc_obj, &zc->zc_stat, zc->zc_value,
01592             sizeof (zc->zc_value));
01593         dmu_objset_rele(os, FTAG);
01594 
01595         return (error);
01596 }
01597 
01598 static int
01599 zfs_ioc_vdev_add(zfs_cmd_t *zc)
01600 {
01601         spa_t *spa;
01602         int error;
01603         nvlist_t *config, **l2cache, **spares;
01604         uint_t nl2cache = 0, nspares = 0;
01605 
01606         error = spa_open(zc->zc_name, &spa, FTAG);
01607         if (error != 0)
01608                 return (error);
01609 
01610         error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
01611             zc->zc_iflags, &config);
01612         (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_L2CACHE,
01613             &l2cache, &nl2cache);
01614 
01615         (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_SPARES,
01616             &spares, &nspares);
01617 
01618         /*
01619          * A root pool with concatenated devices is not supported.
01620          * Thus, can not add a device to a root pool.
01621          *
01622          * Intent log device can not be added to a rootpool because
01623          * during mountroot, zil is replayed, a seperated log device
01624          * can not be accessed during the mountroot time.
01625          *
01626          * l2cache and spare devices are ok to be added to a rootpool.
01627          */
01628         if (spa_bootfs(spa) != 0 && nl2cache == 0 && nspares == 0) {
01629                 nvlist_free(config);
01630                 spa_close(spa, FTAG);
01631                 return (EDOM);
01632         }
01633 
01634         if (error == 0) {
01635                 error = spa_vdev_add(spa, config);
01636                 nvlist_free(config);
01637         }
01638         spa_close(spa, FTAG);
01639         return (error);
01640 }
01641 
01648 static int
01649 zfs_ioc_vdev_remove(zfs_cmd_t *zc)
01650 {
01651         spa_t *spa;
01652         int error;
01653 
01654         error = spa_open(zc->zc_name, &spa, FTAG);
01655         if (error != 0)
01656                 return (error);
01657         error = spa_vdev_remove(spa, zc->zc_guid, B_FALSE);
01658         spa_close(spa, FTAG);
01659         return (error);
01660 }
01661 
01662 static int
01663 zfs_ioc_vdev_set_state(zfs_cmd_t *zc)
01664 {
01665         spa_t *spa;
01666         int error;
01667         vdev_state_t newstate = VDEV_STATE_UNKNOWN;
01668 
01669         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
01670                 return (error);
01671         switch (zc->zc_cookie) {
01672         case VDEV_STATE_ONLINE:
01673                 error = vdev_online(spa, zc->zc_guid, zc->zc_obj, &newstate);
01674                 break;
01675 
01676         case VDEV_STATE_OFFLINE:
01677                 error = vdev_offline(spa, zc->zc_guid, zc->zc_obj);
01678                 break;
01679 
01680         case VDEV_STATE_FAULTED:
01681                 if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
01682                     zc->zc_obj != VDEV_AUX_EXTERNAL)
01683                         zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
01684 
01685                 error = vdev_fault(spa, zc->zc_guid, zc->zc_obj);
01686                 break;
01687 
01688         case VDEV_STATE_DEGRADED:
01689                 if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
01690                     zc->zc_obj != VDEV_AUX_EXTERNAL)
01691                         zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
01692 
01693                 error = vdev_degrade(spa, zc->zc_guid, zc->zc_obj);
01694                 break;
01695 
01696         default:
01697                 error = EINVAL;
01698         }
01699         zc->zc_cookie = newstate;
01700         spa_close(spa, FTAG);
01701         return (error);
01702 }
01703 
01704 static int
01705 zfs_ioc_vdev_attach(zfs_cmd_t *zc)
01706 {
01707         spa_t *spa;
01708         int replacing = zc->zc_cookie;
01709         nvlist_t *config;
01710         int error;
01711 
01712         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
01713                 return (error);
01714 
01715         if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
01716             zc->zc_iflags, &config)) == 0) {
01717                 error = spa_vdev_attach(spa, zc->zc_guid, config, replacing);
01718                 nvlist_free(config);
01719         }
01720 
01721         spa_close(spa, FTAG);
01722         return (error);
01723 }
01724 
01725 static int
01726 zfs_ioc_vdev_detach(zfs_cmd_t *zc)
01727 {
01728         spa_t *spa;
01729         int error;
01730 
01731         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
01732                 return (error);
01733 
01734         error = spa_vdev_detach(spa, zc->zc_guid, 0, B_FALSE);
01735 
01736         spa_close(spa, FTAG);
01737         return (error);
01738 }
01739 
01740 static int
01741 zfs_ioc_vdev_split(zfs_cmd_t *zc)
01742 {
01743         spa_t *spa;
01744         nvlist_t *config, *props = NULL;
01745         int error;
01746         boolean_t exp = !!(zc->zc_cookie & ZPOOL_EXPORT_AFTER_SPLIT);
01747 
01748         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
01749                 return (error);
01750 
01751         if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
01752             zc->zc_iflags, &config)) {
01753                 spa_close(spa, FTAG);
01754                 return (error);
01755         }
01756 
01757         if (zc->zc_nvlist_src_size != 0 && (error =
01758             get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
01759             zc->zc_iflags, &props))) {
01760                 spa_close(spa, FTAG);
01761                 nvlist_free(config);
01762                 return (error);
01763         }
01764 
01765         error = spa_vdev_split_mirror(spa, zc->zc_string, config, props, exp);
01766 
01767         spa_close(spa, FTAG);
01768 
01769         nvlist_free(config);
01770         nvlist_free(props);
01771 
01772         return (error);
01773 }
01774 
01775 static int
01776 zfs_ioc_vdev_setpath(zfs_cmd_t *zc)
01777 {
01778         spa_t *spa;
01779         char *path = zc->zc_value;
01780         uint64_t guid = zc->zc_guid;
01781         int error;
01782 
01783         error = spa_open(zc->zc_name, &spa, FTAG);
01784         if (error != 0)
01785                 return (error);
01786 
01787         error = spa_vdev_setpath(spa, guid, path);
01788         spa_close(spa, FTAG);
01789         return (error);
01790 }
01791 
01792 static int
01793 zfs_ioc_vdev_setfru(zfs_cmd_t *zc)
01794 {
01795         spa_t *spa;
01796         char *fru = zc->zc_value;
01797         uint64_t guid = zc->zc_guid;
01798         int error;
01799 
01800         error = spa_open(zc->zc_name, &spa, FTAG);
01801         if (error != 0)
01802                 return (error);
01803 
01804         error = spa_vdev_setfru(spa, guid, fru);
01805         spa_close(spa, FTAG);
01806         return (error);
01807 }
01808 
01809 static int
01810 zfs_ioc_objset_stats_impl(zfs_cmd_t *zc, objset_t *os)
01811 {
01812         int error = 0;
01813         nvlist_t *nv;
01814 
01815         dmu_objset_fast_stat(os, &zc->zc_objset_stats);
01816 
01817         if (zc->zc_nvlist_dst != 0 &&
01818             (error = dsl_prop_get_all(os, &nv)) == 0) {
01819                 dmu_objset_stats(os, nv);
01820                 /*
01821                  * NB: zvol_get_stats() will read the objset contents,
01822                  * which we aren't supposed to do with a
01823                  * DS_MODE_USER hold, because it could be
01824                  * inconsistent.  So this is a bit of a workaround...
01825                  * XXX reading with out owning
01826                  */
01827                 if (!zc->zc_objset_stats.dds_inconsistent &&
01828                     dmu_objset_type(os) == DMU_OST_ZVOL) {
01829                         error = zvol_get_stats(os, nv);
01830                         if (error == EIO)
01831                                 return (error);
01832                         VERIFY0(error);
01833                 }
01834                 error = put_nvlist(zc, nv);
01835                 nvlist_free(nv);
01836         }
01837 
01838         return (error);
01839 }
01840 
01851 static int
01852 zfs_ioc_objset_stats(zfs_cmd_t *zc)
01853 {
01854         objset_t *os = NULL;
01855         int error;
01856 
01857         if (error = dmu_objset_hold(zc->zc_name, FTAG, &os))
01858                 return (error);
01859 
01860         error = zfs_ioc_objset_stats_impl(zc, os);
01861 
01862         dmu_objset_rele(os, FTAG);
01863 
01864         if (error == ENOMEM)
01865                 error = 0;
01866         return (error);
01867 }
01868 
01883 static int
01884 zfs_ioc_objset_recvd_props(zfs_cmd_t *zc)
01885 {
01886         objset_t *os = NULL;
01887         int error;
01888         nvlist_t *nv;
01889 
01890         if (error = dmu_objset_hold(zc->zc_name, FTAG, &os))
01891                 return (error);
01892 
01893         /*
01894          * Without this check, we would return local property values if the
01895          * caller has not already received properties on or after
01896          * SPA_VERSION_RECVD_PROPS.
01897          */
01898         if (!dsl_prop_get_hasrecvd(os)) {
01899                 dmu_objset_rele(os, FTAG);
01900                 return (ENOTSUP);
01901         }
01902 
01903         if (zc->zc_nvlist_dst != 0 &&
01904             (error = dsl_prop_get_received(os, &nv)) == 0) {
01905                 error = put_nvlist(zc, nv);
01906                 nvlist_free(nv);
01907         }
01908 
01909         dmu_objset_rele(os, FTAG);
01910         return (error);
01911 }
01912 
01913 static int
01914 nvl_add_zplprop(objset_t *os, nvlist_t *props, zfs_prop_t prop)
01915 {
01916         uint64_t value;
01917         int error;
01918 
01919         /*
01920          * zfs_get_zplprop() will either find a value or give us
01921          * the default value (if there is one).
01922          */
01923         if ((error = zfs_get_zplprop(os, prop, &value)) != 0)
01924                 return (error);
01925         VERIFY(nvlist_add_uint64(props, zfs_prop_to_name(prop), value) == 0);
01926         return (0);
01927 }
01928 
01938 static int
01939 zfs_ioc_objset_zplprops(zfs_cmd_t *zc)
01940 {
01941         objset_t *os;
01942         int err;
01943 
01944         /* XXX reading without owning */
01945         if (err = dmu_objset_hold(zc->zc_name, FTAG, &os))
01946                 return (err);
01947 
01948         dmu_objset_fast_stat(os, &zc->zc_objset_stats);
01949 
01950         /*
01951          * NB: nvl_add_zplprop() will read the objset contents,
01952          * which we aren't supposed to do with a DS_MODE_USER
01953          * hold, because it could be inconsistent.
01954          */
01955         if (zc->zc_nvlist_dst != 0 &&
01956             !zc->zc_objset_stats.dds_inconsistent &&
01957             dmu_objset_type(os) == DMU_OST_ZFS) {
01958                 nvlist_t *nv;
01959 
01960                 VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
01961                 if ((err = nvl_add_zplprop(os, nv, ZFS_PROP_VERSION)) == 0 &&
01962                     (err = nvl_add_zplprop(os, nv, ZFS_PROP_NORMALIZE)) == 0 &&
01963                     (err = nvl_add_zplprop(os, nv, ZFS_PROP_UTF8ONLY)) == 0 &&
01964                     (err = nvl_add_zplprop(os, nv, ZFS_PROP_CASE)) == 0)
01965                         err = put_nvlist(zc, nv);
01966                 nvlist_free(nv);
01967         } else {
01968                 err = ENOENT;
01969         }
01970         dmu_objset_rele(os, FTAG);
01971         return (err);
01972 }
01973 
01974 boolean_t
01975 dataset_name_hidden(const char *name)
01976 {
01977         /*
01978          * Skip over datasets that are not visible in this zone,
01979          * internal datasets (which have a $ in their name), and
01980          * temporary datasets (which have a % in their name).
01981          */
01982         if (strchr(name, '$') != NULL)
01983                 return (B_TRUE);
01984         if (strchr(name, '%') != NULL)
01985                 return (B_TRUE);
01986         if (!INGLOBALZONE(curthread) && !zone_dataset_visible(name, NULL))
01987                 return (B_TRUE);
01988         return (B_FALSE);
01989 }
01990 
02004 static int
02005 zfs_ioc_dataset_list_next(zfs_cmd_t *zc)
02006 {
02007         objset_t *os;
02008         int error;
02009         char *p;
02010         size_t orig_len = strlen(zc->zc_name);
02011 
02012 top:
02013         if (error = dmu_objset_hold(zc->zc_name, FTAG, &os)) {
02014                 if (error == ENOENT)
02015                         error = ESRCH;
02016                 return (error);
02017         }
02018 
02019         p = strrchr(zc->zc_name, '/');
02020         if (p == NULL || p[1] != '\0')
02021                 (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name));
02022         p = zc->zc_name + strlen(zc->zc_name);
02023 
02024         /*
02025          * Pre-fetch the datasets.  dmu_objset_prefetch() always returns 0
02026          * but is not declared void because its called by dmu_objset_find().
02027          */
02028         if (zc->zc_cookie == 0) {
02029                 uint64_t cookie = 0;
02030                 int len = sizeof (zc->zc_name) - (p - zc->zc_name);
02031 
02032                 while (dmu_dir_list_next(os, len, p, NULL, &cookie) == 0) {
02033                         if (!dataset_name_hidden(zc->zc_name))
02034                                 (void) dmu_objset_prefetch(zc->zc_name, NULL);
02035                 }
02036         }
02037 
02038         do {
02039                 error = dmu_dir_list_next(os,
02040                     sizeof (zc->zc_name) - (p - zc->zc_name), p,
02041                     NULL, &zc->zc_cookie);
02042                 if (error == ENOENT)
02043                         error = ESRCH;
02044         } while (error == 0 && dataset_name_hidden(zc->zc_name));
02045         dmu_objset_rele(os, FTAG);
02046 
02047         /*
02048          * If it's an internal dataset (ie. with a '$' in its name),
02049          * don't try to get stats for it, otherwise we'll return ENOENT.
02050          */
02051         if (error == 0 && strchr(zc->zc_name, '$') == NULL) {
02052                 error = zfs_ioc_objset_stats(zc); /* fill in the stats */
02053                 if (error == ENOENT) {
02054                         /* We lost a race with destroy, get the next one. */
02055                         zc->zc_name[orig_len] = '\0';
02056                         goto top;
02057                 }
02058         }
02059         return (error);
02060 }
02061 
02075 static int
02076 zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
02077 {
02078         objset_t *os;
02079         int error;
02080 
02081 top:
02082         if (snapshot_list_prefetch && zc->zc_cookie == 0 && !zc->zc_simple)
02083                 (void) dmu_objset_find(zc->zc_name, dmu_objset_prefetch,
02084                     NULL, DS_FIND_SNAPSHOTS);
02085 
02086         error = dmu_objset_hold(zc->zc_name, FTAG, &os);
02087         if (error)
02088                 return (error == ENOENT ? ESRCH : error);
02089 
02090         /*
02091          * A dataset name of maximum length cannot have any snapshots,
02092          * so exit immediately.
02093          */
02094         if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) {
02095                 dmu_objset_rele(os, FTAG);
02096                 return (ESRCH);
02097         }
02098 
02099         error = dmu_snapshot_list_next(os,
02100             sizeof (zc->zc_name) - strlen(zc->zc_name),
02101             zc->zc_name + strlen(zc->zc_name), &zc->zc_obj, &zc->zc_cookie,
02102             NULL);
02103 
02104         if (error == 0 && !zc->zc_simple) {
02105                 dsl_dataset_t *ds;
02106                 dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool;
02107 
02108                 /*
02109                  * Since we probably don't have a hold on this snapshot,
02110                  * it's possible that the objsetid could have been destroyed
02111                  * and reused for a new objset. It's OK if this happens during
02112                  * a zfs send operation, since the new createtxg will be
02113                  * beyond the range we're interested in.
02114                  */
02115                 rw_enter(&dp->dp_config_rwlock, RW_READER);
02116                 error = dsl_dataset_hold_obj(dp, zc->zc_obj, FTAG, &ds);
02117                 rw_exit(&dp->dp_config_rwlock);
02118                 if (error) {
02119                         if (error == ENOENT) {
02120                                 /* Racing with destroy, get the next one. */
02121                                 *strchr(zc->zc_name, '@') = '\0';
02122                                 dmu_objset_rele(os, FTAG);
02123                                 goto top;
02124                         }
02125                 } else {
02126                         objset_t *ossnap;
02127 
02128                         error = dmu_objset_from_ds(ds, &ossnap);
02129                         if (error == 0)
02130                                 error = zfs_ioc_objset_stats_impl(zc, ossnap);
02131                         dsl_dataset_rele(ds, FTAG);
02132                 }
02133         } else if (error == ENOENT) {
02134                 error = ESRCH;
02135         }
02136 
02137         dmu_objset_rele(os, FTAG);
02138         /* if we failed, undo the @ that we tacked on to zc_name */
02139         if (error)
02140                 *strchr(zc->zc_name, '@') = '\0';
02141         return (error);
02142 }
02143 
02144 static int
02145 zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
02146 {
02147         const char *propname = nvpair_name(pair);
02148         uint64_t *valary;
02149         unsigned int vallen;
02150         const char *domain;
02151         char *dash;
02152         zfs_userquota_prop_t type;
02153         uint64_t rid;
02154         uint64_t quota;
02155         zfsvfs_t *zfsvfs;
02156         int err;
02157 
02158         if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
02159                 nvlist_t *attrs;
02160                 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
02161                 if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
02162                     &pair) != 0)
02163                         return (EINVAL);
02164         }
02165 
02166         /*
02167          * A correctly constructed propname is encoded as
02168          * userquota@<rid>-<domain>.
02169          */
02170         if ((dash = strchr(propname, '-')) == NULL ||
02171             nvpair_value_uint64_array(pair, &valary, &vallen) != 0 ||
02172             vallen != 3)
02173                 return (EINVAL);
02174 
02175         domain = dash + 1;
02176         type = valary[0];
02177         rid = valary[1];
02178         quota = valary[2];
02179 
02180         err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_FALSE);
02181         if (err == 0) {
02182                 err = zfs_set_userquota(zfsvfs, type, domain, rid, quota);
02183                 zfsvfs_rele(zfsvfs, FTAG);
02184         }
02185 
02186         return (err);
02187 }
02188 
02197 static int
02198 zfs_prop_set_special(const char *dsname, zprop_source_t source,
02199     nvpair_t *pair)
02200 {
02201         const char *propname = nvpair_name(pair);
02202         zfs_prop_t prop = zfs_name_to_prop(propname);
02203         uint64_t intval;
02204         int err;
02205 
02206         if (prop == ZPROP_INVAL) {
02207                 if (zfs_prop_userquota(propname))
02208                         return (zfs_prop_set_userquota(dsname, pair));
02209                 return (-1);
02210         }
02211 
02212         if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
02213                 nvlist_t *attrs;
02214                 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
02215                 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
02216                     &pair) == 0);
02217         }
02218 
02219         if (zfs_prop_get_type(prop) == PROP_TYPE_STRING)
02220                 return (-1);
02221 
02222         VERIFY(0 == nvpair_value_uint64(pair, &intval));
02223 
02224         switch (prop) {
02225         case ZFS_PROP_QUOTA:
02226                 err = dsl_dir_set_quota(dsname, source, intval);
02227                 break;
02228         case ZFS_PROP_REFQUOTA:
02229                 err = dsl_dataset_set_quota(dsname, source, intval);
02230                 break;
02231         case ZFS_PROP_RESERVATION:
02232                 err = dsl_dir_set_reservation(dsname, source, intval);
02233                 break;
02234         case ZFS_PROP_REFRESERVATION:
02235                 err = dsl_dataset_set_reservation(dsname, source, intval);
02236                 break;
02237         case ZFS_PROP_VOLSIZE:
02238                 err = zvol_set_volsize(dsname, ddi_driver_major(zfs_dip),
02239                     intval);
02240                 break;
02241         case ZFS_PROP_VERSION:
02242         {
02243                 zfsvfs_t *zfsvfs;
02244 
02245                 if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_TRUE)) != 0)
02246                         break;
02247 
02248                 err = zfs_set_version(zfsvfs, intval);
02249                 zfsvfs_rele(zfsvfs, FTAG);
02250 
02251                 if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
02252                         zfs_cmd_t *zc;
02253 
02254                         zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
02255                         (void) strcpy(zc->zc_name, dsname);
02256                         (void) zfs_ioc_userspace_upgrade(zc);
02257                         kmem_free(zc, sizeof (zfs_cmd_t));
02258                 }
02259                 break;
02260         }
02261 
02262         default:
02263                 err = -1;
02264         }
02265 
02266         return (err);
02267 }
02268 
02280 int
02281 zfs_set_prop_nvlist(const char *dsname, zprop_source_t source, nvlist_t *nvl,
02282     nvlist_t **errlist)
02283 {
02284         nvpair_t *pair;
02285         nvpair_t *propval;
02286         int rv = 0;
02287         uint64_t intval;
02288         char *strval;
02289         nvlist_t *genericnvl;
02290         nvlist_t *errors;
02291         nvlist_t *retrynvl;
02292 
02293         VERIFY(nvlist_alloc(&genericnvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
02294         VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
02295         VERIFY(nvlist_alloc(&retrynvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
02296 
02297 retry:
02298         pair = NULL;
02299         while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
02300                 const char *propname = nvpair_name(pair);
02301                 zfs_prop_t prop = zfs_name_to_prop(propname);
02302                 int err = 0;
02303 
02304                 /* decode the property value */
02305                 propval = pair;
02306                 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
02307                         nvlist_t *attrs;
02308                         VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
02309                         if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
02310                             &propval) != 0)
02311                                 err = EINVAL;
02312                 }
02313 
02314                 /* Validate value type */
02315                 if (err == 0 && prop == ZPROP_INVAL) {
02316                         if (zfs_prop_user(propname)) {
02317                                 if (nvpair_type(propval) != DATA_TYPE_STRING)
02318                                         err = EINVAL;
02319                         } else if (zfs_prop_userquota(propname)) {
02320                                 if (nvpair_type(propval) !=
02321                                     DATA_TYPE_UINT64_ARRAY)
02322                                         err = EINVAL;
02323                         } else {
02324                                 err = EINVAL;
02325                         }
02326                 } else if (err == 0) {
02327                         if (nvpair_type(propval) == DATA_TYPE_STRING) {
02328                                 if (zfs_prop_get_type(prop) != PROP_TYPE_STRING)
02329                                         err = EINVAL;
02330                         } else if (nvpair_type(propval) == DATA_TYPE_UINT64) {
02331                                 const char *unused;
02332 
02333                                 VERIFY(nvpair_value_uint64(propval,
02334                                     &intval) == 0);
02335 
02336                                 switch (zfs_prop_get_type(prop)) {
02337                                 case PROP_TYPE_NUMBER:
02338                                         break;
02339                                 case PROP_TYPE_STRING:
02340                                         err = EINVAL;
02341                                         break;
02342                                 case PROP_TYPE_INDEX:
02343                                         if (zfs_prop_index_to_string(prop,
02344                                             intval, &unused) != 0)
02345                                                 err = EINVAL;
02346                                         break;
02347                                 default:
02348                                         cmn_err(CE_PANIC,
02349                                             "unknown property type");
02350                                 }
02351                         } else {
02352                                 err = EINVAL;
02353                         }
02354                 }
02355 
02356                 /* Validate permissions */
02357                 if (err == 0)
02358                         err = zfs_check_settable(dsname, pair, CRED());
02359 
02360                 if (err == 0) {
02361                         err = zfs_prop_set_special(dsname, source, pair);
02362                         if (err == -1) {
02363                                 /*
02364                                  * For better performance we build up a list of
02365                                  * properties to set in a single transaction.
02366                                  */
02367                                 err = nvlist_add_nvpair(genericnvl, pair);
02368                         } else if (err != 0 && nvl != retrynvl) {
02369                                 /*
02370                                  * This may be a spurious error caused by
02371                                  * receiving quota and reservation out of order.
02372                                  * Try again in a second pass.
02373                                  */
02374                                 err = nvlist_add_nvpair(retrynvl, pair);
02375                         }
02376                 }
02377 
02378                 if (err != 0)
02379                         VERIFY(nvlist_add_int32(errors, propname, err) == 0);
02380         }
02381 
02382         if (nvl != retrynvl && !nvlist_empty(retrynvl)) {
02383                 nvl = retrynvl;
02384                 goto retry;
02385         }
02386 
02387         if (!nvlist_empty(genericnvl) &&
02388             dsl_props_set(dsname, source, genericnvl) != 0) {
02389                 /*
02390                  * If this fails, we still want to set as many properties as we
02391                  * can, so try setting them individually.
02392                  */
02393                 pair = NULL;
02394                 while ((pair = nvlist_next_nvpair(genericnvl, pair)) != NULL) {
02395                         const char *propname = nvpair_name(pair);
02396                         int err = 0;
02397 
02398                         propval = pair;
02399                         if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
02400                                 nvlist_t *attrs;
02401                                 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
02402                                 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
02403                                     &propval) == 0);
02404                         }
02405 
02406                         if (nvpair_type(propval) == DATA_TYPE_STRING) {
02407                                 VERIFY(nvpair_value_string(propval,
02408                                     &strval) == 0);
02409                                 err = dsl_prop_set(dsname, propname, source, 1,
02410                                     strlen(strval) + 1, strval);
02411                         } else {
02412                                 VERIFY(nvpair_value_uint64(propval,
02413                                     &intval) == 0);
02414                                 err = dsl_prop_set(dsname, propname, source, 8,
02415                                     1, &intval);
02416                         }
02417 
02418                         if (err != 0) {
02419                                 VERIFY(nvlist_add_int32(errors, propname,
02420                                     err) == 0);
02421                         }
02422                 }
02423         }
02424         nvlist_free(genericnvl);
02425         nvlist_free(retrynvl);
02426 
02427         if ((pair = nvlist_next_nvpair(errors, NULL)) == NULL) {
02428                 nvlist_free(errors);
02429                 errors = NULL;
02430         } else {
02431                 VERIFY(nvpair_value_int32(pair, &rv) == 0);
02432         }
02433 
02434         if (errlist == NULL)
02435                 nvlist_free(errors);
02436         else
02437                 *errlist = errors;
02438 
02439         return (rv);
02440 }
02441 
02445 static int
02446 zfs_check_userprops(char *fsname, nvlist_t *nvl)
02447 {
02448         nvpair_t *pair = NULL;
02449         int error = 0;
02450 
02451         while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
02452                 const char *propname = nvpair_name(pair);
02453                 char *valstr;
02454 
02455                 if (!zfs_prop_user(propname) ||
02456                     nvpair_type(pair) != DATA_TYPE_STRING)
02457                         return (EINVAL);
02458 
02459                 if (error = zfs_secpolicy_write_perms(fsname,
02460                     ZFS_DELEG_PERM_USERPROP, CRED()))
02461                         return (error);
02462 
02463                 if (strlen(propname) >= ZAP_MAXNAMELEN)
02464                         return (ENAMETOOLONG);
02465 
02466                 VERIFY(nvpair_value_string(pair, &valstr) == 0);
02467                 if (strlen(valstr) >= ZAP_MAXVALUELEN)
02468                         return (E2BIG);
02469         }
02470         return (0);
02471 }
02472 
02473 static void
02474 props_skip(nvlist_t *props, nvlist_t *skipped, nvlist_t **newprops)
02475 {
02476         nvpair_t *pair;
02477 
02478         VERIFY(nvlist_alloc(newprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
02479 
02480         pair = NULL;
02481         while ((pair = nvlist_next_nvpair(props, pair)) != NULL) {
02482                 if (nvlist_exists(skipped, nvpair_name(pair)))
02483                         continue;
02484 
02485                 VERIFY(nvlist_add_nvpair(*newprops, pair) == 0);
02486         }
02487 }
02488 
02489 static int
02490 clear_received_props(objset_t *os, const char *fs, nvlist_t *props,
02491     nvlist_t *skipped)
02492 {
02493         int err = 0;
02494         nvlist_t *cleared_props = NULL;
02495         props_skip(props, skipped, &cleared_props);
02496         if (!nvlist_empty(cleared_props)) {
02497                 /*
02498                  * Acts on local properties until the dataset has received
02499                  * properties at least once on or after SPA_VERSION_RECVD_PROPS.
02500                  */
02501                 zprop_source_t flags = (ZPROP_SRC_NONE |
02502                     (dsl_prop_get_hasrecvd(os) ? ZPROP_SRC_RECEIVED : 0));
02503                 err = zfs_set_prop_nvlist(fs, flags, cleared_props, NULL);
02504         }
02505         nvlist_free(cleared_props);
02506         return (err);
02507 }
02508 
02519 static int
02520 zfs_ioc_set_prop(zfs_cmd_t *zc)
02521 {
02522         nvlist_t *nvl;
02523         boolean_t received = zc->zc_cookie;
02524         zprop_source_t source = (received ? ZPROP_SRC_RECEIVED :
02525             ZPROP_SRC_LOCAL);
02526         nvlist_t *errors = NULL;
02527         int error;
02528 
02529         if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
02530             zc->zc_iflags, &nvl)) != 0)
02531                 return (error);
02532 
02533         if (received) {
02534                 nvlist_t *origprops;
02535                 objset_t *os;
02536 
02537                 if (dmu_objset_hold(zc->zc_name, FTAG, &os) == 0) {
02538                         if (dsl_prop_get_received(os, &origprops) == 0) {
02539                                 (void) clear_received_props(os,
02540                                     zc->zc_name, origprops, nvl);
02541                                 nvlist_free(origprops);
02542                         }
02543 
02544                         dsl_prop_set_hasrecvd(os);
02545                         dmu_objset_rele(os, FTAG);
02546                 }
02547         }
02548 
02549         error = zfs_set_prop_nvlist(zc->zc_name, source, nvl, &errors);
02550 
02551         if (zc->zc_nvlist_dst != 0 && errors != NULL) {
02552                 (void) put_nvlist(zc, errors);
02553         }
02554 
02555         nvlist_free(errors);
02556         nvlist_free(nvl);
02557         return (error);
02558 }
02559 
02568 static int
02569 zfs_ioc_inherit_prop(zfs_cmd_t *zc)
02570 {
02571         const char *propname = zc->zc_value;
02572         zfs_prop_t prop = zfs_name_to_prop(propname);
02573         boolean_t received = zc->zc_cookie;
02574         zprop_source_t source = (received
02575             ? ZPROP_SRC_NONE            /* revert to received value, if any */
02576             : ZPROP_SRC_INHERITED);     /* explicitly inherit */
02577 
02578         if (received) {
02579                 nvlist_t *dummy;
02580                 nvpair_t *pair;
02581                 zprop_type_t type;
02582                 int err;
02583 
02584                 /*
02585                  * zfs_prop_set_special() expects properties in the form of an
02586                  * nvpair with type info.
02587                  */
02588                 if (prop == ZPROP_INVAL) {
02589                         if (!zfs_prop_user(propname))
02590                                 return (EINVAL);
02591 
02592                         type = PROP_TYPE_STRING;
02593                 } else if (prop == ZFS_PROP_VOLSIZE ||
02594                     prop == ZFS_PROP_VERSION) {
02595                         return (EINVAL);
02596                 } else {
02597                         type = zfs_prop_get_type(prop);
02598                 }
02599 
02600                 VERIFY(nvlist_alloc(&dummy, NV_UNIQUE_NAME, KM_SLEEP) == 0);
02601 
02602                 switch (type) {
02603                 case PROP_TYPE_STRING:
02604                         VERIFY(0 == nvlist_add_string(dummy, propname, ""));
02605                         break;
02606                 case PROP_TYPE_NUMBER:
02607                 case PROP_TYPE_INDEX:
02608                         VERIFY(0 == nvlist_add_uint64(dummy, propname, 0));
02609                         break;
02610                 default:
02611                         nvlist_free(dummy);
02612                         return (EINVAL);
02613                 }
02614 
02615                 pair = nvlist_next_nvpair(dummy, NULL);
02616                 err = zfs_prop_set_special(zc->zc_name, source, pair);
02617                 nvlist_free(dummy);
02618                 if (err != -1)
02619                         return (err); /* special property already handled */
02620         } else {
02621                 /*
02622                  * Only check this in the non-received case. We want to allow
02623                  * 'inherit -S' to revert non-inheritable properties like quota
02624                  * and reservation to the received or default values even though
02625                  * they are not considered inheritable.
02626                  */
02627                 if (prop != ZPROP_INVAL && !zfs_prop_inheritable(prop))
02628                         return (EINVAL);
02629         }
02630 
02631         /* the property name has been validated by zfs_secpolicy_inherit() */
02632         return (dsl_prop_set(zc->zc_name, zc->zc_value, source, 0, 0, NULL));
02633 }
02634 
02635 static int
02636 zfs_ioc_pool_set_props(zfs_cmd_t *zc)
02637 {
02638         nvlist_t *props;
02639         spa_t *spa;
02640         int error;
02641         nvpair_t *pair;
02642 
02643         if (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
02644             zc->zc_iflags, &props))
02645                 return (error);
02646 
02647         /*
02648          * If the only property is the configfile, then just do a spa_lookup()
02649          * to handle the faulted case.
02650          */
02651         pair = nvlist_next_nvpair(props, NULL);
02652         if (pair != NULL && strcmp(nvpair_name(pair),
02653             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE)) == 0 &&
02654             nvlist_next_nvpair(props, pair) == NULL) {
02655                 mutex_enter(&spa_namespace_lock);
02656                 if ((spa = spa_lookup(zc->zc_name)) != NULL) {
02657                         spa_configfile_set(spa, props, B_FALSE);
02658                         spa_config_sync(spa, B_FALSE, B_TRUE);
02659                 }
02660                 mutex_exit(&spa_namespace_lock);
02661                 if (spa != NULL) {
02662                         nvlist_free(props);
02663                         return (0);
02664                 }
02665         }
02666 
02667         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
02668                 nvlist_free(props);
02669                 return (error);
02670         }
02671 
02672         error = spa_prop_set(spa, props);
02673 
02674         nvlist_free(props);
02675         spa_close(spa, FTAG);
02676 
02677         return (error);
02678 }
02679 
02680 static int
02681 zfs_ioc_pool_get_props(zfs_cmd_t *zc)
02682 {
02683         spa_t *spa;
02684         int error;
02685         nvlist_t *nvp = NULL;
02686 
02687         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
02688                 /*
02689                  * If the pool is faulted, there may be properties we can still
02690                  * get (such as altroot and cachefile), so attempt to get them
02691                  * anyway.
02692                  */
02693                 mutex_enter(&spa_namespace_lock);
02694                 if ((spa = spa_lookup(zc->zc_name)) != NULL)
02695                         error = spa_prop_get(spa, &nvp);
02696                 mutex_exit(&spa_namespace_lock);
02697         } else {
02698                 error = spa_prop_get(spa, &nvp);
02699                 spa_close(spa, FTAG);
02700         }
02701 
02702         if (error == 0 && zc->zc_nvlist_dst != 0)
02703                 error = put_nvlist(zc, nvp);
02704         else
02705                 error = EFAULT;
02706 
02707         nvlist_free(nvp);
02708         return (error);
02709 }
02710 
02719 static int
02720 zfs_ioc_set_fsacl(zfs_cmd_t *zc)
02721 {
02722         int error;
02723         nvlist_t *fsaclnv = NULL;
02724 
02725         if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
02726             zc->zc_iflags, &fsaclnv)) != 0)
02727                 return (error);
02728 
02729         /*
02730          * Verify nvlist is constructed correctly
02731          */
02732         if ((error = zfs_deleg_verify_nvlist(fsaclnv)) != 0) {
02733                 nvlist_free(fsaclnv);
02734                 return (EINVAL);
02735         }
02736 
02737         /*
02738          * If we don't have PRIV_SYS_MOUNT, then validate
02739          * that user is allowed to hand out each permission in
02740          * the nvlist(s)
02741          */
02742 
02743         error = secpolicy_zfs(CRED());
02744         if (error) {
02745                 if (zc->zc_perm_action == B_FALSE) {
02746                         error = dsl_deleg_can_allow(zc->zc_name,
02747                             fsaclnv, CRED());
02748                 } else {
02749                         error = dsl_deleg_can_unallow(zc->zc_name,
02750                             fsaclnv, CRED());
02751                 }
02752         }
02753 
02754         if (error == 0)
02755                 error = dsl_deleg_set(zc->zc_name, fsaclnv, zc->zc_perm_action);
02756 
02757         nvlist_free(fsaclnv);
02758         return (error);
02759 }
02760 
02768 static int
02769 zfs_ioc_get_fsacl(zfs_cmd_t *zc)
02770 {
02771         nvlist_t *nvp;
02772         int error;
02773 
02774         if ((error = dsl_deleg_get(zc->zc_name, &nvp)) == 0) {
02775                 error = put_nvlist(zc, nvp);
02776                 nvlist_free(nvp);
02777         }
02778 
02779         return (error);
02780 }
02781 
02787 static vfs_t *
02788 zfs_get_vfs(const char *resource)
02789 {
02790         vfs_t *vfsp;
02791 
02792         mtx_lock(&mountlist_mtx);
02793         TAILQ_FOREACH(vfsp, &mountlist, mnt_list) {
02794                 if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) {
02795                         VFS_HOLD(vfsp);
02796                         break;
02797                 }
02798         }
02799         mtx_unlock(&mountlist_mtx);
02800         return (vfsp);
02801 }
02802 
02803 /* ARGSUSED */
02804 static void
02805 zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
02806 {
02807         zfs_creat_t *zct = arg;
02808 
02809         zfs_create_fs(os, cr, zct->zct_zplprops, tx);
02810 }
02811 
02812 #define ZFS_PROP_UNDEFINED      ((uint64_t)-1)
02813 
02833 static int
02834 zfs_fill_zplprops_impl(objset_t *os, uint64_t zplver,
02835     boolean_t fuids_ok, boolean_t sa_ok, nvlist_t *createprops,
02836     nvlist_t *zplprops, boolean_t *is_ci)
02837 {
02838         uint64_t sense = ZFS_PROP_UNDEFINED;
02839         uint64_t norm = ZFS_PROP_UNDEFINED;
02840         uint64_t u8 = ZFS_PROP_UNDEFINED;
02841 
02842         ASSERT(zplprops != NULL);
02843 
02844         /*
02845          * Pull out creator prop choices, if any.
02846          */
02847         if (createprops) {
02848                 (void) nvlist_lookup_uint64(createprops,
02849                     zfs_prop_to_name(ZFS_PROP_VERSION), &zplver);
02850                 (void) nvlist_lookup_uint64(createprops,
02851                     zfs_prop_to_name(ZFS_PROP_NORMALIZE), &norm);
02852                 (void) nvlist_remove_all(createprops,
02853                     zfs_prop_to_name(ZFS_PROP_NORMALIZE));
02854                 (void) nvlist_lookup_uint64(createprops,
02855                     zfs_prop_to_name(ZFS_PROP_UTF8ONLY), &u8);
02856                 (void) nvlist_remove_all(createprops,
02857                     zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
02858                 (void) nvlist_lookup_uint64(createprops,
02859                     zfs_prop_to_name(ZFS_PROP_CASE), &sense);
02860                 (void) nvlist_remove_all(createprops,
02861                     zfs_prop_to_name(ZFS_PROP_CASE));
02862         }
02863 
02864         /*
02865          * If the zpl version requested is whacky or the file system
02866          * or pool is version is too "young" to support normalization
02867          * and the creator tried to set a value for one of the props,
02868          * error out.
02869          */
02870         if ((zplver < ZPL_VERSION_INITIAL || zplver > ZPL_VERSION) ||
02871             (zplver >= ZPL_VERSION_FUID && !fuids_ok) ||
02872             (zplver >= ZPL_VERSION_SA && !sa_ok) ||
02873             (zplver < ZPL_VERSION_NORMALIZATION &&
02874             (norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED ||
02875             sense != ZFS_PROP_UNDEFINED)))
02876                 return (ENOTSUP);
02877 
02878         /*
02879          * Put the version in the zplprops
02880          */
02881         VERIFY(nvlist_add_uint64(zplprops,
02882             zfs_prop_to_name(ZFS_PROP_VERSION), zplver) == 0);
02883 
02884         if (norm == ZFS_PROP_UNDEFINED)
02885                 VERIFY(zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &norm) == 0);
02886         VERIFY(nvlist_add_uint64(zplprops,
02887             zfs_prop_to_name(ZFS_PROP_NORMALIZE), norm) == 0);
02888 
02889         /*
02890          * If we're normalizing, names must always be valid UTF-8 strings.
02891          */
02892         if (norm)
02893                 u8 = 1;
02894         if (u8 == ZFS_PROP_UNDEFINED)
02895                 VERIFY(zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &u8) == 0);
02896         VERIFY(nvlist_add_uint64(zplprops,
02897             zfs_prop_to_name(ZFS_PROP_UTF8ONLY), u8) == 0);
02898 
02899         if (sense == ZFS_PROP_UNDEFINED)
02900                 VERIFY(zfs_get_zplprop(os, ZFS_PROP_CASE, &sense) == 0);
02901         VERIFY(nvlist_add_uint64(zplprops,
02902             zfs_prop_to_name(ZFS_PROP_CASE), sense) == 0);
02903 
02904         if (is_ci)
02905                 *is_ci = (sense == ZFS_CASE_INSENSITIVE);
02906 
02907         return (0);
02908 }
02909 
02910 static int
02911 zfs_fill_zplprops(const char *dataset, nvlist_t *createprops,
02912     nvlist_t *zplprops, boolean_t *is_ci)
02913 {
02914         boolean_t fuids_ok, sa_ok;
02915         uint64_t zplver = ZPL_VERSION;
02916         objset_t *os = NULL;
02917         char parentname[MAXNAMELEN];
02918         char *cp;
02919         spa_t *spa;
02920         uint64_t spa_vers;
02921         int error;
02922 
02923         (void) strlcpy(parentname, dataset, sizeof (parentname));
02924         cp = strrchr(parentname, '/');
02925         ASSERT(cp != NULL);
02926         cp[0] = '\0';
02927 
02928         if ((error = spa_open(dataset, &spa, FTAG)) != 0)
02929                 return (error);
02930 
02931         spa_vers = spa_version(spa);
02932         spa_close(spa, FTAG);
02933 
02934         zplver = zfs_zpl_version_map(spa_vers);
02935         fuids_ok = (zplver >= ZPL_VERSION_FUID);
02936         sa_ok = (zplver >= ZPL_VERSION_SA);
02937 
02938         /*
02939          * Open parent object set so we can inherit zplprop values.
02940          */
02941         if ((error = dmu_objset_hold(parentname, FTAG, &os)) != 0)
02942                 return (error);
02943 
02944         error = zfs_fill_zplprops_impl(os, zplver, fuids_ok, sa_ok, createprops,
02945             zplprops, is_ci);
02946         dmu_objset_rele(os, FTAG);
02947         return (error);
02948 }
02949 
02950 static int
02951 zfs_fill_zplprops_root(uint64_t spa_vers, nvlist_t *createprops,
02952     nvlist_t *zplprops, boolean_t *is_ci)
02953 {
02954         boolean_t fuids_ok;
02955         boolean_t sa_ok;
02956         uint64_t zplver = ZPL_VERSION;
02957         int error;
02958 
02959         zplver = zfs_zpl_version_map(spa_vers);
02960         fuids_ok = (zplver >= ZPL_VERSION_FUID);
02961         sa_ok = (zplver >= ZPL_VERSION_SA);
02962 
02963         error = zfs_fill_zplprops_impl(NULL, zplver, fuids_ok, sa_ok,
02964             createprops, zplprops, is_ci);
02965         return (error);
02966 }
02967 
02977 static int
02978 zfs_ioc_create(zfs_cmd_t *zc)
02979 {
02980         objset_t *clone;
02981         int error = 0;
02982         zfs_creat_t zct;
02983         nvlist_t *nvprops = NULL;
02984         void (*cbfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
02985         dmu_objset_type_t type = zc->zc_objset_type;
02986 
02987         switch (type) {
02988 
02989         case DMU_OST_ZFS:
02990                 cbfunc = zfs_create_cb;
02991                 break;
02992 
02993         case DMU_OST_ZVOL:
02994                 cbfunc = zvol_create_cb;
02995                 break;
02996 
02997         default:
02998                 cbfunc = NULL;
02999                 break;
03000         }
03001         if (strchr(zc->zc_name, '@') ||
03002             strchr(zc->zc_name, '%'))
03003                 return (EINVAL);
03004 
03005         if (zc->zc_nvlist_src != 0 &&
03006             (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
03007             zc->zc_iflags, &nvprops)) != 0)
03008                 return (error);
03009 
03010         zct.zct_zplprops = NULL;
03011         zct.zct_props = nvprops;
03012 
03013         if (zc->zc_value[0] != '\0') {
03014                 /*
03015                  * We're creating a clone of an existing snapshot.
03016                  */
03017                 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
03018                 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0) {
03019                         nvlist_free(nvprops);
03020                         return (EINVAL);
03021                 }
03022 
03023                 error = dmu_objset_hold(zc->zc_value, FTAG, &clone);
03024                 if (error) {
03025                         nvlist_free(nvprops);
03026                         return (error);
03027                 }
03028 
03029                 error = dmu_objset_clone(zc->zc_name, dmu_objset_ds(clone), 0);
03030                 dmu_objset_rele(clone, FTAG);
03031                 if (error) {
03032                         nvlist_free(nvprops);
03033                         return (error);
03034                 }
03035         } else {
03036                 boolean_t is_insensitive = B_FALSE;
03037 
03038                 if (cbfunc == NULL) {
03039                         nvlist_free(nvprops);
03040                         return (EINVAL);
03041                 }
03042 
03043                 if (type == DMU_OST_ZVOL) {
03044                         uint64_t volsize, volblocksize;
03045 
03046                         if (nvprops == NULL ||
03047                             nvlist_lookup_uint64(nvprops,
03048                             zfs_prop_to_name(ZFS_PROP_VOLSIZE),
03049                             &volsize) != 0) {
03050                                 nvlist_free(nvprops);
03051                                 return (EINVAL);
03052                         }
03053 
03054                         if ((error = nvlist_lookup_uint64(nvprops,
03055                             zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
03056                             &volblocksize)) != 0 && error != ENOENT) {
03057                                 nvlist_free(nvprops);
03058                                 return (EINVAL);
03059                         }
03060 
03061                         if (error != 0)
03062                                 volblocksize = zfs_prop_default_numeric(
03063                                     ZFS_PROP_VOLBLOCKSIZE);
03064 
03065                         if ((error = zvol_check_volblocksize(
03066                             volblocksize)) != 0 ||
03067                             (error = zvol_check_volsize(volsize,
03068                             volblocksize)) != 0) {
03069                                 nvlist_free(nvprops);
03070                                 return (error);
03071                         }
03072                 } else if (type == DMU_OST_ZFS) {
03073                         int error;
03074 
03075                         /*
03076                          * We have to have normalization and
03077                          * case-folding flags correct when we do the
03078                          * file system creation, so go figure them out
03079                          * now.
03080                          */
03081                         VERIFY(nvlist_alloc(&zct.zct_zplprops,
03082                             NV_UNIQUE_NAME, KM_SLEEP) == 0);
03083                         error = zfs_fill_zplprops(zc->zc_name, nvprops,
03084                             zct.zct_zplprops, &is_insensitive);
03085                         if (error != 0) {
03086                                 nvlist_free(nvprops);
03087                                 nvlist_free(zct.zct_zplprops);
03088                                 return (error);
03089                         }
03090                 }
03091                 error = dmu_objset_create(zc->zc_name, type,
03092                     is_insensitive ? DS_FLAG_CI_DATASET : 0, cbfunc, &zct);
03093                 nvlist_free(zct.zct_zplprops);
03094         }
03095 
03096         /*
03097          * It would be nice to do this atomically.
03098          */
03099         if (error == 0) {
03100                 error = zfs_set_prop_nvlist(zc->zc_name, ZPROP_SRC_LOCAL,
03101                     nvprops, NULL);
03102                 if (error != 0)
03103                         (void) dmu_objset_destroy(zc->zc_name, B_FALSE);
03104         }
03105         nvlist_free(nvprops);
03106 #ifdef __FreeBSD__
03107         if (error == 0 && type == DMU_OST_ZVOL)
03108                 zvol_create_minors(zc->zc_name);
03109 #endif
03110         return (error);
03111 }
03112 
03123 static int
03124 zfs_ioc_snapshot(zfs_cmd_t *zc)
03125 {
03126         nvlist_t *nvprops = NULL;
03127         int error;
03128         boolean_t recursive = zc->zc_cookie;
03129 
03130         if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
03131                 return (EINVAL);
03132 
03133         if (zc->zc_nvlist_src != 0 &&
03134             (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
03135             zc->zc_iflags, &nvprops)) != 0)
03136                 return (error);
03137 
03138         error = zfs_check_userprops(zc->zc_name, nvprops);
03139         if (error)
03140                 goto out;
03141 
03142         if (!nvlist_empty(nvprops) &&
03143             zfs_earlier_version(zc->zc_name, SPA_VERSION_SNAP_PROPS)) {
03144                 error = ENOTSUP;
03145                 goto out;
03146         }
03147 
03148         error = dmu_objset_snapshot(zc->zc_name, zc->zc_value, NULL,
03149             nvprops, recursive, B_FALSE, -1);
03150 
03151 out:
03152         nvlist_free(nvprops);
03153         return (error);
03154 }
03155 
03156 int
03157 zfs_unmount_snap(const char *name, void *arg)
03158 {
03159         vfs_t *vfsp = NULL;
03160 
03161         if (arg) {
03162                 char *snapname = arg;
03163                 char *fullname = kmem_asprintf("%s@%s", name, snapname);
03164                 vfsp = zfs_get_vfs(fullname);
03165                 strfree(fullname);
03166         } else if (strchr(name, '@')) {
03167                 vfsp = zfs_get_vfs(name);
03168         }
03169 
03170         if (vfsp) {
03171                 /*
03172                  * Always force the unmount for snapshots.
03173                  */
03174                 int flag = MS_FORCE;
03175                 int err;
03176 
03177                 if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) {
03178                         VFS_RELE(vfsp);
03179                         return (err);
03180                 }
03181                 VFS_RELE(vfsp);
03182                 mtx_lock(&Giant);       /* dounmount() */
03183                 dounmount(vfsp, flag, curthread);
03184                 mtx_unlock(&Giant);     /* dounmount() */
03185         }
03186         return (0);
03187 }
03188 
03198 static int
03199 zfs_ioc_destroy_snaps_nvl(zfs_cmd_t *zc)
03200 {
03201         int err, len;
03202         nvlist_t *nvl;
03203         nvpair_t *pair;
03204 
03205         if ((err = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
03206             zc->zc_iflags, &nvl)) != 0) {
03207 #ifndef __FreeBSD__
03208                 return (err);
03209 #else
03210                 /*
03211                  * We are probably called by older binaries,
03212                  * allocate and populate nvlist with recursive snapshots
03213                  */
03214                 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
03215                         return (EINVAL);
03216                 VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
03217                 err = dmu_get_recursive_snaps_nvl(zc->zc_name,
03218                     zc->zc_value, nvl);
03219                 if (err) {
03220                         nvlist_free(nvl);
03221                         return (err);
03222                 }
03223 #endif /* __FreeBSD__ */
03224         }
03225 
03226         len = strlen(zc->zc_name);
03227         for (pair = nvlist_next_nvpair(nvl, NULL); pair != NULL;
03228             pair = nvlist_next_nvpair(nvl, pair)) {
03229                 const char *name = nvpair_name(pair);
03230                 /*
03231                  * The snap name must be underneath the zc_name.  This ensures
03232                  * that our permission checks were legitimate.
03233                  */
03234                 if (strncmp(zc->zc_name, name, len) != 0 ||
03235                     (name[len] != '@' && name[len] != '/')) {
03236                         nvlist_free(nvl);
03237                         return (EINVAL);
03238                 }
03239 
03240                 (void) zfs_unmount_snap(name, NULL);
03241                 (void) zvol_remove_minor(name);
03242         }
03243 
03244         err = dmu_snapshots_destroy_nvl(nvl, zc->zc_defer_destroy,
03245             zc->zc_name);
03246         nvlist_free(nvl);
03247         return (err);
03248 }
03249 
03258 static int
03259 zfs_ioc_destroy(zfs_cmd_t *zc)
03260 {
03261         int err;
03262         if (strchr(zc->zc_name, '@') && zc->zc_objset_type == DMU_OST_ZFS) {
03263                 err = zfs_unmount_snap(zc->zc_name, NULL);
03264                 if (err)
03265                         return (err);
03266         }
03267 
03268         err = dmu_objset_destroy(zc->zc_name, zc->zc_defer_destroy);
03269         if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0)
03270                 (void) zvol_remove_minor(zc->zc_name);
03271         return (err);
03272 }
03273 
03280 static int
03281 zfs_ioc_rollback(zfs_cmd_t *zc)
03282 {
03283         dsl_dataset_t *ds, *clone;
03284         int error;
03285         zfsvfs_t *zfsvfs;
03286         char *clone_name;
03287 
03288         error = dsl_dataset_hold(zc->zc_name, FTAG, &ds);
03289         if (error)
03290                 return (error);
03291 
03292         /* must not be a snapshot */
03293         if (dsl_dataset_is_snapshot(ds)) {
03294                 dsl_dataset_rele(ds, FTAG);
03295                 return (EINVAL);
03296         }
03297 
03298         /* must have a most recent snapshot */
03299         if (ds->ds_phys->ds_prev_snap_txg < TXG_INITIAL) {
03300                 dsl_dataset_rele(ds, FTAG);
03301                 return (EINVAL);
03302         }
03303 
03304         /*
03305          * Create clone of most recent snapshot.
03306          */
03307         clone_name = kmem_asprintf("%s/%%rollback", zc->zc_name);
03308         error = dmu_objset_clone(clone_name, ds->ds_prev, DS_FLAG_INCONSISTENT);
03309         if (error)
03310                 goto out;
03311 
03312         error = dsl_dataset_own(clone_name, B_TRUE, FTAG, &clone);
03313         if (error)
03314                 goto out;
03315 
03316         /*
03317          * Do clone swap.
03318          */
03319         if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
03320                 error = zfs_suspend_fs(zfsvfs);
03321                 if (error == 0) {
03322                         int resume_err;
03323 
03324                         if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
03325                                 error = dsl_dataset_clone_swap(clone, ds,
03326                                     B_TRUE);
03327                                 dsl_dataset_disown(ds, FTAG);
03328                                 ds = NULL;
03329                         } else {
03330                                 error = EBUSY;
03331                         }
03332                         resume_err = zfs_resume_fs(zfsvfs, zc->zc_name);
03333                         error = error ? error : resume_err;
03334                 }
03335                 VFS_RELE(zfsvfs->z_vfs);
03336         } else {
03337                 if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
03338                         error = dsl_dataset_clone_swap(clone, ds, B_TRUE);
03339                         dsl_dataset_disown(ds, FTAG);
03340                         ds = NULL;
03341                 } else {
03342                         error = EBUSY;
03343                 }
03344         }
03345 
03346         /*
03347          * Destroy clone (which also closes it).
03348          */
03349         (void) dsl_dataset_destroy(clone, FTAG, B_FALSE);
03350 
03351 out:
03352         strfree(clone_name);
03353         if (ds)
03354                 dsl_dataset_rele(ds, FTAG);
03355         return (error);
03356 }
03357 
03366 static int
03367 zfs_ioc_rename(zfs_cmd_t *zc)
03368 {
03369         int flags = 0;
03370 
03371         if (zc->zc_cookie & 1)
03372                 flags |= ZFS_RENAME_RECURSIVE;
03373         if (zc->zc_cookie & 2)
03374                 flags |= ZFS_RENAME_ALLOW_MOUNTED;
03375 
03376         zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
03377         if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
03378             strchr(zc->zc_value, '%'))
03379                 return (EINVAL);
03380 
03381         /*
03382          * Unmount snapshot unless we're doing a recursive rename,
03383          * in which case the dataset code figures out which snapshots
03384          * to unmount.
03385          */
03386         if (!(flags & ZFS_RENAME_RECURSIVE) &&
03387             strchr(zc->zc_name, '@') != NULL &&
03388             zc->zc_objset_type == DMU_OST_ZFS) {
03389                 int err = zfs_unmount_snap(zc->zc_name, NULL);
03390                 if (err)
03391                         return (err);
03392         }
03393         return (dmu_objset_rename(zc->zc_name, zc->zc_value, flags));
03394 }
03395 
03396 static int
03397 zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
03398 {
03399         const char *propname = nvpair_name(pair);
03400         boolean_t issnap = (strchr(dsname, '@') != NULL);
03401         zfs_prop_t prop = zfs_name_to_prop(propname);
03402         uint64_t intval;
03403         int err;
03404 
03405         if (prop == ZPROP_INVAL) {
03406                 if (zfs_prop_user(propname)) {
03407                         if (err = zfs_secpolicy_write_perms(dsname,
03408                             ZFS_DELEG_PERM_USERPROP, cr))
03409                                 return (err);
03410                         return (0);
03411                 }
03412 
03413                 if (!issnap && zfs_prop_userquota(propname)) {
03414                         const char *perm = NULL;
03415                         const char *uq_prefix =
03416                             zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA];
03417                         const char *gq_prefix =
03418                             zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA];
03419 
03420                         if (strncmp(propname, uq_prefix,
03421                             strlen(uq_prefix)) == 0) {
03422                                 perm = ZFS_DELEG_PERM_USERQUOTA;
03423                         } else if (strncmp(propname, gq_prefix,
03424                             strlen(gq_prefix)) == 0) {
03425                                 perm = ZFS_DELEG_PERM_GROUPQUOTA;
03426                         } else {
03427                                 /* USERUSED and GROUPUSED are read-only */
03428                                 return (EINVAL);
03429                         }
03430 
03431                         if (err = zfs_secpolicy_write_perms(dsname, perm, cr))
03432                                 return (err);
03433                         return (0);
03434                 }
03435 
03436                 return (EINVAL);
03437         }
03438 
03439         if (issnap)
03440                 return (EINVAL);
03441 
03442         if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
03443                 /*
03444                  * dsl_prop_get_all_impl() returns properties in this
03445                  * format.
03446                  */
03447                 nvlist_t *attrs;
03448                 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
03449                 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
03450                     &pair) == 0);
03451         }
03452 
03453         /*
03454          * Check that this value is valid for this pool version
03455          */
03456         switch (prop) {
03457         case ZFS_PROP_COMPRESSION:
03458                 /*
03459                  * If the user specified gzip compression, make sure
03460                  * the SPA supports it. We ignore any errors here since
03461                  * we'll catch them later.
03462                  */
03463                 if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
03464                     nvpair_value_uint64(pair, &intval) == 0) {
03465                         if (intval >= ZIO_COMPRESS_GZIP_1 &&
03466                             intval <= ZIO_COMPRESS_GZIP_9 &&
03467                             zfs_earlier_version(dsname,
03468                             SPA_VERSION_GZIP_COMPRESSION)) {
03469                                 return (ENOTSUP);
03470                         }
03471 
03472                         if (intval == ZIO_COMPRESS_ZLE &&
03473                             zfs_earlier_version(dsname,
03474                             SPA_VERSION_ZLE_COMPRESSION))
03475                                 return (ENOTSUP);
03476 
03477                         /*
03478                          * If this is a bootable dataset then
03479                          * verify that the compression algorithm
03480                          * is supported for booting. We must return
03481                          * something other than ENOTSUP since it
03482                          * implies a downrev pool version.
03483                          */
03484                         if (zfs_is_bootfs(dsname) &&
03485                             !BOOTFS_COMPRESS_VALID(intval)) {
03486                                 return (ERANGE);
03487                         }
03488                 }
03489                 break;
03490 
03491         case ZFS_PROP_COPIES:
03492                 if (zfs_earlier_version(dsname, SPA_VERSION_DITTO_BLOCKS))
03493                         return (ENOTSUP);
03494                 break;
03495 
03496         case ZFS_PROP_DEDUP:
03497                 if (zfs_earlier_version(dsname, SPA_VERSION_DEDUP))
03498                         return (ENOTSUP);
03499                 break;
03500 
03501         case ZFS_PROP_SHARESMB:
03502                 if (zpl_earlier_version(dsname, ZPL_VERSION_FUID))
03503                         return (ENOTSUP);
03504                 break;
03505 
03506         case ZFS_PROP_ACLINHERIT:
03507                 if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
03508                     nvpair_value_uint64(pair, &intval) == 0) {
03509                         if (intval == ZFS_ACL_PASSTHROUGH_X &&
03510                             zfs_earlier_version(dsname,
03511                             SPA_VERSION_PASSTHROUGH_X))
03512                                 return (ENOTSUP);
03513                 }
03514                 break;
03515         }
03516 
03517         return (zfs_secpolicy_setprop(dsname, prop, pair, CRED()));
03518 }
03519 
03534 static int
03535 zfs_check_clearable(char *dataset, nvlist_t *props, nvlist_t **errlist)
03536 {
03537         zfs_cmd_t *zc;
03538         nvpair_t *pair, *next_pair;
03539         nvlist_t *errors;
03540         int err, rv = 0;
03541 
03542         if (props == NULL)
03543                 return (0);
03544 
03545         VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
03546 
03547         zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP);
03548         (void) strcpy(zc->zc_name, dataset);
03549         pair = nvlist_next_nvpair(props, NULL);
03550         while (pair != NULL) {
03551                 next_pair = nvlist_next_nvpair(props, pair);
03552 
03553                 (void) strcpy(zc->zc_value, nvpair_name(pair));
03554                 if ((err = zfs_check_settable(dataset, pair, CRED())) != 0 ||
03555                     (err = zfs_secpolicy_inherit(zc, CRED())) != 0) {
03556                         VERIFY(nvlist_remove_nvpair(props, pair) == 0);
03557                         VERIFY(nvlist_add_int32(errors,
03558                             zc->zc_value, err) == 0);
03559                 }
03560                 pair = next_pair;
03561         }
03562         kmem_free(zc, sizeof (zfs_cmd_t));
03563 
03564         if ((pair = nvlist_next_nvpair(errors, NULL)) == NULL) {
03565                 nvlist_free(errors);
03566                 errors = NULL;
03567         } else {
03568                 VERIFY(nvpair_value_int32(pair, &rv) == 0);
03569         }
03570 
03571         if (errlist == NULL)
03572                 nvlist_free(errors);
03573         else
03574                 *errlist = errors;
03575 
03576         return (rv);
03577 }
03578 
03579 static boolean_t
03580 propval_equals(nvpair_t *p1, nvpair_t *p2)
03581 {
03582         if (nvpair_type(p1) == DATA_TYPE_NVLIST) {
03583                 /* dsl_prop_get_all_impl() format */
03584                 nvlist_t *attrs;
03585                 VERIFY(nvpair_value_nvlist(p1, &attrs) == 0);
03586                 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
03587                     &p1) == 0);
03588         }
03589 
03590         if (nvpair_type(p2) == DATA_TYPE_NVLIST) {
03591                 nvlist_t *attrs;
03592                 VERIFY(nvpair_value_nvlist(p2, &attrs) == 0);
03593                 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
03594                     &p2) == 0);
03595         }
03596 
03597         if (nvpair_type(p1) != nvpair_type(p2))
03598                 return (B_FALSE);
03599 
03600         if (nvpair_type(p1) == DATA_TYPE_STRING) {
03601                 char *valstr1, *valstr2;
03602 
03603                 VERIFY(nvpair_value_string(p1, (char **)&valstr1) == 0);
03604                 VERIFY(nvpair_value_string(p2, (char **)&valstr2) == 0);
03605                 return (strcmp(valstr1, valstr2) == 0);
03606         } else {
03607                 uint64_t intval1, intval2;
03608 
03609                 VERIFY(nvpair_value_uint64(p1, &intval1) == 0);
03610                 VERIFY(nvpair_value_uint64(p2, &intval2) == 0);
03611                 return (intval1 == intval2);
03612         }
03613 }
03614 
03620 static void
03621 props_reduce(nvlist_t *props, nvlist_t *origprops)
03622 {
03623         nvpair_t *pair, *next_pair;
03624 
03625         if (origprops == NULL)
03626                 return; /* all props need to be received */
03627 
03628         pair = nvlist_next_nvpair(props, NULL);
03629         while (pair != NULL) {
03630                 const char *propname = nvpair_name(pair);
03631                 nvpair_t *match;
03632 
03633                 next_pair = nvlist_next_nvpair(props, pair);
03634 
03635                 if ((nvlist_lookup_nvpair(origprops, propname,
03636                     &match) != 0) || !propval_equals(pair, match))
03637                         goto next; /* need to set received value */
03638 
03639                 /* don't clear the existing received value */
03640                 (void) nvlist_remove_nvpair(origprops, match);
03641                 /* don't bother receiving the property */
03642                 (void) nvlist_remove_nvpair(props, pair);
03643 next:
03644                 pair = next_pair;
03645         }
03646 }
03647 
03648 #ifdef  DEBUG
03649 static boolean_t zfs_ioc_recv_inject_err;
03650 #endif
03651 
03670 static int
03671 zfs_ioc_recv(zfs_cmd_t *zc)
03672 {
03673         file_t *fp;
03674         objset_t *os;
03675         dmu_recv_cookie_t drc;
03676         boolean_t force = (boolean_t)zc->zc_guid;
03677         int fd;
03678         int error = 0;
03679         int props_error = 0;
03680         nvlist_t *errors;
03681         offset_t off;
03682         nvlist_t *props = NULL; /* sent properties */
03683         nvlist_t *origprops = NULL; /* existing properties */
03684         objset_t *origin = NULL;
03685         char *tosnap;
03686         char tofs[ZFS_MAXNAMELEN];
03687         boolean_t first_recvd_props = B_FALSE;
03688 
03689         if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
03690             strchr(zc->zc_value, '@') == NULL ||
03691             strchr(zc->zc_value, '%'))
03692                 return (EINVAL);
03693 
03694         (void) strcpy(tofs, zc->zc_value);
03695         tosnap = strchr(tofs, '@');
03696         *tosnap++ = '\0';
03697 
03698         if (zc->zc_nvlist_src != 0 &&
03699             (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
03700             zc->zc_iflags, &props)) != 0)
03701                 return (error);
03702 
03703         fd = zc->zc_cookie;
03704         fp = getf(fd);
03705         if (fp == NULL) {
03706                 nvlist_free(props);
03707                 return (EBADF);
03708         }
03709 
03710         VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
03711 
03712         if (props && dmu_objset_hold(tofs, FTAG, &os) == 0) {
03713                 if ((spa_version(os->os_spa) >= SPA_VERSION_RECVD_PROPS) &&
03714                     !dsl_prop_get_hasrecvd(os)) {
03715                         first_recvd_props = B_TRUE;
03716                 }
03717 
03718                 /*
03719                  * If new received properties are supplied, they are to
03720                  * completely replace the existing received properties, so stash
03721                  * away the existing ones.
03722                  */
03723                 if (dsl_prop_get_received(os, &origprops) == 0) {
03724                         nvlist_t *errlist = NULL;
03725                         /*
03726                          * Don't bother writing a property if its value won't
03727                          * change (and avoid the unnecessary security checks).
03728                          *
03729                          * The first receive after SPA_VERSION_RECVD_PROPS is a
03730                          * special case where we blow away all local properties
03731                          * regardless.
03732                          */
03733                         if (!first_recvd_props)
03734                                 props_reduce(props, origprops);
03735                         if (zfs_check_clearable(tofs, origprops,
03736                             &errlist) != 0)
03737                                 (void) nvlist_merge(errors, errlist, 0);
03738                         nvlist_free(errlist);
03739                 }
03740 
03741                 dmu_objset_rele(os, FTAG);
03742         }
03743 
03744         if (zc->zc_string[0]) {
03745                 error = dmu_objset_hold(zc->zc_string, FTAG, &origin);
03746                 if (error)
03747                         goto out;
03748         }
03749 
03750         error = dmu_recv_begin(tofs, tosnap, zc->zc_top_ds,
03751             &zc->zc_begin_record, force, origin, &drc);
03752         if (origin)
03753                 dmu_objset_rele(origin, FTAG);
03754         if (error)
03755                 goto out;
03756 
03757         /*
03758          * Set properties before we receive the stream so that they are applied
03759          * to the new data. Note that we must call dmu_recv_stream() if
03760          * dmu_recv_begin() succeeds.
03761          */
03762         if (props) {
03763                 nvlist_t *errlist;
03764 
03765                 if (dmu_objset_from_ds(drc.drc_logical_ds, &os) == 0) {
03766                         if (drc.drc_newfs) {
03767                                 if (spa_version(os->os_spa) >=
03768                                     SPA_VERSION_RECVD_PROPS)
03769                                         first_recvd_props = B_TRUE;
03770                         } else if (origprops != NULL) {
03771                                 if (clear_received_props(os, tofs, origprops,
03772                                     first_recvd_props ? NULL : props) != 0)
03773                                         zc->zc_obj |= ZPROP_ERR_NOCLEAR;
03774                         } else {
03775                                 zc->zc_obj |= ZPROP_ERR_NOCLEAR;
03776                         }
03777                         dsl_prop_set_hasrecvd(os);
03778                 } else if (!drc.drc_newfs) {
03779                         zc->zc_obj |= ZPROP_ERR_NOCLEAR;
03780                 }
03781 
03782                 (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
03783                     props, &errlist);
03784                 (void) nvlist_merge(errors, errlist, 0);
03785                 nvlist_free(errlist);
03786         }
03787 
03788         if (fit_error_list(zc, &errors) != 0 || put_nvlist(zc, errors) != 0) {
03789                 /*
03790                  * Caller made zc->zc_nvlist_dst less than the minimum expected
03791                  * size or supplied an invalid address.
03792                  */
03793                 props_error = EINVAL;
03794         }
03795 
03796         off = fp->f_offset;
03797         error = dmu_recv_stream(&drc, fp, &off, zc->zc_cleanup_fd,
03798             &zc->zc_action_handle);
03799 
03800         if (error == 0) {
03801                 zfsvfs_t *zfsvfs = NULL;
03802 
03803                 if (getzfsvfs(tofs, &zfsvfs) == 0) {
03804                         /* online recv */
03805                         int end_err;
03806 
03807                         error = zfs_suspend_fs(zfsvfs);
03808                         /*
03809                          * If the suspend fails, then the recv_end will
03810                          * likely also fail, and clean up after itself.
03811                          */
03812                         end_err = dmu_recv_end(&drc);
03813                         if (error == 0)
03814                                 error = zfs_resume_fs(zfsvfs, tofs);
03815                         error = error ? error : end_err;
03816                         VFS_RELE(zfsvfs->z_vfs);
03817                 } else {
03818                         error = dmu_recv_end(&drc);
03819                 }
03820         }
03821 
03822         zc->zc_cookie = off - fp->f_offset;
03823         if (off >= 0 && off <= MAXOFFSET_T)
03824                 fp->f_offset = off;
03825 
03826 #ifdef  DEBUG
03827         if (zfs_ioc_recv_inject_err) {
03828                 zfs_ioc_recv_inject_err = B_FALSE;
03829                 error = 1;
03830         }
03831 #endif
03832         /*
03833          * On error, restore the original props.
03834          */
03835         if (error && props) {
03836                 if (dmu_objset_hold(tofs, FTAG, &os) == 0) {
03837                         if (clear_received_props(os, tofs, props, NULL) != 0) {
03838                                 /*
03839                                  * We failed to clear the received properties.
03840                                  * Since we may have left a $recvd value on the
03841                                  * system, we can't clear the $hasrecvd flag.
03842                                  */
03843                                 zc->zc_obj |= ZPROP_ERR_NORESTORE;
03844                         } else if (first_recvd_props) {
03845                                 dsl_prop_unset_hasrecvd(os);
03846                         }
03847                         dmu_objset_rele(os, FTAG);
03848                 } else if (!drc.drc_newfs) {
03849                         /* We failed to clear the received properties. */
03850                         zc->zc_obj |= ZPROP_ERR_NORESTORE;
03851                 }
03852 
03853                 if (origprops == NULL && !drc.drc_newfs) {
03854                         /* We failed to stash the original properties. */
03855                         zc->zc_obj |= ZPROP_ERR_NORESTORE;
03856                 }
03857 
03858                 /*
03859                  * dsl_props_set() will not convert RECEIVED to LOCAL on or
03860                  * after SPA_VERSION_RECVD_PROPS, so we need to specify LOCAL
03861                  * explictly if we're restoring local properties cleared in the
03862                  * first new-style receive.
03863                  */
03864                 if (origprops != NULL &&
03865                     zfs_set_prop_nvlist(tofs, (first_recvd_props ?
03866                     ZPROP_SRC_LOCAL : ZPROP_SRC_RECEIVED),
03867                     origprops, NULL) != 0) {
03868                         /*
03869                          * We stashed the original properties but failed to
03870                          * restore them.
03871                          */
03872                         zc->zc_obj |= ZPROP_ERR_NORESTORE;
03873                 }
03874         }
03875 out:
03876         nvlist_free(props);
03877         nvlist_free(origprops);
03878         nvlist_free(errors);
03879         releasef(fd);
03880 
03881         if (error == 0)
03882                 error = props_error;
03883 
03884         return (error);
03885 }
03886 
03899 static int
03900 zfs_ioc_send(zfs_cmd_t *zc)
03901 {
03902         objset_t *fromsnap = NULL;
03903         objset_t *tosnap;
03904         int error;
03905         offset_t off;
03906         dsl_dataset_t *ds;
03907         dsl_dataset_t *dsfrom = NULL;
03908         spa_t *spa;
03909         dsl_pool_t *dp;
03910         boolean_t estimate = (zc->zc_guid != 0);
03911 
03912         error = spa_open(zc->zc_name, &spa, FTAG);
03913         if (error)
03914                 return (error);
03915 
03916         dp = spa_get_dsl(spa);
03917         rw_enter(&dp->dp_config_rwlock, RW_READER);
03918         error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
03919         rw_exit(&dp->dp_config_rwlock);
03920         if (error) {
03921                 spa_close(spa, FTAG);
03922                 return (error);
03923         }
03924 
03925         error = dmu_objset_from_ds(ds, &tosnap);
03926         if (error) {
03927                 dsl_dataset_rele(ds, FTAG);
03928                 spa_close(spa, FTAG);
03929                 return (error);
03930         }
03931 
03932         if (zc->zc_fromobj != 0) {
03933                 rw_enter(&dp->dp_config_rwlock, RW_READER);
03934                 error = dsl_dataset_hold_obj(dp, zc->zc_fromobj, FTAG, &dsfrom);
03935                 rw_exit(&dp->dp_config_rwlock);
03936                 spa_close(spa, FTAG);
03937                 if (error) {
03938                         dsl_dataset_rele(ds, FTAG);
03939                         return (error);
03940                 }
03941                 error = dmu_objset_from_ds(dsfrom, &fromsnap);
03942                 if (error) {
03943                         dsl_dataset_rele(dsfrom, FTAG);
03944                         dsl_dataset_rele(ds, FTAG);
03945                         return (error);
03946                 }
03947         } else {
03948                 spa_close(spa, FTAG);
03949         }
03950 
03951         if (estimate) {
03952                 error = dmu_send_estimate(tosnap, fromsnap, zc->zc_obj,
03953                     &zc->zc_objset_type);
03954         } else {
03955                 file_t *fp = getf(zc->zc_cookie);
03956                 if (fp == NULL) {
03957                         dsl_dataset_rele(ds, FTAG);
03958                         if (dsfrom)
03959                                 dsl_dataset_rele(dsfrom, FTAG);
03960                         return (EBADF);
03961                 }
03962 
03963                 off = fp->f_offset;
03964                 error = dmu_send(tosnap, fromsnap, zc->zc_obj,
03965                     zc->zc_cookie, fp, &off);
03966 
03967                 if (off >= 0 && off <= MAXOFFSET_T)
03968                         fp->f_offset = off;
03969                 releasef(zc->zc_cookie);
03970         }
03971         if (dsfrom)
03972                 dsl_dataset_rele(dsfrom, FTAG);
03973         dsl_dataset_rele(ds, FTAG);
03974         return (error);
03975 }
03976 
03977 /*
03978  * inputs:
03979  * zc_name      name of snapshot on which to report progress
03980  * zc_cookie    file descriptor of send stream
03981  *
03982  * outputs:
03983  * zc_cookie    number of bytes written in send stream thus far
03984  */
03985 static int
03986 zfs_ioc_send_progress(zfs_cmd_t *zc)
03987 {
03988         dsl_dataset_t *ds;
03989         dmu_sendarg_t *dsp = NULL;
03990         int error;
03991 
03992         if ((error = dsl_dataset_hold(zc->zc_name, FTAG, &ds)) != 0)
03993                 return (error);
03994 
03995         mutex_enter(&ds->ds_sendstream_lock);
03996 
03997         /*
03998          * Iterate over all the send streams currently active on this dataset.
03999          * If there's one which matches the specified file descriptor _and_ the
04000          * stream was started by the current process, return the progress of
04001          * that stream.
04002          */
04003         for (dsp = list_head(&ds->ds_sendstreams); dsp != NULL;
04004             dsp = list_next(&ds->ds_sendstreams, dsp)) {
04005                 if (dsp->dsa_outfd == zc->zc_cookie &&
04006                     dsp->dsa_proc == curproc)
04007                         break;
04008         }
04009 
04010         if (dsp != NULL)
04011                 zc->zc_cookie = *(dsp->dsa_off);
04012         else
04013                 error = ENOENT;
04014 
04015         mutex_exit(&ds->ds_sendstream_lock);
04016         dsl_dataset_rele(ds, FTAG);
04017         return (error);
04018 }
04019 
04020 static int
04021 zfs_ioc_inject_fault(zfs_cmd_t *zc)
04022 {
04023         int id, error;
04024 
04025         error = zio_inject_fault(zc->zc_name, (int)zc->zc_guid, &id,
04026             &zc->zc_inject_record);
04027 
04028         if (error == 0)
04029                 zc->zc_guid = (uint64_t)id;
04030 
04031         return (error);
04032 }
04033 
04034 static int
04035 zfs_ioc_clear_fault(zfs_cmd_t *zc)
04036 {
04037         return (zio_clear_fault((int)zc->zc_guid));
04038 }
04039 
04040 static int
04041 zfs_ioc_inject_list_next(zfs_cmd_t *zc)
04042 {
04043         int id = (int)zc->zc_guid;
04044         int error;
04045 
04046         error = zio_inject_list_next(&id, zc->zc_name, sizeof (zc->zc_name),
04047             &zc->zc_inject_record);
04048 
04049         zc->zc_guid = id;
04050 
04051         return (error);
04052 }
04053 
04054 static int
04055 zfs_ioc_error_log(zfs_cmd_t *zc)
04056 {
04057         spa_t *spa;
04058         int error;
04059         size_t count = (size_t)zc->zc_nvlist_dst_size;
04060 
04061         if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
04062                 return (error);
04063 
04064         error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst,
04065             &count);
04066         if (error == 0)
04067                 zc->zc_nvlist_dst_size = count;
04068         else
04069                 zc->zc_nvlist_dst_size = spa_get_errlog_size(spa);
04070 
04071         spa_close(spa, FTAG);
04072 
04073         return (error);
04074 }
04075 
04076 static int
04077 zfs_ioc_clear(zfs_cmd_t *zc)
04078 {
04079         spa_t *spa;
04080         vdev_t *vd;
04081         int error;
04082 
04083         /*
04084          * On zpool clear we also fix up missing slogs
04085          */
04086         mutex_enter(&spa_namespace_lock);
04087         spa = spa_lookup(zc->zc_name);
04088         if (spa == NULL) {
04089                 mutex_exit(&spa_namespace_lock);
04090                 return (EIO);
04091         }
04092         if (spa_get_log_state(spa) == SPA_LOG_MISSING) {
04093                 /* we need to let spa_open/spa_load clear the chains */
04094                 spa_set_log_state(spa, SPA_LOG_CLEAR);
04095         }
04096         spa->spa_last_open_failed = 0;
04097         mutex_exit(&spa_namespace_lock);
04098 
04099         if (zc->zc_cookie & ZPOOL_NO_REWIND) {
04100                 error = spa_open(zc->zc_name, &spa, FTAG);
04101         } else {
04102                 nvlist_t *policy;
04103                 nvlist_t *config = NULL;
04104 
04105                 if (zc->zc_nvlist_src == 0)
04106                         return (EINVAL);
04107 
04108                 if ((error = get_nvlist(zc->zc_nvlist_src,
04109                     zc->zc_nvlist_src_size, zc->zc_iflags, &policy)) == 0) {
04110                         error = spa_open_rewind(zc->zc_name, &spa, FTAG,
04111                             policy, &config);
04112                         if (config != NULL) {
04113                                 int err;
04114 
04115                                 if ((err = put_nvlist(zc, config)) != 0)
04116                                         error = err;
04117                                 nvlist_free(config);
04118                         }
04119                         nvlist_free(policy);
04120                 }
04121         }
04122 
04123         if (error)
04124                 return (error);
04125 
04126         spa_vdev_state_enter(spa, SCL_NONE);
04127 
04128         if (zc->zc_guid == 0) {
04129                 vd = NULL;
04130         } else {
04131                 vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE);
04132                 if (vd == NULL) {
04133                         (void) spa_vdev_state_exit(spa, NULL, ENODEV);
04134                         spa_close(spa, FTAG);
04135                         return (ENODEV);
04136                 }
04137         }
04138 
04139         vdev_clear(spa, vd);
04140 
04141         (void) spa_vdev_state_exit(spa, NULL, 0);
04142 
04143         /*
04144          * Resume any suspended I/Os.
04145          */
04146         if (zio_resume(spa) != 0)
04147                 error = EIO;
04148 
04149         spa_close(spa, FTAG);
04150 
04151         return (error);
04152 }
04153 
04154 static int
04155 zfs_ioc_pool_reopen(zfs_cmd_t *zc)
04156 {
04157         spa_t *spa;
04158         int error;
04159 
04160         error = spa_open(zc->zc_name, &spa, FTAG);
04161         if (error)
04162                 return (error);
04163 
04164         spa_vdev_state_enter(spa, SCL_NONE);
04165 
04166         /*
04167          * If a resilver is already in progress then set the
04168          * spa_scrub_reopen flag to B_TRUE so that we don't restart
04169          * the scan as a side effect of the reopen. Otherwise, let
04170          * vdev_open() decided if a resilver is required.
04171          */
04172         spa->spa_scrub_reopen = dsl_scan_resilvering(spa->spa_dsl_pool);
04173         vdev_reopen(spa->spa_root_vdev);
04174         spa->spa_scrub_reopen = B_FALSE;
04175 
04176         (void) spa_vdev_state_exit(spa, NULL, 0);
04177         spa_close(spa, FTAG);
04178         return (0);
04179 }
04180 
04189 static int
04190 zfs_ioc_promote(zfs_cmd_t *zc)
04191 {
04192         char *cp;
04193 
04194         /*
04195          * We don't need to unmount *all* the origin fs's snapshots, but
04196          * it's easier.
04197          */
04198         cp = strchr(zc->zc_value, '@');
04199         if (cp)
04200                 *cp = '\0';
04201         (void) dmu_objset_find(zc->zc_value,
04202             zfs_unmount_snap, NULL, DS_FIND_SNAPSHOTS);
04203         return (dsl_dataset_promote(zc->zc_name, zc->zc_string));
04204 }
04205 
04218 static int
04219 zfs_ioc_userspace_one(zfs_cmd_t *zc)
04220 {
04221         zfsvfs_t *zfsvfs;
04222         int error;
04223 
04224         if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
04225                 return (EINVAL);
04226 
04227         error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
04228         if (error)
04229                 return (error);
04230 
04231         error = zfs_userspace_one(zfsvfs,
04232             zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie);
04233         zfsvfs_rele(zfsvfs, FTAG);
04234 
04235         return (error);
04236 }
04237 
04249 static int
04250 zfs_ioc_userspace_many(zfs_cmd_t *zc)
04251 {
04252         zfsvfs_t *zfsvfs;
04253         int bufsize = zc->zc_nvlist_dst_size;
04254 
04255         if (bufsize <= 0)
04256                 return (ENOMEM);
04257 
04258         int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
04259         if (error)
04260                 return (error);
04261 
04262         void *buf = kmem_alloc(bufsize, KM_SLEEP);
04263 
04264         error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie,
04265             buf, &zc->zc_nvlist_dst_size);
04266 
04267         if (error == 0) {
04268                 error = ddi_copyout(buf,
04269                     (void *)(uintptr_t)zc->zc_nvlist_dst,
04270                     zc->zc_nvlist_dst_size, zc->zc_iflags);
04271         }
04272         kmem_free(buf, bufsize);
04273         zfsvfs_rele(zfsvfs, FTAG);
04274 
04275         return (error);
04276 }
04277 
04285 static int
04286 zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
04287 {
04288         objset_t *os;
04289         int error = 0;
04290         zfsvfs_t *zfsvfs;
04291 
04292         if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
04293                 if (!dmu_objset_userused_enabled(zfsvfs->z_os)) {
04294                         /*
04295                          * If userused is not enabled, it may be because the
04296                          * objset needs to be closed & reopened (to grow the
04297                          * objset_phys_t).  Suspend/resume the fs will do that.
04298                          */
04299                         error = zfs_suspend_fs(zfsvfs);
04300                         if (error == 0)
04301                                 error = zfs_resume_fs(zfsvfs, zc->zc_name);
04302                 }
04303                 if (error == 0)
04304                         error = dmu_objset_userspace_upgrade(zfsvfs->z_os);
04305                 VFS_RELE(zfsvfs->z_vfs);
04306         } else {
04307                 /* XXX kind of reading contents without owning */
04308                 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
04309                 if (error)
04310                         return (error);
04311 
04312                 error = dmu_objset_userspace_upgrade(os);
04313                 dmu_objset_rele(os, FTAG);
04314         }
04315 
04316         return (error);
04317 }
04318 
04319 #ifdef sun
04320 /*
04321  * We don't want to have a hard dependency
04322  * against some special symbols in sharefs
04323  * nfs, and smbsrv.  Determine them if needed when
04324  * the first file system is shared.
04325  * Neither sharefs, nfs or smbsrv are unloadable modules.
04326  */
04327 int (*znfsexport_fs)(void *arg);
04328 int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t);
04329 int (*zsmbexport_fs)(void *arg, boolean_t add_share);
04330 
04331 int zfs_nfsshare_inited;
04332 int zfs_smbshare_inited;
04333 
04334 ddi_modhandle_t nfs_mod;
04335 ddi_modhandle_t sharefs_mod;
04336 ddi_modhandle_t smbsrv_mod;
04337 #endif  /* sun */
04338 kmutex_t zfs_share_lock;
04339 
04340 #ifdef sun
04341 static int
04342 zfs_init_sharefs()
04343 {
04344         int error;
04345 
04346         ASSERT(MUTEX_HELD(&zfs_share_lock));
04347         /* Both NFS and SMB shares also require sharetab support. */
04348         if (sharefs_mod == NULL && ((sharefs_mod =
04349             ddi_modopen("fs/sharefs",
04350             KRTLD_MODE_FIRST, &error)) == NULL)) {
04351                 return (ENOSYS);
04352         }
04353         if (zshare_fs == NULL && ((zshare_fs =
04354             (int (*)(enum sharefs_sys_op, share_t *, uint32_t))
04355             ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) {
04356                 return (ENOSYS);
04357         }
04358         return (0);
04359 }
04360 #endif  /* sun */
04361 
04362 static int
04363 zfs_ioc_share(zfs_cmd_t *zc)
04364 {
04365 #ifdef sun
04366         int error;
04367         int opcode;
04368 
04369         switch (zc->zc_share.z_sharetype) {
04370         case ZFS_SHARE_NFS:
04371         case ZFS_UNSHARE_NFS:
04372                 if (zfs_nfsshare_inited == 0) {
04373                         mutex_enter(&zfs_share_lock);
04374                         if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs",
04375                             KRTLD_MODE_FIRST, &error)) == NULL)) {
04376                                 mutex_exit(&zfs_share_lock);
04377                                 return (ENOSYS);
04378                         }
04379                         if (znfsexport_fs == NULL &&
04380                             ((znfsexport_fs = (int (*)(void *))
04381                             ddi_modsym(nfs_mod,
04382                             "nfs_export", &error)) == NULL)) {
04383                                 mutex_exit(&zfs_share_lock);
04384                                 return (ENOSYS);
04385                         }
04386                         error = zfs_init_sharefs();
04387                         if (error) {
04388                                 mutex_exit(&zfs_share_lock);
04389                                 return (ENOSYS);
04390                         }
04391                         zfs_nfsshare_inited = 1;
04392                         mutex_exit(&zfs_share_lock);
04393                 }
04394                 break;
04395         case ZFS_SHARE_SMB:
04396         case ZFS_UNSHARE_SMB:
04397                 if (zfs_smbshare_inited == 0) {
04398                         mutex_enter(&zfs_share_lock);
04399                         if (smbsrv_mod == NULL && ((smbsrv_mod =
04400                             ddi_modopen("drv/smbsrv",
04401                             KRTLD_MODE_FIRST, &error)) == NULL)) {
04402                                 mutex_exit(&zfs_share_lock);
04403                                 return (ENOSYS);
04404                         }
04405                         if (zsmbexport_fs == NULL && ((zsmbexport_fs =
04406                             (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod,
04407                             "smb_server_share", &error)) == NULL)) {
04408                                 mutex_exit(&zfs_share_lock);
04409                                 return (ENOSYS);
04410                         }
04411                         error = zfs_init_sharefs();
04412                         if (error) {
04413                                 mutex_exit(&zfs_share_lock);
04414                                 return (ENOSYS);
04415                         }
04416                         zfs_smbshare_inited = 1;
04417                         mutex_exit(&zfs_share_lock);
04418                 }
04419                 break;
04420         default:
04421                 return (EINVAL);
04422         }
04423 
04424         switch (zc->zc_share.z_sharetype) {
04425         case ZFS_SHARE_NFS:
04426         case ZFS_UNSHARE_NFS:
04427                 if (error =
04428                     znfsexport_fs((void *)
04429                     (uintptr_t)zc->zc_share.z_exportdata))
04430                         return (error);
04431                 break;
04432         case ZFS_SHARE_SMB:
04433         case ZFS_UNSHARE_SMB:
04434                 if (error = zsmbexport_fs((void *)
04435                     (uintptr_t)zc->zc_share.z_exportdata,
04436                     zc->zc_share.z_sharetype == ZFS_SHARE_SMB ?
04437                     B_TRUE: B_FALSE)) {
04438                         return (error);
04439                 }
04440                 break;
04441         }
04442 
04443         opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS ||
04444             zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ?
04445             SHAREFS_ADD : SHAREFS_REMOVE;
04446 
04447         /*
04448          * Add or remove share from sharetab
04449          */
04450         error = zshare_fs(opcode,
04451             (void *)(uintptr_t)zc->zc_share.z_sharedata,
04452             zc->zc_share.z_sharemax);
04453 
04454         return (error);
04455 
04456 #else   /* !sun */
04457         return (ENOSYS);
04458 #endif  /* !sun */
04459 }
04460 
04461 ace_t full_access[] = {
04462         {(uid_t)-1, ACE_ALL_PERMS, ACE_EVERYONE, 0}
04463 };
04464 
04473 static int
04474 zfs_ioc_next_obj(zfs_cmd_t *zc)
04475 {
04476         objset_t *os = NULL;
04477         int error;
04478 
04479         error = dmu_objset_hold(zc->zc_name, FTAG, &os);
04480         if (error)
04481                 return (error);
04482 
04483         error = dmu_object_next(os, &zc->zc_obj, B_FALSE,
04484             os->os_dsl_dataset->ds_phys->ds_prev_snap_txg);
04485 
04486         dmu_objset_rele(os, FTAG);
04487         return (error);
04488 }
04489 
04498 static int
04499 zfs_ioc_tmp_snapshot(zfs_cmd_t *zc)
04500 {
04501         char *snap_name;
04502         int error;
04503 
04504         snap_name = kmem_asprintf("%s-%016llx", zc->zc_value,
04505             (u_longlong_t)ddi_get_lbolt64());
04506 
04507         if (strlen(snap_name) >= MAXNAMELEN) {
04508                 strfree(snap_name);
04509                 return (E2BIG);
04510         }
04511 
04512         error = dmu_objset_snapshot(zc->zc_name, snap_name, snap_name,
04513             NULL, B_FALSE, B_TRUE, zc->zc_cleanup_fd);
04514         if (error != 0) {
04515                 strfree(snap_name);
04516                 return (error);
04517         }
04518 
04519         (void) strcpy(zc->zc_value, snap_name);
04520         strfree(snap_name);
04521         return (0);
04522 }
04523 
04533 static int
04534 zfs_ioc_diff(zfs_cmd_t *zc)
04535 {
04536         objset_t *fromsnap;
04537         objset_t *tosnap;
04538         file_t *fp;
04539         offset_t off;
04540         int error;
04541 
04542         error = dmu_objset_hold(zc->zc_name, FTAG, &tosnap);
04543         if (error)
04544                 return (error);
04545 
04546         error = dmu_objset_hold(zc->zc_value, FTAG, &fromsnap);
04547         if (error) {
04548                 dmu_objset_rele(tosnap, FTAG);
04549                 return (error);
04550         }
04551 
04552         fp = getf(zc->zc_cookie);
04553         if (fp == NULL) {
04554                 dmu_objset_rele(fromsnap, FTAG);
04555                 dmu_objset_rele(tosnap, FTAG);
04556                 return (EBADF);
04557         }
04558 
04559         off = fp->f_offset;
04560 
04561         error = dmu_diff(tosnap, fromsnap, fp, &off);
04562 
04563         if (off >= 0 && off <= MAXOFFSET_T)
04564                 fp->f_offset = off;
04565         releasef(zc->zc_cookie);
04566 
04567         dmu_objset_rele(fromsnap, FTAG);
04568         dmu_objset_rele(tosnap, FTAG);
04569         return (error);
04570 }
04571 
04572 #ifdef sun
04573 
04576 static int
04577 zfs_smb_acl_purge(znode_t *dzp)
04578 {
04579         zap_cursor_t    zc;
04580         zap_attribute_t zap;
04581         zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
04582         int error;
04583 
04584         for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
04585             (error = zap_cursor_retrieve(&zc, &zap)) == 0;
04586             zap_cursor_advance(&zc)) {
04587                 if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred,
04588                     NULL, 0)) != 0)
04589                         break;
04590         }
04591         zap_cursor_fini(&zc);
04592         return (error);
04593 }
04594 #endif  /* sun */
04595 
04596 static int
04597 zfs_ioc_smb_acl(zfs_cmd_t *zc)
04598 {
04599 #ifdef sun
04600         vnode_t *vp;
04601         znode_t *dzp;
04602         vnode_t *resourcevp = NULL;
04603         znode_t *sharedir;
04604         zfsvfs_t *zfsvfs;
04605         nvlist_t *nvlist;
04606         char *src, *target;
04607         vattr_t vattr;
04608         vsecattr_t vsec;
04609         int error = 0;
04610 
04611         if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
04612             NO_FOLLOW, NULL, &vp)) != 0)
04613                 return (error);
04614 
04615         /* Now make sure mntpnt and dataset are ZFS */
04616 
04617         if (strcmp(vp->v_vfsp->mnt_stat.f_fstypename, "zfs") != 0 ||
04618             (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
04619             zc->zc_name) != 0)) {
04620                 VN_RELE(vp);
04621                 return (EINVAL);
04622         }
04623 
04624         dzp = VTOZ(vp);
04625         zfsvfs = dzp->z_zfsvfs;
04626         ZFS_ENTER(zfsvfs);
04627 
04628         /*
04629          * Create share dir if its missing.
04630          */
04631         mutex_enter(&zfsvfs->z_lock);
04632         if (zfsvfs->z_shares_dir == 0) {
04633                 dmu_tx_t *tx;
04634 
04635                 tx = dmu_tx_create(zfsvfs->z_os);
04636                 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE,
04637                     ZFS_SHARES_DIR);
04638                 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
04639                 error = dmu_tx_assign(tx, TXG_WAIT);
04640                 if (error) {
04641                         dmu_tx_abort(tx);
04642                 } else {
04643                         error = zfs_create_share_dir(zfsvfs, tx);
04644                         dmu_tx_commit(tx);
04645                 }
04646                 if (error) {
04647                         mutex_exit(&zfsvfs->z_lock);
04648                         VN_RELE(vp);
04649                         ZFS_EXIT(zfsvfs);
04650                         return (error);
04651                 }
04652         }
04653         mutex_exit(&zfsvfs->z_lock);
04654 
04655         ASSERT(zfsvfs->z_shares_dir);
04656         if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &sharedir)) != 0) {
04657                 VN_RELE(vp);
04658                 ZFS_EXIT(zfsvfs);
04659                 return (error);
04660         }
04661 
04662         switch (zc->zc_cookie) {
04663         case ZFS_SMB_ACL_ADD:
04664                 vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
04665                 vattr.va_type = VREG;
04666                 vattr.va_mode = S_IFREG|0777;
04667                 vattr.va_uid = 0;
04668                 vattr.va_gid = 0;
04669 
04670                 vsec.vsa_mask = VSA_ACE;
04671                 vsec.vsa_aclentp = &full_access;
04672                 vsec.vsa_aclentsz = sizeof (full_access);
04673                 vsec.vsa_aclcnt = 1;
04674 
04675                 error = VOP_CREATE(ZTOV(sharedir), zc->zc_string,
04676                     &vattr, EXCL, 0, &resourcevp, kcred, 0, NULL, &vsec);
04677                 if (resourcevp)
04678                         VN_RELE(resourcevp);
04679                 break;
04680 
04681         case ZFS_SMB_ACL_REMOVE:
04682                 error = VOP_REMOVE(ZTOV(sharedir), zc->zc_string, kcred,
04683                     NULL, 0);
04684                 break;
04685 
04686         case ZFS_SMB_ACL_RENAME:
04687                 if ((error = get_nvlist(zc->zc_nvlist_src,
04688                     zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) {
04689                         VN_RELE(vp);
04690                         ZFS_EXIT(zfsvfs);
04691                         return (error);
04692                 }
04693                 if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
04694                     nvlist_lookup_string(nvlist, ZFS_SMB_ACL_TARGET,
04695                     &target)) {
04696                         VN_RELE(vp);
04697                         VN_RELE(ZTOV(sharedir));
04698                         ZFS_EXIT(zfsvfs);
04699                         nvlist_free(nvlist);
04700                         return (error);
04701                 }
04702                 error = VOP_RENAME(ZTOV(sharedir), src, ZTOV(sharedir), target,
04703                     kcred, NULL, 0);
04704                 nvlist_free(nvlist);
04705                 break;
04706 
04707         case ZFS_SMB_ACL_PURGE:
04708                 error = zfs_smb_acl_purge(sharedir);
04709                 break;
04710 
04711         default:
04712                 error = EINVAL;
04713                 break;
04714         }
04715 
04716         VN_RELE(vp);
04717         VN_RELE(ZTOV(sharedir));
04718 
04719         ZFS_EXIT(zfsvfs);
04720 
04721         return (error);
04722 #else   /* !sun */
04723         return (EOPNOTSUPP);
04724 #endif  /* !sun */
04725 }
04726 
04740 static int
04741 zfs_ioc_hold(zfs_cmd_t *zc)
04742 {
04743         boolean_t recursive = zc->zc_cookie;
04744         spa_t *spa;
04745         dsl_pool_t *dp;
04746         dsl_dataset_t *ds;
04747         int error;
04748         minor_t minor = 0;
04749 
04750         if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
04751                 return (EINVAL);
04752 
04753         if (zc->zc_sendobj == 0) {
04754                 return (dsl_dataset_user_hold(zc->zc_name, zc->zc_value,
04755                     zc->zc_string, recursive, zc->zc_temphold,
04756                     zc->zc_cleanup_fd));
04757         }
04758 
04759         if (recursive)
04760                 return (EINVAL);
04761 
04762         error = spa_open(zc->zc_name, &spa, FTAG);
04763         if (error)
04764                 return (error);
04765 
04766         dp = spa_get_dsl(spa);
04767         rw_enter(&dp->dp_config_rwlock, RW_READER);
04768         error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
04769         rw_exit(&dp->dp_config_rwlock);
04770         spa_close(spa, FTAG);
04771         if (error)
04772                 return (error);
04773 
04774         /*
04775          * Until we have a hold on this snapshot, it's possible that
04776          * zc_sendobj could've been destroyed and reused as part
04777          * of a later txg.  Make sure we're looking at the right object.
04778          */
04779         if (zc->zc_createtxg != ds->ds_phys->ds_creation_txg) {
04780                 dsl_dataset_rele(ds, FTAG);
04781                 return (ENOENT);
04782         }
04783 
04784         if (zc->zc_cleanup_fd != -1 && zc->zc_temphold) {
04785                 error = zfs_onexit_fd_hold(zc->zc_cleanup_fd, &minor);
04786                 if (error) {
04787                         dsl_dataset_rele(ds, FTAG);
04788                         return (error);
04789                 }
04790         }
04791 
04792         error = dsl_dataset_user_hold_for_send(ds, zc->zc_string,
04793             zc->zc_temphold);
04794         if (minor != 0) {
04795                 if (error == 0) {
04796                         dsl_register_onexit_hold_cleanup(ds, zc->zc_string,
04797                             minor);
04798                 }
04799                 zfs_onexit_fd_rele(zc->zc_cleanup_fd);
04800         }
04801         dsl_dataset_rele(ds, FTAG);
04802 
04803         return (error);
04804 }
04805 
04815 static int
04816 zfs_ioc_release(zfs_cmd_t *zc)
04817 {
04818         boolean_t recursive = zc->zc_cookie;
04819 
04820         if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
04821                 return (EINVAL);
04822 
04823         return (dsl_dataset_user_release(zc->zc_name, zc->zc_value,
04824             zc->zc_string, recursive));
04825 }
04826 
04834 static int
04835 zfs_ioc_get_holds(zfs_cmd_t *zc)
04836 {
04837         nvlist_t *nvp;
04838         int error;
04839 
04840         if ((error = dsl_dataset_get_holds(zc->zc_name, &nvp)) == 0) {
04841                 error = put_nvlist(zc, nvp);
04842                 nvlist_free(nvp);
04843         }
04844 
04845         return (error);
04846 }
04847 
04858 static int
04859 zfs_ioc_space_written(zfs_cmd_t *zc)
04860 {
04861         int error;
04862         dsl_dataset_t *new, *old;
04863 
04864         error = dsl_dataset_hold(zc->zc_name, FTAG, &new);
04865         if (error != 0)
04866                 return (error);
04867         error = dsl_dataset_hold(zc->zc_value, FTAG, &old);
04868         if (error != 0) {
04869                 dsl_dataset_rele(new, FTAG);
04870                 return (error);
04871         }
04872 
04873         error = dsl_dataset_space_written(old, new, &zc->zc_cookie,
04874             &zc->zc_objset_type, &zc->zc_perm_action);
04875         dsl_dataset_rele(old, FTAG);
04876         dsl_dataset_rele(new, FTAG);
04877         return (error);
04878 }
04879 
04880 /*
04881  * inputs:
04882  * zc_name              full name of last snapshot
04883  * zc_value             full name of first snapshot
04884  *
04885  * outputs:
04886  * zc_cookie            space in bytes
04887  * zc_objset_type       compressed space in bytes
04888  * zc_perm_action       uncompressed space in bytes
04889  */
04890 static int
04891 zfs_ioc_space_snaps(zfs_cmd_t *zc)
04892 {
04893         int error;
04894         dsl_dataset_t *new, *old;
04895 
04896         error = dsl_dataset_hold(zc->zc_name, FTAG, &new);
04897         if (error != 0)
04898                 return (error);
04899         error = dsl_dataset_hold(zc->zc_value, FTAG, &old);
04900         if (error != 0) {
04901                 dsl_dataset_rele(new, FTAG);
04902                 return (error);
04903         }
04904 
04905         error = dsl_dataset_space_wouldfree(old, new, &zc->zc_cookie,
04906             &zc->zc_objset_type, &zc->zc_perm_action);
04907         dsl_dataset_rele(old, FTAG);
04908         dsl_dataset_rele(new, FTAG);
04909         return (error);
04910 }
04911 
04917 static int
04918 zfs_ioc_jail(zfs_cmd_t *zc)
04919 {
04920 
04921         return (zone_dataset_attach(curthread->td_ucred, zc->zc_name,
04922             (int)zc->zc_jailid));
04923 }
04924 
04925 static int
04926 zfs_ioc_unjail(zfs_cmd_t *zc)
04927 {
04928 
04929         return (zone_dataset_detach(curthread->td_ucred, zc->zc_name,
04930             (int)zc->zc_jailid));
04931 }
04932 
04933 static zfs_ioc_vec_t zfs_ioc_vec[] = {
04934         { zfs_ioc_pool_create, zfs_secpolicy_config, POOL_NAME, B_FALSE,
04935             B_FALSE },
04936         { zfs_ioc_pool_destroy, zfs_secpolicy_config, POOL_NAME, B_FALSE,
04937             B_FALSE },
04938         { zfs_ioc_pool_import, zfs_secpolicy_config, POOL_NAME, B_TRUE,
04939             B_FALSE },
04940         { zfs_ioc_pool_export, zfs_secpolicy_config, POOL_NAME, B_FALSE,
04941             B_FALSE },
04942         { zfs_ioc_pool_configs, zfs_secpolicy_none, NO_NAME, B_FALSE,
04943             B_FALSE },
04944         { zfs_ioc_pool_stats, zfs_secpolicy_read, POOL_NAME, B_FALSE,
04945             B_FALSE },
04946         { zfs_ioc_pool_tryimport, zfs_secpolicy_config, NO_NAME, B_FALSE,
04947             B_FALSE },
04948         { zfs_ioc_pool_scan, zfs_secpolicy_config, POOL_NAME, B_TRUE,
04949             B_TRUE },
04950         { zfs_ioc_pool_freeze, zfs_secpolicy_config, NO_NAME, B_FALSE,
04951             B_FALSE },
04952         { zfs_ioc_pool_upgrade, zfs_secpolicy_config, POOL_NAME, B_TRUE,
04953             B_TRUE },
04954         { zfs_ioc_pool_get_history, zfs_secpolicy_config, POOL_NAME, B_FALSE,
04955             B_FALSE },
04956         { zfs_ioc_vdev_add, zfs_secpolicy_config, POOL_NAME, B_TRUE,
04957             B_TRUE },
04958         { zfs_ioc_vdev_remove, zfs_secpolicy_config, POOL_NAME, B_TRUE,
04959             B_TRUE },
04960         { zfs_ioc_vdev_set_state, zfs_secpolicy_config, POOL_NAME, B_TRUE,
04961             B_FALSE },
04962         { zfs_ioc_vdev_attach, zfs_secpolicy_config, POOL_NAME, B_TRUE,
04963             B_TRUE },
04964         { zfs_ioc_vdev_detach, zfs_secpolicy_config, POOL_NAME, B_TRUE,
04965             B_TRUE },
04966         { zfs_ioc_vdev_setpath, zfs_secpolicy_config, POOL_NAME, B_FALSE,
04967             B_TRUE },
04968         { zfs_ioc_vdev_setfru,  zfs_secpolicy_config, POOL_NAME, B_FALSE,
04969             B_TRUE },
04970         { zfs_ioc_objset_stats, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
04971             B_TRUE },
04972         { zfs_ioc_objset_zplprops, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
04973             B_FALSE },
04974         { zfs_ioc_dataset_list_next, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
04975             B_TRUE },
04976         { zfs_ioc_snapshot_list_next, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
04977             B_TRUE },
04978         { zfs_ioc_set_prop, zfs_secpolicy_none, DATASET_NAME, B_TRUE, B_TRUE },
04979         { zfs_ioc_create, zfs_secpolicy_create, DATASET_NAME, B_TRUE, B_TRUE },
04980         { zfs_ioc_destroy, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE,
04981             B_TRUE},
04982         { zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME, B_TRUE,
04983             B_TRUE },
04984         { zfs_ioc_rename, zfs_secpolicy_rename, DATASET_NAME, B_TRUE, B_TRUE },
04985         { zfs_ioc_recv, zfs_secpolicy_receive, DATASET_NAME, B_TRUE, B_TRUE },
04986         { zfs_ioc_send, zfs_secpolicy_send, DATASET_NAME, B_FALSE, B_FALSE },
04987         { zfs_ioc_inject_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE,
04988             B_FALSE },
04989         { zfs_ioc_clear_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE,
04990             B_FALSE },
04991         { zfs_ioc_inject_list_next, zfs_secpolicy_inject, NO_NAME, B_FALSE,
04992             B_FALSE },
04993         { zfs_ioc_error_log, zfs_secpolicy_inject, POOL_NAME, B_FALSE,
04994             B_FALSE },
04995         { zfs_ioc_clear, zfs_secpolicy_config, POOL_NAME, B_TRUE, B_FALSE },
04996         { zfs_ioc_promote, zfs_secpolicy_promote, DATASET_NAME, B_TRUE,
04997             B_TRUE },
04998         { zfs_ioc_destroy_snaps_nvl, zfs_secpolicy_destroy_recursive, DATASET_NAME,
04999             B_TRUE, B_TRUE },
05000         { zfs_ioc_snapshot, zfs_secpolicy_snapshot, DATASET_NAME, B_TRUE,
05001             B_TRUE },
05002         { zfs_ioc_dsobj_to_dsname, zfs_secpolicy_diff, POOL_NAME, B_FALSE,
05003             B_FALSE },
05004         { zfs_ioc_obj_to_path, zfs_secpolicy_diff, DATASET_NAME, B_FALSE,
05005             B_TRUE },
05006         { zfs_ioc_pool_set_props, zfs_secpolicy_config, POOL_NAME, B_TRUE,
05007             B_TRUE },
05008         { zfs_ioc_pool_get_props, zfs_secpolicy_read, POOL_NAME, B_FALSE,
05009             B_FALSE },
05010         { zfs_ioc_set_fsacl, zfs_secpolicy_fsacl, DATASET_NAME, B_TRUE,
05011             B_TRUE },
05012         { zfs_ioc_get_fsacl, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
05013             B_FALSE },
05014         { zfs_ioc_share, zfs_secpolicy_share, DATASET_NAME, B_FALSE, B_FALSE },
05015         { zfs_ioc_inherit_prop, zfs_secpolicy_inherit, DATASET_NAME, B_TRUE,
05016             B_TRUE },
05017         { zfs_ioc_smb_acl, zfs_secpolicy_smb_acl, DATASET_NAME, B_FALSE,
05018             B_FALSE },
05019         { zfs_ioc_userspace_one, zfs_secpolicy_userspace_one,
05020             DATASET_NAME, B_FALSE, B_FALSE },
05021         { zfs_ioc_userspace_many, zfs_secpolicy_userspace_many,
05022             DATASET_NAME, B_FALSE, B_FALSE },
05023         { zfs_ioc_userspace_upgrade, zfs_secpolicy_userspace_upgrade,
05024             DATASET_NAME, B_FALSE, B_TRUE },
05025         { zfs_ioc_hold, zfs_secpolicy_hold, DATASET_NAME, B_TRUE, B_TRUE },
05026         { zfs_ioc_release, zfs_secpolicy_release, DATASET_NAME, B_TRUE,
05027             B_TRUE },
05028         { zfs_ioc_get_holds, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
05029             B_TRUE },
05030         { zfs_ioc_objset_recvd_props, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
05031             B_FALSE },
05032         { zfs_ioc_vdev_split, zfs_secpolicy_config, POOL_NAME, B_TRUE,
05033             B_TRUE },
05034         { zfs_ioc_next_obj, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
05035             B_FALSE },
05036         { zfs_ioc_diff, zfs_secpolicy_diff, DATASET_NAME, B_FALSE, B_FALSE },
05037         { zfs_ioc_tmp_snapshot, zfs_secpolicy_tmp_snapshot, DATASET_NAME,
05038             B_FALSE, B_FALSE },
05039         { zfs_ioc_obj_to_stats, zfs_secpolicy_diff, DATASET_NAME, B_FALSE,
05040             B_TRUE },
05041         { zfs_ioc_jail, zfs_secpolicy_config, DATASET_NAME, B_TRUE, B_FALSE },
05042         { zfs_ioc_unjail, zfs_secpolicy_config, DATASET_NAME, B_TRUE, B_FALSE },
05043         { zfs_ioc_pool_reguid, zfs_secpolicy_config, POOL_NAME, B_TRUE,
05044             B_TRUE },
05045         { zfs_ioc_space_written, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
05046             B_TRUE },
05047         { zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
05048             B_TRUE },
05049         { zfs_ioc_send_progress, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
05050             B_FALSE },
05051         { zfs_ioc_pool_reopen, zfs_secpolicy_config, POOL_NAME, B_TRUE,
05052             B_TRUE },
05053 };
05054 
05055 int
05056 pool_status_check(const char *name, zfs_ioc_namecheck_t type)
05057 {
05058         spa_t *spa;
05059         int error;
05060 
05061         ASSERT(type == POOL_NAME || type == DATASET_NAME);
05062 
05063         error = spa_open(name, &spa, FTAG);
05064         if (error == 0) {
05065                 if (spa_suspended(spa))
05066                         error = EAGAIN;
05067                 spa_close(spa, FTAG);
05068         }
05069         return (error);
05070 }
05071 
05075 minor_t
05076 zfsdev_minor_alloc(void)
05077 {
05078         static minor_t last_minor;
05079         minor_t m;
05080 
05081         ASSERT(MUTEX_HELD(&spa_namespace_lock));
05082 
05083         for (m = last_minor + 1; m != last_minor; m++) {
05084                 if (m > ZFSDEV_MAX_MINOR)
05085                         m = 1;
05086                 if (ddi_get_soft_state(zfsdev_state, m) == NULL) {
05087                         last_minor = m;
05088                         return (m);
05089                 }
05090         }
05091 
05092         return (0);
05093 }
05094 
05095 static int
05096 zfs_ctldev_init(struct cdev *devp)
05097 {
05098         minor_t minor;
05099         zfs_soft_state_t *zs;
05100 
05101         ASSERT(MUTEX_HELD(&spa_namespace_lock));
05102 
05103         minor = zfsdev_minor_alloc();
05104         if (minor == 0)
05105                 return (ENXIO);
05106 
05107         if (ddi_soft_state_zalloc(zfsdev_state, minor) != DDI_SUCCESS)
05108                 return (EAGAIN);
05109 
05110         devfs_set_cdevpriv((void *)(uintptr_t)minor, zfsdev_close);
05111 
05112         zs = ddi_get_soft_state(zfsdev_state, minor);
05113         zs->zss_type = ZSST_CTLDEV;
05114         zfs_onexit_init((zfs_onexit_t **)&zs->zss_data);
05115 
05116         return (0);
05117 }
05118 
05119 static void
05120 zfs_ctldev_destroy(zfs_onexit_t *zo, minor_t minor)
05121 {
05122         ASSERT(MUTEX_HELD(&spa_namespace_lock));
05123 
05124         zfs_onexit_destroy(zo);
05125         ddi_soft_state_free(zfsdev_state, minor);
05126 }
05127 
05128 void *
05129 zfsdev_get_soft_state(minor_t minor, enum zfs_soft_state_type which)
05130 {
05131         zfs_soft_state_t *zp;
05132 
05133         zp = ddi_get_soft_state(zfsdev_state, minor);
05134         if (zp == NULL || zp->zss_type != which)
05135                 return (NULL);
05136 
05137         return (zp->zss_data);
05138 }
05139 
05140 static int
05141 zfsdev_open(struct cdev *devp, int flag, int mode, struct thread *td)
05142 {
05143         int error = 0;
05144 
05145 #ifdef sun
05146         if (getminor(*devp) != 0)
05147                 return (zvol_open(devp, flag, otyp, cr));
05148 #endif
05149 
05150         /* This is the control device. Allocate a new minor if requested. */
05151         if (flag & FEXCL) {
05152                 mutex_enter(&spa_namespace_lock);
05153                 error = zfs_ctldev_init(devp);
05154                 mutex_exit(&spa_namespace_lock);
05155         }
05156 
05157         return (error);
05158 }
05159 
05160 static void
05161 zfsdev_close(void *data)
05162 {
05163         zfs_onexit_t *zo;
05164         minor_t minor = (minor_t)(uintptr_t)data;
05165 
05166         if (minor == 0)
05167                 return;
05168 
05169         mutex_enter(&spa_namespace_lock);
05170         zo = zfsdev_get_soft_state(minor, ZSST_CTLDEV);
05171         if (zo == NULL) {
05172                 mutex_exit(&spa_namespace_lock);
05173                 return;
05174         }
05175         zfs_ctldev_destroy(zo, minor);
05176         mutex_exit(&spa_namespace_lock);
05177 }
05178 
05179 static int
05180 zfsdev_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
05181     struct thread *td)
05182 {
05183         zfs_cmd_t *zc;
05184         uint_t vec;
05185         int cflag, error, len;
05186 
05187         cflag = ZFS_CMD_COMPAT_NONE;
05188         len = IOCPARM_LEN(cmd);
05189 
05190         /*
05191          * Check if we have sufficient kernel memory allocated
05192          * for the zfs_cmd_t request.  Bail out if not so we
05193          * will not access undefined memory region.
05194          */
05195         if (len < sizeof(zfs_cmd_t))
05196                 if (len == sizeof(zfs_cmd_v15_t)) {
05197                         cflag = ZFS_CMD_COMPAT_V15;
05198                         vec = zfs_ioctl_v15_to_v28[ZFS_IOC(cmd)];
05199                 } else
05200                         return (EINVAL);
05201         else
05202                 vec = ZFS_IOC(cmd);
05203 
05204         if (cflag != ZFS_CMD_COMPAT_NONE) {
05205                 if (vec == ZFS_IOC_COMPAT_PASS)
05206                         return (0);
05207                 else if (vec == ZFS_IOC_COMPAT_FAIL)
05208                         return (ENOTSUP);
05209         }
05210 
05211         if (vec >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
05212                 return (EINVAL);
05213 
05214         if (cflag != ZFS_CMD_COMPAT_NONE) {
05215                 zc = kmem_zalloc(sizeof(zfs_cmd_t), KM_SLEEP);
05216                 bzero(zc, sizeof(zfs_cmd_t));
05217                 zfs_cmd_compat_get(zc, addr, cflag);
05218                 zfs_ioctl_compat_pre(zc, &vec, cflag);
05219         } else {
05220                 zc = (void *)addr;
05221         }
05222 
05223         error = zfs_ioc_vec[vec].zvec_secpolicy(zc, td->td_ucred);
05224 
05225         /*
05226          * Ensure that all pool/dataset names are valid before we pass down to
05227          * the lower layers.
05228          */
05229         if (error == 0) {
05230                 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
05231                 zc->zc_iflags = flag & FKIOCTL;
05232                 switch (zfs_ioc_vec[vec].zvec_namecheck) {
05233                 case POOL_NAME:
05234                         if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
05235                                 error = EINVAL;
05236                         if (zfs_ioc_vec[vec].zvec_pool_check)
05237                                 error = pool_status_check(zc->zc_name,
05238                                     zfs_ioc_vec[vec].zvec_namecheck);
05239                         break;
05240 
05241                 case DATASET_NAME:
05242                         if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
05243                                 error = EINVAL;
05244                         if (zfs_ioc_vec[vec].zvec_pool_check)
05245                                 error = pool_status_check(zc->zc_name,
05246                                     zfs_ioc_vec[vec].zvec_namecheck);
05247                         break;
05248 
05249                 case NO_NAME:
05250                         break;
05251                 }
05252         }
05253 
05254         if (error == 0)
05255                 error = zfs_ioc_vec[vec].zvec_func(zc);
05256 
05257         if (error == 0) {
05258                 if (zfs_ioc_vec[vec].zvec_his_log)
05259                         zfs_log_history(zc);
05260         }
05261 
05262         if (cflag != ZFS_CMD_COMPAT_NONE) {
05263                 zfs_ioctl_compat_post(zc, ZFS_IOC(cmd), cflag);
05264                 zfs_cmd_compat_put(zc, addr, cflag);
05265                 kmem_free(zc, sizeof(zfs_cmd_t));
05266         }
05267 
05268         return (error);
05269 }
05270 
05271 #ifdef sun
05272 static int
05273 zfs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
05274 {
05275         if (cmd != DDI_ATTACH)
05276                 return (DDI_FAILURE);
05277 
05278         if (ddi_create_minor_node(dip, "zfs", S_IFCHR, 0,
05279             DDI_PSEUDO, 0) == DDI_FAILURE)
05280                 return (DDI_FAILURE);
05281 
05282         zfs_dip = dip;
05283 
05284         ddi_report_dev(dip);
05285 
05286         return (DDI_SUCCESS);
05287 }
05288 
05289 static int
05290 zfs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
05291 {
05292         if (spa_busy() || zfs_busy() || zvol_busy())
05293                 return (DDI_FAILURE);
05294 
05295         if (cmd != DDI_DETACH)
05296                 return (DDI_FAILURE);
05297 
05298         zfs_dip = NULL;
05299 
05300         ddi_prop_remove_all(dip);
05301         ddi_remove_minor_node(dip, NULL);
05302 
05303         return (DDI_SUCCESS);
05304 }
05305 
05306 /*ARGSUSED*/
05307 static int
05308 zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
05309 {
05310         switch (infocmd) {
05311         case DDI_INFO_DEVT2DEVINFO:
05312                 *result = zfs_dip;
05313                 return (DDI_SUCCESS);
05314 
05315         case DDI_INFO_DEVT2INSTANCE:
05316                 *result = (void *)0;
05317                 return (DDI_SUCCESS);
05318         }
05319 
05320         return (DDI_FAILURE);
05321 }
05322 #endif  /* sun */
05323 
05324 /*
05325  * OK, so this is a little weird.
05326  *
05327  * /dev/zfs is the control node, i.e. minor 0.
05328  * /dev/zvol/[r]dsk/pool/dataset are the zvols, minor > 0.
05329  *
05330  * /dev/zfs has basically nothing to do except serve up ioctls,
05331  * so most of the standard driver entry points are in zvol.c.
05332  */
05333 #ifdef sun
05334 static struct cb_ops zfs_cb_ops = {
05335         zfsdev_open,    
05336         zfsdev_close,   
05337         zvol_strategy,  
05338         nodev,          
05339         zvol_dump,      
05340         zvol_read,      
05341         zvol_write,     
05342         zfsdev_ioctl,   
05343         nodev,          
05344         nodev,          
05345         nodev,          
05346         nochpoll,       
05347         ddi_prop_op,    
05348         NULL,           
05349         D_NEW | D_MP | D_64BIT,         
05350         CB_REV,         
05351         nodev,          
05352         nodev,          
05353 };
05354 
05355 static struct dev_ops zfs_dev_ops = {
05356         DEVO_REV,       
05357         0,              
05358         zfs_info,       
05359         nulldev,        
05360         nulldev,        
05361         zfs_attach,     
05362         zfs_detach,     
05363         nodev,          
05364         &zfs_cb_ops,    
05365         NULL,           
05366         NULL,           
05367         ddi_quiesce_not_needed, 
05368 };
05369 
05370 static struct modldrv zfs_modldrv = {
05371         &mod_driverops,
05372         "ZFS storage pool",
05373         &zfs_dev_ops
05374 };
05375 
05376 static struct modlinkage modlinkage = {
05377         MODREV_1,
05378         (void *)&zfs_modlfs,
05379         (void *)&zfs_modldrv,
05380         NULL
05381 };
05382 #endif  /* sun */
05383 
05384 static struct cdevsw zfs_cdevsw = {
05385         .d_version =    D_VERSION,
05386         .d_open =       zfsdev_open,
05387         .d_ioctl =      zfsdev_ioctl,
05388         .d_name =       ZFS_DEV_NAME
05389 };
05390 
05391 static void
05392 zfsdev_init(void)
05393 {
05394         zfsdev = make_dev(&zfs_cdevsw, 0x0, UID_ROOT, GID_OPERATOR, 0666,
05395             ZFS_DEV_NAME);
05396 }
05397 
05398 static void
05399 zfsdev_fini(void)
05400 {
05401         if (zfsdev != NULL)
05402                 destroy_dev(zfsdev);
05403 }
05404 
05405 static struct root_hold_token *zfs_root_token;
05406 struct proc *zfsproc;
05407 
05408 uint_t zfs_fsyncer_key;
05409 extern uint_t rrw_tsd_key;
05410 
05411 #ifdef sun
05412 int
05413 _init(void)
05414 {
05415         int error;
05416 
05417         spa_init(FREAD | FWRITE);
05418         zfs_init();
05419         zvol_init();
05420 
05421         if ((error = mod_install(&modlinkage)) != 0) {
05422                 zvol_fini();
05423                 zfs_fini();
05424                 spa_fini();
05425                 return (error);
05426         }
05427 
05428         tsd_create(&zfs_fsyncer_key, NULL);
05429         tsd_create(&rrw_tsd_key, NULL);
05430 
05431         error = ldi_ident_from_mod(&modlinkage, &zfs_li);
05432         ASSERT(error == 0);
05433         mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
05434 
05435         return (0);
05436 }
05437 
05438 int
05439 _fini(void)
05440 {
05441         int error;
05442 
05443         if (spa_busy() || zfs_busy() || zvol_busy() || zio_injection_enabled)
05444                 return (EBUSY);
05445 
05446         if ((error = mod_remove(&modlinkage)) != 0)
05447                 return (error);
05448 
05449         zvol_fini();
05450         zfs_fini();
05451         spa_fini();
05452         if (zfs_nfsshare_inited)
05453                 (void) ddi_modclose(nfs_mod);
05454         if (zfs_smbshare_inited)
05455                 (void) ddi_modclose(smbsrv_mod);
05456         if (zfs_nfsshare_inited || zfs_smbshare_inited)
05457                 (void) ddi_modclose(sharefs_mod);
05458 
05459         tsd_destroy(&zfs_fsyncer_key);
05460         ldi_ident_release(zfs_li);
05461         zfs_li = NULL;
05462         mutex_destroy(&zfs_share_lock);
05463 
05464         return (error);
05465 }
05466 
05467 int
05468 _info(struct modinfo *modinfop)
05469 {
05470         return (mod_info(&modlinkage, modinfop));
05471 }
05472 #endif  /* sun */
05473 
05474 static int
05475 zfs_modevent(module_t mod, int type, void *unused __unused)
05476 {
05477         int error = 0;
05478 
05479         switch (type) {
05480         case MOD_LOAD:
05481                 zfs_root_token = root_mount_hold("ZFS");
05482 
05483                 mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
05484 
05485                 spa_init(FREAD | FWRITE);
05486                 zfs_init();
05487                 zvol_init();
05488 
05489                 tsd_create(&zfs_fsyncer_key, NULL);
05490                 tsd_create(&rrw_tsd_key, NULL);
05491 
05492                 printf("ZFS storage pool version: features support (" SPA_VERSION_STRING ")\n");
05493                 root_mount_rel(zfs_root_token);
05494 
05495                 zfsdev_init();
05496                 break;
05497         case MOD_UNLOAD:
05498                 if (spa_busy() || zfs_busy() || zvol_busy() ||
05499                     zio_injection_enabled) {
05500                         error = EBUSY;
05501                         break;
05502                 }
05503 
05504                 zfsdev_fini();
05505                 zvol_fini();
05506                 zfs_fini();
05507                 spa_fini();
05508 
05509                 tsd_destroy(&zfs_fsyncer_key);
05510                 tsd_destroy(&rrw_tsd_key);
05511 
05512                 mutex_destroy(&zfs_share_lock);
05513                 break;
05514         default:
05515                 error = EOPNOTSUPP;
05516                 break;
05517         }
05518         return (error);
05519 }
05520 
05521 static moduledata_t zfs_mod = {
05522         "zfsctrl",
05523         zfs_modevent,
05524         0
05525 };
05526 DECLARE_MODULE(zfsctrl, zfs_mod, SI_SUB_VFS, SI_ORDER_ANY);
05527 MODULE_DEPEND(zfsctrl, opensolaris, 1, 1, 1);
05528 MODULE_DEPEND(zfsctrl, krpc, 1, 1, 1);
05529 MODULE_DEPEND(zfsctrl, acl_nfs4, 1, 1, 1);
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines