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