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