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