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