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