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