]> git.proxmox.com Git - mirror_zfs.git/blame - module/zfs/zfs_ioctl.c
Illumos 3835 zfs need not store 2 copies of all metadata
[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.
34dc7c2f 4241 *
da536844
MA
4242 * outputs:
4243 * zc_objset_type estimated size, if zc_guid is set
34dc7c2f
BB
4244 */
4245static int
4246zfs_ioc_send(zfs_cmd_t *zc)
4247{
34dc7c2f
BB
4248 int error;
4249 offset_t off;
330d06f9 4250 boolean_t estimate = (zc->zc_guid != 0);
34dc7c2f 4251
13fe0198
MA
4252 if (zc->zc_obj != 0) {
4253 dsl_pool_t *dp;
4254 dsl_dataset_t *tosnap;
34dc7c2f 4255
13fe0198
MA
4256 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
4257 if (error != 0)
572e2857 4258 return (error);
13fe0198
MA
4259
4260 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
4261 if (error != 0) {
4262 dsl_pool_rele(dp, FTAG);
34dc7c2f
BB
4263 return (error);
4264 }
13fe0198
MA
4265
4266 if (dsl_dir_is_clone(tosnap->ds_dir))
4267 zc->zc_fromobj = tosnap->ds_dir->dd_phys->dd_origin_obj;
4268 dsl_dataset_rele(tosnap, FTAG);
4269 dsl_pool_rele(dp, FTAG);
6f1ffb06
MA
4270 }
4271
13fe0198
MA
4272 if (estimate) {
4273 dsl_pool_t *dp;
4274 dsl_dataset_t *tosnap;
4275 dsl_dataset_t *fromsnap = NULL;
4276
4277 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
4278 if (error != 0)
4279 return (error);
6f1ffb06 4280
13fe0198
MA
4281 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
4282 if (error != 0) {
4283 dsl_pool_rele(dp, FTAG);
4284 return (error);
6f1ffb06
MA
4285 }
4286
13fe0198
MA
4287 if (zc->zc_fromobj != 0) {
4288 error = dsl_dataset_hold_obj(dp, zc->zc_fromobj,
4289 FTAG, &fromsnap);
4290 if (error != 0) {
4291 dsl_dataset_rele(tosnap, FTAG);
4292 dsl_pool_rele(dp, FTAG);
6f1ffb06
MA
4293 return (error);
4294 }
4295 }
34dc7c2f 4296
6f1ffb06 4297 error = dmu_send_estimate(tosnap, fromsnap,
330d06f9 4298 &zc->zc_objset_type);
13fe0198
MA
4299
4300 if (fromsnap != NULL)
4301 dsl_dataset_rele(fromsnap, FTAG);
4302 dsl_dataset_rele(tosnap, FTAG);
4303 dsl_pool_rele(dp, FTAG);
330d06f9
MA
4304 } else {
4305 file_t *fp = getf(zc->zc_cookie);
13fe0198 4306 if (fp == NULL)
2e528b49 4307 return (SET_ERROR(EBADF));
34dc7c2f 4308
330d06f9 4309 off = fp->f_offset;
13fe0198
MA
4310 error = dmu_send_obj(zc->zc_name, zc->zc_sendobj,
4311 zc->zc_fromobj, zc->zc_cookie, fp->f_vnode, &off);
34dc7c2f 4312
330d06f9
MA
4313 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4314 fp->f_offset = off;
4315 releasef(zc->zc_cookie);
4316 }
34dc7c2f
BB
4317 return (error);
4318}
4319
37abac6d
BP
4320/*
4321 * inputs:
4322 * zc_name name of snapshot on which to report progress
4323 * zc_cookie file descriptor of send stream
4324 *
4325 * outputs:
4326 * zc_cookie number of bytes written in send stream thus far
4327 */
4328static int
4329zfs_ioc_send_progress(zfs_cmd_t *zc)
4330{
13fe0198 4331 dsl_pool_t *dp;
37abac6d
BP
4332 dsl_dataset_t *ds;
4333 dmu_sendarg_t *dsp = NULL;
4334 int error;
4335
13fe0198
MA
4336 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
4337 if (error != 0)
37abac6d
BP
4338 return (error);
4339
13fe0198
MA
4340 error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &ds);
4341 if (error != 0) {
4342 dsl_pool_rele(dp, FTAG);
4343 return (error);
4344 }
4345
37abac6d
BP
4346 mutex_enter(&ds->ds_sendstream_lock);
4347
4348 /*
4349 * Iterate over all the send streams currently active on this dataset.
4350 * If there's one which matches the specified file descriptor _and_ the
4351 * stream was started by the current process, return the progress of
4352 * that stream.
4353 */
4354
4355 for (dsp = list_head(&ds->ds_sendstreams); dsp != NULL;
4356 dsp = list_next(&ds->ds_sendstreams, dsp)) {
4357 if (dsp->dsa_outfd == zc->zc_cookie &&
4358 dsp->dsa_proc->group_leader == curproc->group_leader)
4359 break;
4360 }
4361
4362 if (dsp != NULL)
4363 zc->zc_cookie = *(dsp->dsa_off);
4364 else
2e528b49 4365 error = SET_ERROR(ENOENT);
37abac6d
BP
4366
4367 mutex_exit(&ds->ds_sendstream_lock);
4368 dsl_dataset_rele(ds, FTAG);
13fe0198 4369 dsl_pool_rele(dp, FTAG);
37abac6d
BP
4370 return (error);
4371}
4372
34dc7c2f
BB
4373static int
4374zfs_ioc_inject_fault(zfs_cmd_t *zc)
4375{
4376 int id, error;
4377
4378 error = zio_inject_fault(zc->zc_name, (int)zc->zc_guid, &id,
4379 &zc->zc_inject_record);
4380
4381 if (error == 0)
4382 zc->zc_guid = (uint64_t)id;
4383
4384 return (error);
4385}
4386
4387static int
4388zfs_ioc_clear_fault(zfs_cmd_t *zc)
4389{
4390 return (zio_clear_fault((int)zc->zc_guid));
4391}
4392
4393static int
4394zfs_ioc_inject_list_next(zfs_cmd_t *zc)
4395{
4396 int id = (int)zc->zc_guid;
4397 int error;
4398
4399 error = zio_inject_list_next(&id, zc->zc_name, sizeof (zc->zc_name),
4400 &zc->zc_inject_record);
4401
4402 zc->zc_guid = id;
4403
4404 return (error);
4405}
4406
4407static int
4408zfs_ioc_error_log(zfs_cmd_t *zc)
4409{
4410 spa_t *spa;
4411 int error;
4412 size_t count = (size_t)zc->zc_nvlist_dst_size;
4413
4414 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
4415 return (error);
4416
4417 error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst,
4418 &count);
4419 if (error == 0)
4420 zc->zc_nvlist_dst_size = count;
4421 else
4422 zc->zc_nvlist_dst_size = spa_get_errlog_size(spa);
4423
4424 spa_close(spa, FTAG);
4425
4426 return (error);
4427}
4428
4429static int
4430zfs_ioc_clear(zfs_cmd_t *zc)
4431{
4432 spa_t *spa;
4433 vdev_t *vd;
34dc7c2f
BB
4434 int error;
4435
34dc7c2f 4436 /*
b128c09f 4437 * On zpool clear we also fix up missing slogs
34dc7c2f 4438 */
b128c09f
BB
4439 mutex_enter(&spa_namespace_lock);
4440 spa = spa_lookup(zc->zc_name);
4441 if (spa == NULL) {
4442 mutex_exit(&spa_namespace_lock);
2e528b49 4443 return (SET_ERROR(EIO));
b128c09f 4444 }
428870ff 4445 if (spa_get_log_state(spa) == SPA_LOG_MISSING) {
b128c09f 4446 /* we need to let spa_open/spa_load clear the chains */
428870ff 4447 spa_set_log_state(spa, SPA_LOG_CLEAR);
34dc7c2f 4448 }
428870ff 4449 spa->spa_last_open_failed = 0;
b128c09f 4450 mutex_exit(&spa_namespace_lock);
34dc7c2f 4451
428870ff
BB
4452 if (zc->zc_cookie & ZPOOL_NO_REWIND) {
4453 error = spa_open(zc->zc_name, &spa, FTAG);
4454 } else {
4455 nvlist_t *policy;
4456 nvlist_t *config = NULL;
4457
b8864a23 4458 if (zc->zc_nvlist_src == 0)
2e528b49 4459 return (SET_ERROR(EINVAL));
428870ff
BB
4460
4461 if ((error = get_nvlist(zc->zc_nvlist_src,
4462 zc->zc_nvlist_src_size, zc->zc_iflags, &policy)) == 0) {
4463 error = spa_open_rewind(zc->zc_name, &spa, FTAG,
4464 policy, &config);
4465 if (config != NULL) {
572e2857
BB
4466 int err;
4467
4468 if ((err = put_nvlist(zc, config)) != 0)
4469 error = err;
428870ff
BB
4470 nvlist_free(config);
4471 }
4472 nvlist_free(policy);
4473 }
4474 }
4475
13fe0198 4476 if (error != 0)
b128c09f
BB
4477 return (error);
4478
428870ff 4479 spa_vdev_state_enter(spa, SCL_NONE);
34dc7c2f
BB
4480
4481 if (zc->zc_guid == 0) {
4482 vd = NULL;
b128c09f
BB
4483 } else {
4484 vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE);
34dc7c2f 4485 if (vd == NULL) {
b128c09f 4486 (void) spa_vdev_state_exit(spa, NULL, ENODEV);
34dc7c2f 4487 spa_close(spa, FTAG);
2e528b49 4488 return (SET_ERROR(ENODEV));
34dc7c2f
BB
4489 }
4490 }
4491
b128c09f
BB
4492 vdev_clear(spa, vd);
4493
4494 (void) spa_vdev_state_exit(spa, NULL, 0);
34dc7c2f 4495
b128c09f
BB
4496 /*
4497 * Resume any suspended I/Os.
4498 */
9babb374 4499 if (zio_resume(spa) != 0)
2e528b49 4500 error = SET_ERROR(EIO);
34dc7c2f
BB
4501
4502 spa_close(spa, FTAG);
4503
9babb374 4504 return (error);
34dc7c2f
BB
4505}
4506
1bd201e7
CS
4507static int
4508zfs_ioc_pool_reopen(zfs_cmd_t *zc)
4509{
4510 spa_t *spa;
4511 int error;
4512
4513 error = spa_open(zc->zc_name, &spa, FTAG);
13fe0198 4514 if (error != 0)
1bd201e7
CS
4515 return (error);
4516
4517 spa_vdev_state_enter(spa, SCL_NONE);
65947351
GW
4518
4519 /*
4520 * If a resilver is already in progress then set the
4521 * spa_scrub_reopen flag to B_TRUE so that we don't restart
4522 * the scan as a side effect of the reopen. Otherwise, let
4523 * vdev_open() decided if a resilver is required.
4524 */
4525 spa->spa_scrub_reopen = dsl_scan_resilvering(spa->spa_dsl_pool);
1bd201e7 4526 vdev_reopen(spa->spa_root_vdev);
65947351
GW
4527 spa->spa_scrub_reopen = B_FALSE;
4528
1bd201e7
CS
4529 (void) spa_vdev_state_exit(spa, NULL, 0);
4530 spa_close(spa, FTAG);
4531 return (0);
4532}
34dc7c2f
BB
4533/*
4534 * inputs:
4535 * zc_name name of filesystem
4536 * zc_value name of origin snapshot
4537 *
428870ff
BB
4538 * outputs:
4539 * zc_string name of conflicting snapshot, if there is one
34dc7c2f
BB
4540 */
4541static int
4542zfs_ioc_promote(zfs_cmd_t *zc)
4543{
4544 char *cp;
4545
4546 /*
4547 * We don't need to unmount *all* the origin fs's snapshots, but
4548 * it's easier.
4549 */
4550 cp = strchr(zc->zc_value, '@');
4551 if (cp)
4552 *cp = '\0';
4553 (void) dmu_objset_find(zc->zc_value,
13fe0198 4554 zfs_unmount_snap_cb, NULL, DS_FIND_SNAPSHOTS);
428870ff 4555 return (dsl_dataset_promote(zc->zc_name, zc->zc_string));
34dc7c2f
BB
4556}
4557
9babb374
BB
4558/*
4559 * Retrieve a single {user|group}{used|quota}@... property.
4560 *
4561 * inputs:
4562 * zc_name name of filesystem
4563 * zc_objset_type zfs_userquota_prop_t
4564 * zc_value domain name (eg. "S-1-234-567-89")
4565 * zc_guid RID/UID/GID
4566 *
4567 * outputs:
4568 * zc_cookie property value
4569 */
4570static int
4571zfs_ioc_userspace_one(zfs_cmd_t *zc)
4572{
3558fd73 4573 zfs_sb_t *zsb;
9babb374
BB
4574 int error;
4575
4576 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
2e528b49 4577 return (SET_ERROR(EINVAL));
9babb374 4578
3558fd73 4579 error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
13fe0198 4580 if (error != 0)
9babb374
BB
4581 return (error);
4582
3558fd73 4583 error = zfs_userspace_one(zsb,
9babb374 4584 zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie);
3558fd73 4585 zfs_sb_rele(zsb, FTAG);
9babb374
BB
4586
4587 return (error);
4588}
4589
4590/*
4591 * inputs:
4592 * zc_name name of filesystem
4593 * zc_cookie zap cursor
4594 * zc_objset_type zfs_userquota_prop_t
4595 * zc_nvlist_dst[_size] buffer to fill (not really an nvlist)
4596 *
4597 * outputs:
4598 * zc_nvlist_dst[_size] data buffer (array of zfs_useracct_t)
4599 * zc_cookie zap cursor
4600 */
4601static int
4602zfs_ioc_userspace_many(zfs_cmd_t *zc)
4603{
3558fd73 4604 zfs_sb_t *zsb;
428870ff 4605 int bufsize = zc->zc_nvlist_dst_size;
3558fd73
BB
4606 int error;
4607 void *buf;
428870ff
BB
4608
4609 if (bufsize <= 0)
2e528b49 4610 return (SET_ERROR(ENOMEM));
9babb374 4611
3558fd73 4612 error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
13fe0198 4613 if (error != 0)
9babb374
BB
4614 return (error);
4615
2b8cad61 4616 buf = vmem_alloc(bufsize, KM_SLEEP);
9babb374 4617
3558fd73 4618 error = zfs_userspace_many(zsb, zc->zc_objset_type, &zc->zc_cookie,
9babb374
BB
4619 buf, &zc->zc_nvlist_dst_size);
4620
4621 if (error == 0) {
4622 error = xcopyout(buf,
4623 (void *)(uintptr_t)zc->zc_nvlist_dst,
4624 zc->zc_nvlist_dst_size);
4625 }
2b8cad61 4626 vmem_free(buf, bufsize);
3558fd73 4627 zfs_sb_rele(zsb, FTAG);
9babb374
BB
4628
4629 return (error);
4630}
4631
4632/*
4633 * inputs:
4634 * zc_name name of filesystem
4635 *
4636 * outputs:
4637 * none
4638 */
4639static int
4640zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
4641{
4642 objset_t *os;
428870ff 4643 int error = 0;
3558fd73 4644 zfs_sb_t *zsb;
9babb374 4645
3558fd73
BB
4646 if (get_zfs_sb(zc->zc_name, &zsb) == 0) {
4647 if (!dmu_objset_userused_enabled(zsb->z_os)) {
9babb374
BB
4648 /*
4649 * If userused is not enabled, it may be because the
4650 * objset needs to be closed & reopened (to grow the
4651 * objset_phys_t). Suspend/resume the fs will do that.
4652 */
3558fd73 4653 error = zfs_suspend_fs(zsb);
831baf06
KW
4654 if (error == 0) {
4655 dmu_objset_refresh_ownership(zsb->z_os,
4656 zsb);
3558fd73 4657 error = zfs_resume_fs(zsb, zc->zc_name);
831baf06 4658 }
9babb374
BB
4659 }
4660 if (error == 0)
3558fd73 4661 error = dmu_objset_userspace_upgrade(zsb->z_os);
2cf7f52b 4662 deactivate_super(zsb->z_sb);
9babb374 4663 } else {
428870ff
BB
4664 /* XXX kind of reading contents without owning */
4665 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
13fe0198 4666 if (error != 0)
9babb374
BB
4667 return (error);
4668
4669 error = dmu_objset_userspace_upgrade(os);
428870ff 4670 dmu_objset_rele(os, FTAG);
9babb374
BB
4671 }
4672
4673 return (error);
4674}
4675
34dc7c2f
BB
4676static int
4677zfs_ioc_share(zfs_cmd_t *zc)
4678{
2e528b49 4679 return (SET_ERROR(ENOSYS));
34dc7c2f
BB
4680}
4681
9babb374
BB
4682ace_t full_access[] = {
4683 {(uid_t)-1, ACE_ALL_PERMS, ACE_EVERYONE, 0}
4684};
4685
572e2857
BB
4686/*
4687 * inputs:
4688 * zc_name name of containing filesystem
4689 * zc_obj object # beyond which we want next in-use object #
4690 *
4691 * outputs:
4692 * zc_obj next in-use object #
4693 */
4694static int
4695zfs_ioc_next_obj(zfs_cmd_t *zc)
4696{
4697 objset_t *os = NULL;
4698 int error;
4699
4700 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
13fe0198 4701 if (error != 0)
572e2857
BB
4702 return (error);
4703
4704 error = dmu_object_next(os, &zc->zc_obj, B_FALSE,
4705 os->os_dsl_dataset->ds_phys->ds_prev_snap_txg);
4706
4707 dmu_objset_rele(os, FTAG);
4708 return (error);
4709}
4710
4711/*
4712 * inputs:
4713 * zc_name name of filesystem
4714 * zc_value prefix name for snapshot
4715 * zc_cleanup_fd cleanup-on-exit file descriptor for calling process
4716 *
4717 * outputs:
6f1ffb06 4718 * zc_value short name of new snapshot
572e2857
BB
4719 */
4720static int
4721zfs_ioc_tmp_snapshot(zfs_cmd_t *zc)
4722{
4723 char *snap_name;
13fe0198 4724 char *hold_name;
572e2857 4725 int error;
13fe0198 4726 minor_t minor;
572e2857 4727
13fe0198
MA
4728 error = zfs_onexit_fd_hold(zc->zc_cleanup_fd, &minor);
4729 if (error != 0)
572e2857 4730 return (error);
572e2857 4731
13fe0198
MA
4732 snap_name = kmem_asprintf("%s-%016llx", zc->zc_value,
4733 (u_longlong_t)ddi_get_lbolt64());
4734 hold_name = kmem_asprintf("%%%s", zc->zc_value);
4735
4736 error = dsl_dataset_snapshot_tmp(zc->zc_name, snap_name, minor,
4737 hold_name);
4738 if (error == 0)
4739 (void) strcpy(zc->zc_value, snap_name);
572e2857 4740 strfree(snap_name);
13fe0198
MA
4741 strfree(hold_name);
4742 zfs_onexit_fd_rele(zc->zc_cleanup_fd);
4743 return (error);
572e2857
BB
4744}
4745
4746/*
4747 * inputs:
4748 * zc_name name of "to" snapshot
4749 * zc_value name of "from" snapshot
4750 * zc_cookie file descriptor to write diff data on
4751 *
4752 * outputs:
4753 * dmu_diff_record_t's to the file descriptor
4754 */
4755static int
4756zfs_ioc_diff(zfs_cmd_t *zc)
4757{
572e2857
BB
4758 file_t *fp;
4759 offset_t off;
4760 int error;
4761
572e2857 4762 fp = getf(zc->zc_cookie);
13fe0198 4763 if (fp == NULL)
2e528b49 4764 return (SET_ERROR(EBADF));
572e2857
BB
4765
4766 off = fp->f_offset;
4767
13fe0198 4768 error = dmu_diff(zc->zc_name, zc->zc_value, fp->f_vnode, &off);
572e2857
BB
4769
4770 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4771 fp->f_offset = off;
4772 releasef(zc->zc_cookie);
4773
572e2857
BB
4774 return (error);
4775}
4776
9babb374
BB
4777/*
4778 * Remove all ACL files in shares dir
4779 */
3c9609b3 4780#ifdef HAVE_SMB_SHARE
9babb374
BB
4781static int
4782zfs_smb_acl_purge(znode_t *dzp)
4783{
4784 zap_cursor_t zc;
4785 zap_attribute_t zap;
3558fd73 4786 zfs_sb_t *zsb = ZTOZSB(dzp);
9babb374
BB
4787 int error;
4788
3558fd73 4789 for (zap_cursor_init(&zc, zsb->z_os, dzp->z_id);
9babb374
BB
4790 (error = zap_cursor_retrieve(&zc, &zap)) == 0;
4791 zap_cursor_advance(&zc)) {
4792 if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred,
4793 NULL, 0)) != 0)
4794 break;
4795 }
4796 zap_cursor_fini(&zc);
4797 return (error);
4798}
3c9609b3 4799#endif /* HAVE_SMB_SHARE */
9babb374
BB
4800
4801static int
4802zfs_ioc_smb_acl(zfs_cmd_t *zc)
4803{
3c9609b3 4804#ifdef HAVE_SMB_SHARE
9babb374
BB
4805 vnode_t *vp;
4806 znode_t *dzp;
4807 vnode_t *resourcevp = NULL;
4808 znode_t *sharedir;
3558fd73 4809 zfs_sb_t *zsb;
9babb374
BB
4810 nvlist_t *nvlist;
4811 char *src, *target;
4812 vattr_t vattr;
4813 vsecattr_t vsec;
4814 int error = 0;
4815
4816 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
4817 NO_FOLLOW, NULL, &vp)) != 0)
4818 return (error);
4819
4820 /* Now make sure mntpnt and dataset are ZFS */
4821
4822 if (vp->v_vfsp->vfs_fstype != zfsfstype ||
4823 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
4824 zc->zc_name) != 0)) {
4825 VN_RELE(vp);
2e528b49 4826 return (SET_ERROR(EINVAL));
9babb374
BB
4827 }
4828
4829 dzp = VTOZ(vp);
3558fd73
BB
4830 zsb = ZTOZSB(dzp);
4831 ZFS_ENTER(zsb);
9babb374
BB
4832
4833 /*
4834 * Create share dir if its missing.
4835 */
3558fd73
BB
4836 mutex_enter(&zsb->z_lock);
4837 if (zsb->z_shares_dir == 0) {
9babb374
BB
4838 dmu_tx_t *tx;
4839
3558fd73 4840 tx = dmu_tx_create(zsb->z_os);
9babb374
BB
4841 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE,
4842 ZFS_SHARES_DIR);
4843 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
4844 error = dmu_tx_assign(tx, TXG_WAIT);
13fe0198 4845 if (error != 0) {
9babb374
BB
4846 dmu_tx_abort(tx);
4847 } else {
3558fd73 4848 error = zfs_create_share_dir(zsb, tx);
9babb374
BB
4849 dmu_tx_commit(tx);
4850 }
13fe0198 4851 if (error != 0) {
3558fd73 4852 mutex_exit(&zsb->z_lock);
9babb374 4853 VN_RELE(vp);
3558fd73 4854 ZFS_EXIT(zsb);
9babb374
BB
4855 return (error);
4856 }
4857 }
3558fd73 4858 mutex_exit(&zsb->z_lock);
9babb374 4859
3558fd73
BB
4860 ASSERT(zsb->z_shares_dir);
4861 if ((error = zfs_zget(zsb, zsb->z_shares_dir, &sharedir)) != 0) {
9babb374 4862 VN_RELE(vp);
3558fd73 4863 ZFS_EXIT(zsb);
9babb374
BB
4864 return (error);
4865 }
4866
4867 switch (zc->zc_cookie) {
4868 case ZFS_SMB_ACL_ADD:
4869 vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
9babb374
BB
4870 vattr.va_mode = S_IFREG|0777;
4871 vattr.va_uid = 0;
4872 vattr.va_gid = 0;
4873
4874 vsec.vsa_mask = VSA_ACE;
4875 vsec.vsa_aclentp = &full_access;
4876 vsec.vsa_aclentsz = sizeof (full_access);
4877 vsec.vsa_aclcnt = 1;
4878
4879 error = VOP_CREATE(ZTOV(sharedir), zc->zc_string,
4880 &vattr, EXCL, 0, &resourcevp, kcred, 0, NULL, &vsec);
4881 if (resourcevp)
4882 VN_RELE(resourcevp);
4883 break;
4884
4885 case ZFS_SMB_ACL_REMOVE:
4886 error = VOP_REMOVE(ZTOV(sharedir), zc->zc_string, kcred,
4887 NULL, 0);
4888 break;
4889
4890 case ZFS_SMB_ACL_RENAME:
4891 if ((error = get_nvlist(zc->zc_nvlist_src,
4892 zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) {
4893 VN_RELE(vp);
3558fd73 4894 ZFS_EXIT(zsb);
9babb374
BB
4895 return (error);
4896 }
4897 if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
4898 nvlist_lookup_string(nvlist, ZFS_SMB_ACL_TARGET,
4899 &target)) {
4900 VN_RELE(vp);
4901 VN_RELE(ZTOV(sharedir));
3558fd73 4902 ZFS_EXIT(zsb);
428870ff 4903 nvlist_free(nvlist);
9babb374
BB
4904 return (error);
4905 }
4906 error = VOP_RENAME(ZTOV(sharedir), src, ZTOV(sharedir), target,
4907 kcred, NULL, 0);
4908 nvlist_free(nvlist);
4909 break;
4910
4911 case ZFS_SMB_ACL_PURGE:
4912 error = zfs_smb_acl_purge(sharedir);
4913 break;
4914
4915 default:
2e528b49 4916 error = SET_ERROR(EINVAL);
9babb374
BB
4917 break;
4918 }
4919
4920 VN_RELE(vp);
4921 VN_RELE(ZTOV(sharedir));
4922
3558fd73 4923 ZFS_EXIT(zsb);
9babb374
BB
4924
4925 return (error);
325f0235 4926#else
2e528b49 4927 return (SET_ERROR(ENOTSUP));
3c9609b3 4928#endif /* HAVE_SMB_SHARE */
9babb374
BB
4929}
4930
45d1cae3 4931/*
13fe0198
MA
4932 * innvl: {
4933 * "holds" -> { snapname -> holdname (string), ... }
4934 * (optional) "cleanup_fd" -> fd (int32)
4935 * }
45d1cae3 4936 *
13fe0198
MA
4937 * outnvl: {
4938 * snapname -> error value (int32)
4939 * ...
4940 * }
45d1cae3 4941 */
13fe0198 4942/* ARGSUSED */
45d1cae3 4943static int
13fe0198 4944zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
45d1cae3 4945{
13fe0198
MA
4946 nvlist_t *holds;
4947 int cleanup_fd = -1;
572e2857
BB
4948 int error;
4949 minor_t minor = 0;
45d1cae3 4950
13fe0198
MA
4951 error = nvlist_lookup_nvlist(args, "holds", &holds);
4952 if (error != 0)
2e528b49 4953 return (SET_ERROR(EINVAL));
572e2857 4954
13fe0198
MA
4955 if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) {
4956 error = zfs_onexit_fd_hold(cleanup_fd, &minor);
4957 if (error != 0)
572e2857 4958 return (error);
572e2857 4959 }
572e2857 4960
13fe0198
MA
4961 error = dsl_dataset_user_hold(holds, minor, errlist);
4962 if (minor != 0)
4963 zfs_onexit_fd_rele(cleanup_fd);
572e2857 4964 return (error);
45d1cae3
BB
4965}
4966
4967/*
13fe0198 4968 * innvl is not used.
45d1cae3 4969 *
13fe0198
MA
4970 * outnvl: {
4971 * holdname -> time added (uint64 seconds since epoch)
4972 * ...
4973 * }
45d1cae3 4974 */
13fe0198 4975/* ARGSUSED */
45d1cae3 4976static int
13fe0198 4977zfs_ioc_get_holds(const char *snapname, nvlist_t *args, nvlist_t *outnvl)
45d1cae3 4978{
13fe0198 4979 return (dsl_dataset_get_holds(snapname, outnvl));
45d1cae3
BB
4980}
4981
4982/*
13fe0198
MA
4983 * innvl: {
4984 * snapname -> { holdname, ... }
4985 * ...
4986 * }
45d1cae3 4987 *
13fe0198
MA
4988 * outnvl: {
4989 * snapname -> error value (int32)
4990 * ...
4991 * }
45d1cae3 4992 */
13fe0198 4993/* ARGSUSED */
45d1cae3 4994static int
13fe0198 4995zfs_ioc_release(const char *pool, nvlist_t *holds, nvlist_t *errlist)
45d1cae3 4996{
13fe0198 4997 return (dsl_dataset_user_release(holds, errlist));
45d1cae3
BB
4998}
4999
26685276
BB
5000/*
5001 * inputs:
5002 * zc_guid flags (ZEVENT_NONBLOCK)
9b101a73 5003 * zc_cleanup_fd zevent file descriptor
26685276
BB
5004 *
5005 * outputs:
5006 * zc_nvlist_dst next nvlist event
5007 * zc_cookie dropped events since last get
26685276
BB
5008 */
5009static int
5010zfs_ioc_events_next(zfs_cmd_t *zc)
5011{
5012 zfs_zevent_t *ze;
5013 nvlist_t *event = NULL;
5014 minor_t minor;
5015 uint64_t dropped = 0;
5016 int error;
5017
5018 error = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
5019 if (error != 0)
5020 return (error);
5021
5022 do {
baa40d45
BB
5023 error = zfs_zevent_next(ze, &event,
5024 &zc->zc_nvlist_dst_size, &dropped);
26685276
BB
5025 if (event != NULL) {
5026 zc->zc_cookie = dropped;
5027 error = put_nvlist(zc, event);
baa40d45 5028 nvlist_free(event);
26685276
BB
5029 }
5030
5031 if (zc->zc_guid & ZEVENT_NONBLOCK)
5032 break;
5033
5034 if ((error == 0) || (error != ENOENT))
5035 break;
5036
5037 error = zfs_zevent_wait(ze);
13fe0198 5038 if (error != 0)
26685276
BB
5039 break;
5040 } while (1);
5041
5042 zfs_zevent_fd_rele(zc->zc_cleanup_fd);
5043
5044 return (error);
5045}
5046
5047/*
5048 * outputs:
5049 * zc_cookie cleared events count
5050 */
5051static int
5052zfs_ioc_events_clear(zfs_cmd_t *zc)
5053{
5054 int count;
5055
5056 zfs_zevent_drain_all(&count);
5057 zc->zc_cookie = count;
5058
d1d7e268 5059 return (0);
26685276
BB
5060}
5061
75e3ff58
BB
5062/*
5063 * inputs:
5064 * zc_guid eid | ZEVENT_SEEK_START | ZEVENT_SEEK_END
5065 * zc_cleanup zevent file descriptor
5066 */
5067static int
5068zfs_ioc_events_seek(zfs_cmd_t *zc)
5069{
5070 zfs_zevent_t *ze;
5071 minor_t minor;
5072 int error;
5073
5074 error = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
5075 if (error != 0)
5076 return (error);
5077
5078 error = zfs_zevent_seek(ze, zc->zc_guid);
5079 zfs_zevent_fd_rele(zc->zc_cleanup_fd);
5080
5081 return (error);
5082}
5083
330d06f9
MA
5084/*
5085 * inputs:
5086 * zc_name name of new filesystem or snapshot
5087 * zc_value full name of old snapshot
5088 *
5089 * outputs:
5090 * zc_cookie space in bytes
5091 * zc_objset_type compressed space in bytes
5092 * zc_perm_action uncompressed space in bytes
5093 */
5094static int
5095zfs_ioc_space_written(zfs_cmd_t *zc)
5096{
5097 int error;
13fe0198 5098 dsl_pool_t *dp;
330d06f9
MA
5099 dsl_dataset_t *new, *old;
5100
13fe0198 5101 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
330d06f9
MA
5102 if (error != 0)
5103 return (error);
13fe0198
MA
5104 error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &new);
5105 if (error != 0) {
5106 dsl_pool_rele(dp, FTAG);
5107 return (error);
5108 }
5109 error = dsl_dataset_hold(dp, zc->zc_value, FTAG, &old);
330d06f9
MA
5110 if (error != 0) {
5111 dsl_dataset_rele(new, FTAG);
13fe0198 5112 dsl_pool_rele(dp, FTAG);
330d06f9
MA
5113 return (error);
5114 }
5115
5116 error = dsl_dataset_space_written(old, new, &zc->zc_cookie,
5117 &zc->zc_objset_type, &zc->zc_perm_action);
5118 dsl_dataset_rele(old, FTAG);
5119 dsl_dataset_rele(new, FTAG);
13fe0198 5120 dsl_pool_rele(dp, FTAG);
330d06f9
MA
5121 return (error);
5122}
5123
5124/*
6f1ffb06
MA
5125 * innvl: {
5126 * "firstsnap" -> snapshot name
5127 * }
330d06f9 5128 *
6f1ffb06
MA
5129 * outnvl: {
5130 * "used" -> space in bytes
5131 * "compressed" -> compressed space in bytes
5132 * "uncompressed" -> uncompressed space in bytes
5133 * }
330d06f9
MA
5134 */
5135static int
6f1ffb06 5136zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t *outnvl)
330d06f9
MA
5137{
5138 int error;
13fe0198 5139 dsl_pool_t *dp;
330d06f9 5140 dsl_dataset_t *new, *old;
6f1ffb06
MA
5141 char *firstsnap;
5142 uint64_t used, comp, uncomp;
330d06f9 5143
6f1ffb06 5144 if (nvlist_lookup_string(innvl, "firstsnap", &firstsnap) != 0)
2e528b49 5145 return (SET_ERROR(EINVAL));
6f1ffb06 5146
13fe0198 5147 error = dsl_pool_hold(lastsnap, FTAG, &dp);
330d06f9
MA
5148 if (error != 0)
5149 return (error);
13fe0198
MA
5150
5151 error = dsl_dataset_hold(dp, lastsnap, FTAG, &new);
5152 if (error != 0) {
5153 dsl_pool_rele(dp, FTAG);
5154 return (error);
5155 }
5156 error = dsl_dataset_hold(dp, firstsnap, FTAG, &old);
330d06f9
MA
5157 if (error != 0) {
5158 dsl_dataset_rele(new, FTAG);
13fe0198 5159 dsl_pool_rele(dp, FTAG);
330d06f9
MA
5160 return (error);
5161 }
5162
6f1ffb06 5163 error = dsl_dataset_space_wouldfree(old, new, &used, &comp, &uncomp);
330d06f9
MA
5164 dsl_dataset_rele(old, FTAG);
5165 dsl_dataset_rele(new, FTAG);
13fe0198 5166 dsl_pool_rele(dp, FTAG);
6f1ffb06
MA
5167 fnvlist_add_uint64(outnvl, "used", used);
5168 fnvlist_add_uint64(outnvl, "compressed", comp);
5169 fnvlist_add_uint64(outnvl, "uncompressed", uncomp);
330d06f9
MA
5170 return (error);
5171}
5172
34dc7c2f 5173/*
6f1ffb06
MA
5174 * innvl: {
5175 * "fd" -> file descriptor to write stream to (int32)
5176 * (optional) "fromsnap" -> full snap name to send an incremental from
5177 * }
5178 *
5179 * outnvl is unused
34dc7c2f 5180 */
6f1ffb06
MA
5181/* ARGSUSED */
5182static int
5183zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5184{
6f1ffb06
MA
5185 int error;
5186 offset_t off;
13fe0198 5187 char *fromname = NULL;
6f1ffb06 5188 int fd;
13fe0198 5189 file_t *fp;
6f1ffb06
MA
5190
5191 error = nvlist_lookup_int32(innvl, "fd", &fd);
5192 if (error != 0)
2e528b49 5193 return (SET_ERROR(EINVAL));
6f1ffb06 5194
13fe0198 5195 (void) nvlist_lookup_string(innvl, "fromsnap", &fromname);
6f1ffb06 5196
13fe0198 5197 if ((fp = getf(fd)) == NULL)
2e528b49 5198 return (SET_ERROR(EBADF));
6f1ffb06
MA
5199
5200 off = fp->f_offset;
13fe0198 5201 error = dmu_send(snapname, fromname, fd, fp->f_vnode, &off);
6f1ffb06
MA
5202
5203 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5204 fp->f_offset = off;
13fe0198 5205
6f1ffb06 5206 releasef(fd);
6f1ffb06
MA
5207 return (error);
5208}
5209
5210/*
5211 * Determine approximately how large a zfs send stream will be -- the number
5212 * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5213 *
5214 * innvl: {
5215 * (optional) "fromsnap" -> full snap name to send an incremental from
5216 * }
5217 *
5218 * outnvl: {
5219 * "space" -> bytes of space (uint64)
5220 * }
5221 */
5222static int
5223zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5224{
13fe0198
MA
5225 dsl_pool_t *dp;
5226 dsl_dataset_t *fromsnap = NULL;
5227 dsl_dataset_t *tosnap;
6f1ffb06
MA
5228 int error;
5229 char *fromname;
5230 uint64_t space;
5231
13fe0198
MA
5232 error = dsl_pool_hold(snapname, FTAG, &dp);
5233 if (error != 0)
6f1ffb06
MA
5234 return (error);
5235
13fe0198
MA
5236 error = dsl_dataset_hold(dp, snapname, FTAG, &tosnap);
5237 if (error != 0) {
5238 dsl_pool_rele(dp, FTAG);
5239 return (error);
5240 }
5241
6f1ffb06
MA
5242 error = nvlist_lookup_string(innvl, "fromsnap", &fromname);
5243 if (error == 0) {
13fe0198
MA
5244 error = dsl_dataset_hold(dp, fromname, FTAG, &fromsnap);
5245 if (error != 0) {
5246 dsl_dataset_rele(tosnap, FTAG);
5247 dsl_pool_rele(dp, FTAG);
6f1ffb06
MA
5248 return (error);
5249 }
5250 }
5251
5252 error = dmu_send_estimate(tosnap, fromsnap, &space);
5253 fnvlist_add_uint64(outnvl, "space", space);
5254
5255 if (fromsnap != NULL)
13fe0198
MA
5256 dsl_dataset_rele(fromsnap, FTAG);
5257 dsl_dataset_rele(tosnap, FTAG);
5258 dsl_pool_rele(dp, FTAG);
6f1ffb06
MA
5259 return (error);
5260}
5261
5262
5263static zfs_ioc_vec_t zfs_ioc_vec[ZFS_IOC_LAST - ZFS_IOC_FIRST];
5264
5265static void
5266zfs_ioctl_register_legacy(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5267 zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
5268 boolean_t log_history, zfs_ioc_poolcheck_t pool_check)
5269{
5270 zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
5271
5272 ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
5273 ASSERT3U(ioc, <, ZFS_IOC_LAST);
5274 ASSERT3P(vec->zvec_legacy_func, ==, NULL);
5275 ASSERT3P(vec->zvec_func, ==, NULL);
5276
5277 vec->zvec_legacy_func = func;
5278 vec->zvec_secpolicy = secpolicy;
5279 vec->zvec_namecheck = namecheck;
5280 vec->zvec_allow_log = log_history;
5281 vec->zvec_pool_check = pool_check;
5282}
5283
5284/*
5285 * See the block comment at the beginning of this file for details on
5286 * each argument to this function.
5287 */
5288static void
5289zfs_ioctl_register(const char *name, zfs_ioc_t ioc, zfs_ioc_func_t *func,
5290 zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
5291 zfs_ioc_poolcheck_t pool_check, boolean_t smush_outnvlist,
5292 boolean_t allow_log)
5293{
5294 zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
5295
5296 ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
5297 ASSERT3U(ioc, <, ZFS_IOC_LAST);
5298 ASSERT3P(vec->zvec_legacy_func, ==, NULL);
5299 ASSERT3P(vec->zvec_func, ==, NULL);
5300
5301 /* if we are logging, the name must be valid */
5302 ASSERT(!allow_log || namecheck != NO_NAME);
5303
5304 vec->zvec_name = name;
5305 vec->zvec_func = func;
5306 vec->zvec_secpolicy = secpolicy;
5307 vec->zvec_namecheck = namecheck;
5308 vec->zvec_pool_check = pool_check;
5309 vec->zvec_smush_outnvlist = smush_outnvlist;
5310 vec->zvec_allow_log = allow_log;
5311}
5312
5313static void
5314zfs_ioctl_register_pool(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5315 zfs_secpolicy_func_t *secpolicy, boolean_t log_history,
5316 zfs_ioc_poolcheck_t pool_check)
5317{
5318 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5319 POOL_NAME, log_history, pool_check);
5320}
5321
5322static void
5323zfs_ioctl_register_dataset_nolog(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5324 zfs_secpolicy_func_t *secpolicy, zfs_ioc_poolcheck_t pool_check)
5325{
5326 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5327 DATASET_NAME, B_FALSE, pool_check);
5328}
5329
5330static void
5331zfs_ioctl_register_pool_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
5332{
5333 zfs_ioctl_register_legacy(ioc, func, zfs_secpolicy_config,
5334 POOL_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5335}
5336
5337static void
5338zfs_ioctl_register_pool_meta(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5339 zfs_secpolicy_func_t *secpolicy)
5340{
5341 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5342 NO_NAME, B_FALSE, POOL_CHECK_NONE);
5343}
5344
5345static void
5346zfs_ioctl_register_dataset_read_secpolicy(zfs_ioc_t ioc,
5347 zfs_ioc_legacy_func_t *func, zfs_secpolicy_func_t *secpolicy)
5348{
5349 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5350 DATASET_NAME, B_FALSE, POOL_CHECK_SUSPENDED);
5351}
5352
5353static void
5354zfs_ioctl_register_dataset_read(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
5355{
5356 zfs_ioctl_register_dataset_read_secpolicy(ioc, func,
5357 zfs_secpolicy_read);
5358}
5359
5360static void
5361zfs_ioctl_register_dataset_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5362 zfs_secpolicy_func_t *secpolicy)
5363{
5364 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5365 DATASET_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5366}
5367
5368static void
5369zfs_ioctl_init(void)
5370{
5371 zfs_ioctl_register("snapshot", ZFS_IOC_SNAPSHOT,
5372 zfs_ioc_snapshot, zfs_secpolicy_snapshot, POOL_NAME,
5373 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5374
5375 zfs_ioctl_register("log_history", ZFS_IOC_LOG_HISTORY,
5376 zfs_ioc_log_history, zfs_secpolicy_log_history, NO_NAME,
5377 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE);
5378
5379 zfs_ioctl_register("space_snaps", ZFS_IOC_SPACE_SNAPS,
5380 zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME,
5381 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5382
5383 zfs_ioctl_register("send", ZFS_IOC_SEND_NEW,
5384 zfs_ioc_send_new, zfs_secpolicy_send_new, DATASET_NAME,
5385 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5386
5387 zfs_ioctl_register("send_space", ZFS_IOC_SEND_SPACE,
5388 zfs_ioc_send_space, zfs_secpolicy_read, DATASET_NAME,
5389 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5390
5391 zfs_ioctl_register("create", ZFS_IOC_CREATE,
5392 zfs_ioc_create, zfs_secpolicy_create_clone, DATASET_NAME,
5393 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5394
5395 zfs_ioctl_register("clone", ZFS_IOC_CLONE,
5396 zfs_ioc_clone, zfs_secpolicy_create_clone, DATASET_NAME,
5397 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5398
5399 zfs_ioctl_register("destroy_snaps", ZFS_IOC_DESTROY_SNAPS,
5400 zfs_ioc_destroy_snaps, zfs_secpolicy_destroy_snaps, POOL_NAME,
5401 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5402
13fe0198
MA
5403 zfs_ioctl_register("hold", ZFS_IOC_HOLD,
5404 zfs_ioc_hold, zfs_secpolicy_hold, POOL_NAME,
5405 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5406 zfs_ioctl_register("release", ZFS_IOC_RELEASE,
5407 zfs_ioc_release, zfs_secpolicy_release, POOL_NAME,
5408 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5409
5410 zfs_ioctl_register("get_holds", ZFS_IOC_GET_HOLDS,
5411 zfs_ioc_get_holds, zfs_secpolicy_read, DATASET_NAME,
5412 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5413
46ba1e59
MA
5414 zfs_ioctl_register("rollback", ZFS_IOC_ROLLBACK,
5415 zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME,
5416 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE);
5417
da536844
MA
5418 zfs_ioctl_register("bookmark", ZFS_IOC_BOOKMARK,
5419 zfs_ioc_bookmark, zfs_secpolicy_bookmark, POOL_NAME,
5420 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5421
5422 zfs_ioctl_register("get_bookmarks", ZFS_IOC_GET_BOOKMARKS,
5423 zfs_ioc_get_bookmarks, zfs_secpolicy_read, DATASET_NAME,
5424 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5425
5426 zfs_ioctl_register("destroy_bookmarks", ZFS_IOC_DESTROY_BOOKMARKS,
5427 zfs_ioc_destroy_bookmarks, zfs_secpolicy_destroy_bookmarks,
5428 POOL_NAME,
5429 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5430
6f1ffb06
MA
5431 /* IOCTLS that use the legacy function signature */
5432
5433 zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
5434 zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_READONLY);
5435
5436 zfs_ioctl_register_pool(ZFS_IOC_POOL_CREATE, zfs_ioc_pool_create,
5437 zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
5438 zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SCAN,
5439 zfs_ioc_pool_scan);
5440 zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_UPGRADE,
5441 zfs_ioc_pool_upgrade);
5442 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ADD,
5443 zfs_ioc_vdev_add);
5444 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_REMOVE,
5445 zfs_ioc_vdev_remove);
5446 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SET_STATE,
5447 zfs_ioc_vdev_set_state);
5448 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ATTACH,
5449 zfs_ioc_vdev_attach);
5450 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_DETACH,
5451 zfs_ioc_vdev_detach);
5452 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETPATH,
5453 zfs_ioc_vdev_setpath);
5454 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETFRU,
5455 zfs_ioc_vdev_setfru);
5456 zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SET_PROPS,
5457 zfs_ioc_pool_set_props);
5458 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SPLIT,
5459 zfs_ioc_vdev_split);
5460 zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_REGUID,
5461 zfs_ioc_pool_reguid);
5462
5463 zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_CONFIGS,
5464 zfs_ioc_pool_configs, zfs_secpolicy_none);
5465 zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_TRYIMPORT,
5466 zfs_ioc_pool_tryimport, zfs_secpolicy_config);
5467 zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_FAULT,
5468 zfs_ioc_inject_fault, zfs_secpolicy_inject);
5469 zfs_ioctl_register_pool_meta(ZFS_IOC_CLEAR_FAULT,
5470 zfs_ioc_clear_fault, zfs_secpolicy_inject);
5471 zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_LIST_NEXT,
5472 zfs_ioc_inject_list_next, zfs_secpolicy_inject);
5473
5474 /*
5475 * pool destroy, and export don't log the history as part of
5476 * zfsdev_ioctl, but rather zfs_ioc_pool_export
5477 * does the logging of those commands.
5478 */
5479 zfs_ioctl_register_pool(ZFS_IOC_POOL_DESTROY, zfs_ioc_pool_destroy,
5480 zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
5481 zfs_ioctl_register_pool(ZFS_IOC_POOL_EXPORT, zfs_ioc_pool_export,
5482 zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
5483
5484 zfs_ioctl_register_pool(ZFS_IOC_POOL_STATS, zfs_ioc_pool_stats,
5485 zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
5486 zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_PROPS, zfs_ioc_pool_get_props,
5487 zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
5488
5489 zfs_ioctl_register_pool(ZFS_IOC_ERROR_LOG, zfs_ioc_error_log,
5490 zfs_secpolicy_inject, B_FALSE, POOL_CHECK_SUSPENDED);
5491 zfs_ioctl_register_pool(ZFS_IOC_DSOBJ_TO_DSNAME,
5492 zfs_ioc_dsobj_to_dsname,
5493 zfs_secpolicy_diff, B_FALSE, POOL_CHECK_SUSPENDED);
5494 zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_HISTORY,
5495 zfs_ioc_pool_get_history,
5496 zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
5497
5498 zfs_ioctl_register_pool(ZFS_IOC_POOL_IMPORT, zfs_ioc_pool_import,
5499 zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
5500
5501 zfs_ioctl_register_pool(ZFS_IOC_CLEAR, zfs_ioc_clear,
ac72fac3 5502 zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
6f1ffb06
MA
5503 zfs_ioctl_register_pool(ZFS_IOC_POOL_REOPEN, zfs_ioc_pool_reopen,
5504 zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
5505
5506 zfs_ioctl_register_dataset_read(ZFS_IOC_SPACE_WRITTEN,
5507 zfs_ioc_space_written);
6f1ffb06
MA
5508 zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_RECVD_PROPS,
5509 zfs_ioc_objset_recvd_props);
5510 zfs_ioctl_register_dataset_read(ZFS_IOC_NEXT_OBJ,
5511 zfs_ioc_next_obj);
5512 zfs_ioctl_register_dataset_read(ZFS_IOC_GET_FSACL,
5513 zfs_ioc_get_fsacl);
5514 zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_STATS,
5515 zfs_ioc_objset_stats);
5516 zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_ZPLPROPS,
5517 zfs_ioc_objset_zplprops);
5518 zfs_ioctl_register_dataset_read(ZFS_IOC_DATASET_LIST_NEXT,
5519 zfs_ioc_dataset_list_next);
5520 zfs_ioctl_register_dataset_read(ZFS_IOC_SNAPSHOT_LIST_NEXT,
5521 zfs_ioc_snapshot_list_next);
5522 zfs_ioctl_register_dataset_read(ZFS_IOC_SEND_PROGRESS,
5523 zfs_ioc_send_progress);
5524
5525 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_DIFF,
5526 zfs_ioc_diff, zfs_secpolicy_diff);
5527 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_STATS,
5528 zfs_ioc_obj_to_stats, zfs_secpolicy_diff);
5529 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_PATH,
5530 zfs_ioc_obj_to_path, zfs_secpolicy_diff);
5531 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_ONE,
5532 zfs_ioc_userspace_one, zfs_secpolicy_userspace_one);
5533 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_MANY,
5534 zfs_ioc_userspace_many, zfs_secpolicy_userspace_many);
5535 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_SEND,
5536 zfs_ioc_send, zfs_secpolicy_send);
5537
5538 zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_PROP, zfs_ioc_set_prop,
5539 zfs_secpolicy_none);
5540 zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy,
5541 zfs_secpolicy_destroy);
6f1ffb06
MA
5542 zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename,
5543 zfs_secpolicy_rename);
5544 zfs_ioctl_register_dataset_modify(ZFS_IOC_RECV, zfs_ioc_recv,
5545 zfs_secpolicy_recv);
5546 zfs_ioctl_register_dataset_modify(ZFS_IOC_PROMOTE, zfs_ioc_promote,
5547 zfs_secpolicy_promote);
6f1ffb06
MA
5548 zfs_ioctl_register_dataset_modify(ZFS_IOC_INHERIT_PROP,
5549 zfs_ioc_inherit_prop, zfs_secpolicy_inherit_prop);
5550 zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_FSACL, zfs_ioc_set_fsacl,
5551 zfs_secpolicy_set_fsacl);
5552
5553 zfs_ioctl_register_dataset_nolog(ZFS_IOC_SHARE, zfs_ioc_share,
5554 zfs_secpolicy_share, POOL_CHECK_NONE);
5555 zfs_ioctl_register_dataset_nolog(ZFS_IOC_SMB_ACL, zfs_ioc_smb_acl,
5556 zfs_secpolicy_smb_acl, POOL_CHECK_NONE);
5557 zfs_ioctl_register_dataset_nolog(ZFS_IOC_USERSPACE_UPGRADE,
5558 zfs_ioc_userspace_upgrade, zfs_secpolicy_userspace_upgrade,
5559 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5560 zfs_ioctl_register_dataset_nolog(ZFS_IOC_TMP_SNAPSHOT,
5561 zfs_ioc_tmp_snapshot, zfs_secpolicy_tmp_snapshot,
5562 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5563
5564 /*
ba6a2402 5565 * ZoL functions
6f1ffb06 5566 */
6f1ffb06
MA
5567 zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_NEXT, zfs_ioc_events_next,
5568 zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
5569 zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_CLEAR, zfs_ioc_events_clear,
5570 zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
75e3ff58
BB
5571 zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_SEEK, zfs_ioc_events_seek,
5572 zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
6f1ffb06 5573}
34dc7c2f 5574
9babb374 5575int
572e2857
BB
5576pool_status_check(const char *name, zfs_ioc_namecheck_t type,
5577 zfs_ioc_poolcheck_t check)
9babb374
BB
5578{
5579 spa_t *spa;
5580 int error;
5581
5582 ASSERT(type == POOL_NAME || type == DATASET_NAME);
5583
572e2857
BB
5584 if (check & POOL_CHECK_NONE)
5585 return (0);
5586
9babb374
BB
5587 error = spa_open(name, &spa, FTAG);
5588 if (error == 0) {
572e2857 5589 if ((check & POOL_CHECK_SUSPENDED) && spa_suspended(spa))
2e528b49 5590 error = SET_ERROR(EAGAIN);
572e2857 5591 else if ((check & POOL_CHECK_READONLY) && !spa_writeable(spa))
2e528b49 5592 error = SET_ERROR(EROFS);
9babb374
BB
5593 spa_close(spa, FTAG);
5594 }
5595 return (error);
5596}
5597
325f0235
BB
5598static void *
5599zfsdev_get_state_impl(minor_t minor, enum zfsdev_state_type which)
5600{
5601 zfsdev_state_t *zs;
5602
3937ab20 5603 for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
325f0235 5604 if (zs->zs_minor == minor) {
3937ab20 5605 smp_rmb();
325f0235 5606 switch (which) {
d1d7e268
MK
5607 case ZST_ONEXIT:
5608 return (zs->zs_onexit);
5609 case ZST_ZEVENT:
5610 return (zs->zs_zevent);
5611 case ZST_ALL:
5612 return (zs);
325f0235
BB
5613 }
5614 }
5615 }
5616
d1d7e268 5617 return (NULL);
325f0235
BB
5618}
5619
5620void *
5621zfsdev_get_state(minor_t minor, enum zfsdev_state_type which)
5622{
5623 void *ptr;
5624
325f0235 5625 ptr = zfsdev_get_state_impl(minor, which);
325f0235 5626
d1d7e268 5627 return (ptr);
325f0235
BB
5628}
5629
5630minor_t
5631zfsdev_getminor(struct file *filp)
5632{
5633 ASSERT(filp != NULL);
5634 ASSERT(filp->private_data != NULL);
5635
5636 return (((zfsdev_state_t *)filp->private_data)->zs_minor);
5637}
5638
572e2857 5639/*
325f0235
BB
5640 * Find a free minor number. The zfsdev_state_list is expected to
5641 * be short since it is only a list of currently open file handles.
572e2857
BB
5642 */
5643minor_t
5644zfsdev_minor_alloc(void)
5645{
325f0235 5646 static minor_t last_minor = 0;
572e2857
BB
5647 minor_t m;
5648
5649 ASSERT(MUTEX_HELD(&zfsdev_state_lock));
5650
5651 for (m = last_minor + 1; m != last_minor; m++) {
5652 if (m > ZFSDEV_MAX_MINOR)
5653 m = 1;
325f0235 5654 if (zfsdev_get_state_impl(m, ZST_ALL) == NULL) {
572e2857
BB
5655 last_minor = m;
5656 return (m);
5657 }
5658 }
5659
5660 return (0);
5661}
5662
5663static int
325f0235 5664zfsdev_state_init(struct file *filp)
572e2857 5665{
3937ab20 5666 zfsdev_state_t *zs, *zsprev = NULL;
572e2857 5667 minor_t minor;
3937ab20 5668 boolean_t newzs = B_FALSE;
572e2857
BB
5669
5670 ASSERT(MUTEX_HELD(&zfsdev_state_lock));
572e2857 5671
d1d7e268
MK
5672 minor = zfsdev_minor_alloc();
5673 if (minor == 0)
5674 return (SET_ERROR(ENXIO));
325f0235 5675
3937ab20
TC
5676 for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
5677 if (zs->zs_minor == -1)
5678 break;
5679 zsprev = zs;
5680 }
5681
5682 if (!zs) {
5683 zs = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP);
5684 newzs = B_TRUE;
5685 }
572e2857 5686
325f0235 5687 zs->zs_file = filp;
325f0235 5688 filp->private_data = zs;
572e2857 5689
325f0235
BB
5690 zfs_onexit_init((zfs_onexit_t **)&zs->zs_onexit);
5691 zfs_zevent_init((zfs_zevent_t **)&zs->zs_zevent);
572e2857 5692
3937ab20
TC
5693
5694 /*
5695 * In order to provide for lock-free concurrent read access
5696 * to the minor list in zfsdev_get_state_impl(), new entries
5697 * must be completely written before linking them into the
5698 * list whereas existing entries are already linked; the last
5699 * operation must be updating zs_minor (from -1 to the new
5700 * value).
5701 */
5702 if (newzs) {
5703 zs->zs_minor = minor;
5704 smp_wmb();
5705 zsprev->zs_next = zs;
5706 } else {
5707 smp_wmb();
5708 zs->zs_minor = minor;
5709 }
572e2857
BB
5710
5711 return (0);
5712}
5713
325f0235
BB
5714static int
5715zfsdev_state_destroy(struct file *filp)
572e2857 5716{
325f0235 5717 zfsdev_state_t *zs;
572e2857 5718
325f0235
BB
5719 ASSERT(MUTEX_HELD(&zfsdev_state_lock));
5720 ASSERT(filp->private_data != NULL);
572e2857 5721
325f0235 5722 zs = filp->private_data;
3937ab20 5723 zs->zs_minor = -1;
325f0235
BB
5724 zfs_onexit_destroy(zs->zs_onexit);
5725 zfs_zevent_destroy(zs->zs_zevent);
572e2857 5726
d1d7e268 5727 return (0);
572e2857
BB
5728}
5729
5730static int
325f0235 5731zfsdev_open(struct inode *ino, struct file *filp)
572e2857 5732{
325f0235 5733 int error;
572e2857 5734
325f0235
BB
5735 mutex_enter(&zfsdev_state_lock);
5736 error = zfsdev_state_init(filp);
5737 mutex_exit(&zfsdev_state_lock);
572e2857 5738
325f0235 5739 return (-error);
572e2857
BB
5740}
5741
5742static int
325f0235 5743zfsdev_release(struct inode *ino, struct file *filp)
572e2857 5744{
325f0235 5745 int error;
572e2857
BB
5746
5747 mutex_enter(&zfsdev_state_lock);
325f0235 5748 error = zfsdev_state_destroy(filp);
572e2857
BB
5749 mutex_exit(&zfsdev_state_lock);
5750
325f0235 5751 return (-error);
572e2857
BB
5752}
5753
325f0235
BB
5754static long
5755zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
34dc7c2f
BB
5756{
5757 zfs_cmd_t *zc;
6f1ffb06 5758 uint_t vecnum;
4fd762f8 5759 int error, rc, flag = 0;
6f1ffb06 5760 const zfs_ioc_vec_t *vec;
fb8e608d 5761 char *saved_poolname = NULL;
6f1ffb06
MA
5762 nvlist_t *innvl = NULL;
5763
5764 vecnum = cmd - ZFS_IOC_FIRST;
5765 if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
2e528b49 5766 return (-SET_ERROR(EINVAL));
6f1ffb06 5767 vec = &zfs_ioc_vec[vecnum];
34dc7c2f 5768
2e0358cb
BB
5769 /*
5770 * The registered ioctl list may be sparse, verify that either
5771 * a normal or legacy handler are registered.
5772 */
5773 if (vec->zvec_func == NULL && vec->zvec_legacy_func == NULL)
5774 return (-SET_ERROR(EINVAL));
5775
00b46022 5776 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP | KM_NODEBUG);
34dc7c2f 5777
9babb374 5778 error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag);
6f1ffb06 5779 if (error != 0) {
2e528b49 5780 error = SET_ERROR(EFAULT);
6f1ffb06
MA
5781 goto out;
5782 }
34dc7c2f 5783
6f1ffb06
MA
5784 zc->zc_iflags = flag & FKIOCTL;
5785 if (zc->zc_nvlist_src_size != 0) {
5786 error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
5787 zc->zc_iflags, &innvl);
5788 if (error != 0)
5789 goto out;
5790 }
34dc7c2f
BB
5791
5792 /*
5793 * Ensure that all pool/dataset names are valid before we pass down to
5794 * the lower layers.
5795 */
6f1ffb06
MA
5796 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
5797 switch (vec->zvec_namecheck) {
5798 case POOL_NAME:
5799 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
2e528b49 5800 error = SET_ERROR(EINVAL);
6f1ffb06 5801 else
572e2857 5802 error = pool_status_check(zc->zc_name,
6f1ffb06
MA
5803 vec->zvec_namecheck, vec->zvec_pool_check);
5804 break;
34dc7c2f 5805
6f1ffb06
MA
5806 case DATASET_NAME:
5807 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
2e528b49 5808 error = SET_ERROR(EINVAL);
6f1ffb06 5809 else
572e2857 5810 error = pool_status_check(zc->zc_name,
6f1ffb06
MA
5811 vec->zvec_namecheck, vec->zvec_pool_check);
5812 break;
34dc7c2f 5813
6f1ffb06
MA
5814 case NO_NAME:
5815 break;
34dc7c2f
BB
5816 }
5817
34dc7c2f 5818
6f1ffb06
MA
5819 if (error == 0 && !(flag & FKIOCTL))
5820 error = vec->zvec_secpolicy(zc, innvl, CRED());
5821
5822 if (error != 0)
5823 goto out;
5824
5825 /* legacy ioctls can modify zc_name */
4fd762f8
BB
5826 saved_poolname = strdup(zc->zc_name);
5827 if (saved_poolname == NULL) {
5828 error = SET_ERROR(ENOMEM);
5829 goto out;
5830 } else {
5831 saved_poolname[strcspn(saved_poolname, "/@#")] = '\0';
5832 }
6f1ffb06
MA
5833
5834 if (vec->zvec_func != NULL) {
5835 nvlist_t *outnvl;
5836 int puterror = 0;
5837 spa_t *spa;
5838 nvlist_t *lognv = NULL;
5839
5840 ASSERT(vec->zvec_legacy_func == NULL);
5841
5842 /*
5843 * Add the innvl to the lognv before calling the func,
5844 * in case the func changes the innvl.
5845 */
5846 if (vec->zvec_allow_log) {
5847 lognv = fnvlist_alloc();
5848 fnvlist_add_string(lognv, ZPOOL_HIST_IOCTL,
5849 vec->zvec_name);
5850 if (!nvlist_empty(innvl)) {
5851 fnvlist_add_nvlist(lognv, ZPOOL_HIST_INPUT_NVL,
5852 innvl);
5853 }
5854 }
5855
8769db39 5856 VERIFY0(nvlist_alloc(&outnvl, NV_UNIQUE_NAME, KM_PUSHPAGE));
6f1ffb06
MA
5857 error = vec->zvec_func(zc->zc_name, innvl, outnvl);
5858
5859 if (error == 0 && vec->zvec_allow_log &&
5860 spa_open(zc->zc_name, &spa, FTAG) == 0) {
5861 if (!nvlist_empty(outnvl)) {
5862 fnvlist_add_nvlist(lognv, ZPOOL_HIST_OUTPUT_NVL,
5863 outnvl);
5864 }
5865 (void) spa_history_log_nvl(spa, lognv);
5866 spa_close(spa, FTAG);
5867 }
5868 fnvlist_free(lognv);
5869
5870 if (!nvlist_empty(outnvl) || zc->zc_nvlist_dst_size != 0) {
5871 int smusherror = 0;
5872 if (vec->zvec_smush_outnvlist) {
5873 smusherror = nvlist_smush(outnvl,
5874 zc->zc_nvlist_dst_size);
5875 }
5876 if (smusherror == 0)
5877 puterror = put_nvlist(zc, outnvl);
5878 }
5879
5880 if (puterror != 0)
5881 error = puterror;
5882
5883 nvlist_free(outnvl);
5884 } else {
5885 error = vec->zvec_legacy_func(zc);
5886 }
5887
5888out:
5889 nvlist_free(innvl);
9babb374 5890 rc = ddi_copyout(zc, (void *)arg, sizeof (zfs_cmd_t), flag);
6f1ffb06 5891 if (error == 0 && rc != 0)
2e528b49 5892 error = SET_ERROR(EFAULT);
6f1ffb06
MA
5893 if (error == 0 && vec->zvec_allow_log) {
5894 char *s = tsd_get(zfs_allow_log_key);
5895 if (s != NULL)
5896 strfree(s);
fb8e608d
TC
5897 (void) tsd_set(zfs_allow_log_key, saved_poolname);
5898 } else {
5899 if (saved_poolname != NULL)
4fd762f8 5900 strfree(saved_poolname);
34dc7c2f
BB
5901 }
5902
5903 kmem_free(zc, sizeof (zfs_cmd_t));
325f0235 5904 return (-error);
34dc7c2f
BB
5905}
5906
325f0235
BB
5907#ifdef CONFIG_COMPAT
5908static long
5909zfsdev_compat_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
34dc7c2f 5910{
d1d7e268 5911 return (zfsdev_ioctl(filp, cmd, arg));
325f0235
BB
5912}
5913#else
d1d7e268 5914#define zfsdev_compat_ioctl NULL
325f0235 5915#endif
34dc7c2f 5916
325f0235 5917static const struct file_operations zfsdev_fops = {
d1d7e268
MK
5918 .open = zfsdev_open,
5919 .release = zfsdev_release,
5920 .unlocked_ioctl = zfsdev_ioctl,
5921 .compat_ioctl = zfsdev_compat_ioctl,
5922 .owner = THIS_MODULE,
325f0235 5923};
34dc7c2f 5924
325f0235 5925static struct miscdevice zfs_misc = {
d1d7e268
MK
5926 .minor = MISC_DYNAMIC_MINOR,
5927 .name = ZFS_DRIVER,
5928 .fops = &zfsdev_fops,
325f0235 5929};
34dc7c2f
BB
5930
5931static int
325f0235 5932zfs_attach(void)
34dc7c2f 5933{
325f0235 5934 int error;
34dc7c2f 5935
325f0235 5936 mutex_init(&zfsdev_state_lock, NULL, MUTEX_DEFAULT, NULL);
3937ab20
TC
5937 zfsdev_state_list = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP);
5938 zfsdev_state_list->zs_minor = -1;
34dc7c2f 5939
325f0235 5940 error = misc_register(&zfs_misc);
d1d7e268 5941 if (error != 0) {
325f0235
BB
5942 printk(KERN_INFO "ZFS: misc_register() failed %d\n", error);
5943 return (error);
5944 }
34dc7c2f 5945
325f0235 5946 return (0);
34dc7c2f
BB
5947}
5948
325f0235
BB
5949static void
5950zfs_detach(void)
34dc7c2f 5951{
325f0235 5952 int error;
3937ab20 5953 zfsdev_state_t *zs, *zsprev = NULL;
34dc7c2f 5954
325f0235 5955 error = misc_deregister(&zfs_misc);
13fe0198 5956 if (error != 0)
325f0235 5957 printk(KERN_INFO "ZFS: misc_deregister() failed %d\n", error);
34dc7c2f 5958
325f0235 5959 mutex_destroy(&zfsdev_state_lock);
3937ab20
TC
5960
5961 for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
5962 if (zsprev)
5963 kmem_free(zsprev, sizeof (zfsdev_state_t));
5964 zsprev = zs;
5965 }
5966 if (zsprev)
5967 kmem_free(zsprev, sizeof (zfsdev_state_t));
34dc7c2f
BB
5968}
5969
6f1ffb06
MA
5970static void
5971zfs_allow_log_destroy(void *arg)
5972{
5973 char *poolname = arg;
5974 strfree(poolname);
5975}
325f0235
BB
5976
5977#ifdef DEBUG
d1d7e268 5978#define ZFS_DEBUG_STR " (DEBUG mode)"
325f0235 5979#else
d1d7e268 5980#define ZFS_DEBUG_STR ""
325f0235 5981#endif
34dc7c2f
BB
5982
5983int
5984_init(void)
5985{
5986 int error;
5987
5988 spa_init(FREAD | FWRITE);
5989 zfs_init();
34dc7c2f 5990
325f0235
BB
5991 if ((error = zvol_init()) != 0)
5992 goto out1;
5993
6f1ffb06
MA
5994 zfs_ioctl_init();
5995
325f0235
BB
5996 if ((error = zfs_attach()) != 0)
5997 goto out2;
34dc7c2f 5998
d5446cfc 5999 tsd_create(&zfs_fsyncer_key, NULL);
6f1ffb06
MA
6000 tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
6001 tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
34dc7c2f 6002
4b5d425f 6003 printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, "
d1d7e268
MK
6004 "ZFS pool version %s, ZFS filesystem version %s\n",
6005 ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR,
6006 SPA_VERSION_STRING, ZPL_VERSION_STRING);
b695c34e
MM
6007#ifndef CONFIG_FS_POSIX_ACL
6008 printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n");
6009#endif /* CONFIG_FS_POSIX_ACL */
34dc7c2f
BB
6010
6011 return (0);
325f0235
BB
6012
6013out2:
6014 (void) zvol_fini();
6015out1:
6016 zfs_fini();
6017 spa_fini();
4b5d425f 6018 printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s"
d1d7e268
MK
6019 ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE,
6020 ZFS_DEBUG_STR, error);
325f0235
BB
6021
6022 return (error);
34dc7c2f
BB
6023}
6024
6025int
6026_fini(void)
6027{
325f0235 6028 zfs_detach();
34dc7c2f
BB
6029 zvol_fini();
6030 zfs_fini();
6031 spa_fini();
46e18b3f 6032
d5446cfc 6033 tsd_destroy(&zfs_fsyncer_key);
3fc050aa 6034 tsd_destroy(&rrw_tsd_key);
6f1ffb06 6035 tsd_destroy(&zfs_allow_log_key);
34dc7c2f 6036
4b5d425f 6037 printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n",
d1d7e268 6038 ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
34dc7c2f 6039
325f0235 6040 return (0);
34dc7c2f 6041}
325f0235
BB
6042
6043#ifdef HAVE_SPL
6044spl_module_init(_init);
6045spl_module_exit(_fini);
6046
6047MODULE_DESCRIPTION("ZFS");
6048MODULE_AUTHOR(ZFS_META_AUTHOR);
6049MODULE_LICENSE(ZFS_META_LICENSE);
99e349db 6050MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
325f0235 6051#endif /* HAVE_SPL */