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