Mercurial > illumos > illumos-gate
comparison usr/src/uts/common/fs/zfs/zfs_ioctl.c @ 13980:d7059eb1884c
3598 want to dtrace when errors are generated in zfs
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Approved by: Garrett D'Amore <garrett@damore.org>
author | Matthew Ahrens <mahrens@delphix.com> |
---|---|
date | Fri, 08 Mar 2013 10:41:28 -0800 |
parents | 4972ab336f54 |
children | 6a5a2f4a47db |
comparison
equal
deleted
inserted
replaced
13979:b01a4832cdf9 | 13980:d7059eb1884c |
---|---|
22 /* | 22 /* |
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
24 * Portions Copyright 2011 Martin Matuska | 24 * Portions Copyright 2011 Martin Matuska |
25 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. | 25 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. |
26 * Copyright (c) 2012, Joyent, Inc. All rights reserved. | 26 * Copyright (c) 2012, Joyent, Inc. All rights reserved. |
27 * Copyright (c) 2012 by Delphix. All rights reserved. | 27 * Copyright (c) 2013 by Delphix. All rights reserved. |
28 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. | 28 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. |
29 */ | 29 */ |
30 | 30 |
31 /* | 31 /* |
32 * ZFS ioctls. | 32 * ZFS ioctls. |
406 { | 406 { |
407 if (INGLOBALZONE(curproc) || | 407 if (INGLOBALZONE(curproc) || |
408 zone_dataset_visible(zc->zc_name, NULL)) | 408 zone_dataset_visible(zc->zc_name, NULL)) |
409 return (0); | 409 return (0); |
410 | 410 |
411 return (ENOENT); | 411 return (SET_ERROR(ENOENT)); |
412 } | 412 } |
413 | 413 |
414 static int | 414 static int |
415 zfs_dozonecheck_impl(const char *dataset, uint64_t zoned, cred_t *cr) | 415 zfs_dozonecheck_impl(const char *dataset, uint64_t zoned, cred_t *cr) |
416 { | 416 { |
420 * The dataset must be visible by this zone -- check this first | 420 * The dataset must be visible by this zone -- check this first |
421 * so they don't see EPERM on something they shouldn't know about. | 421 * so they don't see EPERM on something they shouldn't know about. |
422 */ | 422 */ |
423 if (!INGLOBALZONE(curproc) && | 423 if (!INGLOBALZONE(curproc) && |
424 !zone_dataset_visible(dataset, &writable)) | 424 !zone_dataset_visible(dataset, &writable)) |
425 return (ENOENT); | 425 return (SET_ERROR(ENOENT)); |
426 | 426 |
427 if (INGLOBALZONE(curproc)) { | 427 if (INGLOBALZONE(curproc)) { |
428 /* | 428 /* |
429 * If the fs is zoned, only root can access it from the | 429 * If the fs is zoned, only root can access it from the |
430 * global zone. | 430 * global zone. |
431 */ | 431 */ |
432 if (secpolicy_zfs(cr) && zoned) | 432 if (secpolicy_zfs(cr) && zoned) |
433 return (EPERM); | 433 return (SET_ERROR(EPERM)); |
434 } else { | 434 } else { |
435 /* | 435 /* |
436 * If we are in a local zone, the 'zoned' property must be set. | 436 * If we are in a local zone, the 'zoned' property must be set. |
437 */ | 437 */ |
438 if (!zoned) | 438 if (!zoned) |
439 return (EPERM); | 439 return (SET_ERROR(EPERM)); |
440 | 440 |
441 /* must be writable by this zone */ | 441 /* must be writable by this zone */ |
442 if (!writable) | 442 if (!writable) |
443 return (EPERM); | 443 return (SET_ERROR(EPERM)); |
444 } | 444 } |
445 return (0); | 445 return (0); |
446 } | 446 } |
447 | 447 |
448 static int | 448 static int |
449 zfs_dozonecheck(const char *dataset, cred_t *cr) | 449 zfs_dozonecheck(const char *dataset, cred_t *cr) |
450 { | 450 { |
451 uint64_t zoned; | 451 uint64_t zoned; |
452 | 452 |
453 if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL)) | 453 if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL)) |
454 return (ENOENT); | 454 return (SET_ERROR(ENOENT)); |
455 | 455 |
456 return (zfs_dozonecheck_impl(dataset, zoned, cr)); | 456 return (zfs_dozonecheck_impl(dataset, zoned, cr)); |
457 } | 457 } |
458 | 458 |
459 static int | 459 static int |
460 zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr) | 460 zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr) |
461 { | 461 { |
462 uint64_t zoned; | 462 uint64_t zoned; |
463 | 463 |
464 if (dsl_prop_get_int_ds(ds, "zoned", &zoned)) | 464 if (dsl_prop_get_int_ds(ds, "zoned", &zoned)) |
465 return (ENOENT); | 465 return (SET_ERROR(ENOENT)); |
466 | 466 |
467 return (zfs_dozonecheck_impl(dataset, zoned, cr)); | 467 return (zfs_dozonecheck_impl(dataset, zoned, cr)); |
468 } | 468 } |
469 | 469 |
470 static int | 470 static int |
523 | 523 |
524 /* First get the existing dataset label. */ | 524 /* First get the existing dataset label. */ |
525 error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL), | 525 error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL), |
526 1, sizeof (ds_hexsl), &ds_hexsl, NULL); | 526 1, sizeof (ds_hexsl), &ds_hexsl, NULL); |
527 if (error != 0) | 527 if (error != 0) |
528 return (EPERM); | 528 return (SET_ERROR(EPERM)); |
529 | 529 |
530 if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0) | 530 if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0) |
531 new_default = TRUE; | 531 new_default = TRUE; |
532 | 532 |
533 /* The label must be translatable */ | 533 /* The label must be translatable */ |
534 if (!new_default && (hexstr_to_label(strval, &new_sl) != 0)) | 534 if (!new_default && (hexstr_to_label(strval, &new_sl) != 0)) |
535 return (EINVAL); | 535 return (SET_ERROR(EINVAL)); |
536 | 536 |
537 /* | 537 /* |
538 * In a non-global zone, disallow attempts to set a label that | 538 * In a non-global zone, disallow attempts to set a label that |
539 * doesn't match that of the zone; otherwise no other checks | 539 * doesn't match that of the zone; otherwise no other checks |
540 * are needed. | 540 * are needed. |
541 */ | 541 */ |
542 if (!INGLOBALZONE(curproc)) { | 542 if (!INGLOBALZONE(curproc)) { |
543 if (new_default || !blequal(&new_sl, CR_SL(CRED()))) | 543 if (new_default || !blequal(&new_sl, CR_SL(CRED()))) |
544 return (EPERM); | 544 return (SET_ERROR(EPERM)); |
545 return (0); | 545 return (0); |
546 } | 546 } |
547 | 547 |
548 /* | 548 /* |
549 * For global-zone datasets (i.e., those whose zoned property is | 549 * For global-zone datasets (i.e., those whose zoned property is |
550 * "off", verify that the specified new label is valid for the | 550 * "off", verify that the specified new label is valid for the |
551 * global zone. | 551 * global zone. |
552 */ | 552 */ |
553 if (dsl_prop_get_integer(name, | 553 if (dsl_prop_get_integer(name, |
554 zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL)) | 554 zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL)) |
555 return (EPERM); | 555 return (SET_ERROR(EPERM)); |
556 if (!zoned) { | 556 if (!zoned) { |
557 if (zfs_check_global_label(name, strval) != 0) | 557 if (zfs_check_global_label(name, strval) != 0) |
558 return (EPERM); | 558 return (SET_ERROR(EPERM)); |
559 } | 559 } |
560 | 560 |
561 /* | 561 /* |
562 * If the existing dataset label is nondefault, check if the | 562 * If the existing dataset label is nondefault, check if the |
563 * dataset is mounted (label cannot be changed while mounted). | 563 * dataset is mounted (label cannot be changed while mounted). |
573 * (e.g., already mounted, in use, or other error). | 573 * (e.g., already mounted, in use, or other error). |
574 */ | 574 */ |
575 error = dmu_objset_own(name, DMU_OST_ZFS, B_TRUE, | 575 error = dmu_objset_own(name, DMU_OST_ZFS, B_TRUE, |
576 setsl_tag, &os); | 576 setsl_tag, &os); |
577 if (error != 0) | 577 if (error != 0) |
578 return (EPERM); | 578 return (SET_ERROR(EPERM)); |
579 | 579 |
580 dmu_objset_disown(os, setsl_tag); | 580 dmu_objset_disown(os, setsl_tag); |
581 | 581 |
582 if (new_default) { | 582 if (new_default) { |
583 needed_priv = PRIV_FILE_DOWNGRADE_SL; | 583 needed_priv = PRIV_FILE_DOWNGRADE_SL; |
584 goto out_check; | 584 goto out_check; |
585 } | 585 } |
586 | 586 |
587 if (hexstr_to_label(strval, &new_sl) != 0) | 587 if (hexstr_to_label(strval, &new_sl) != 0) |
588 return (EPERM); | 588 return (SET_ERROR(EPERM)); |
589 | 589 |
590 if (blstrictdom(&ds_sl, &new_sl)) | 590 if (blstrictdom(&ds_sl, &new_sl)) |
591 needed_priv = PRIV_FILE_DOWNGRADE_SL; | 591 needed_priv = PRIV_FILE_DOWNGRADE_SL; |
592 else if (blstrictdom(&new_sl, &ds_sl)) | 592 else if (blstrictdom(&new_sl, &ds_sl)) |
593 needed_priv = PRIV_FILE_UPGRADE_SL; | 593 needed_priv = PRIV_FILE_UPGRADE_SL; |
616 case ZFS_PROP_ZONED: | 616 case ZFS_PROP_ZONED: |
617 /* | 617 /* |
618 * Disallow setting of 'zoned' from within a local zone. | 618 * Disallow setting of 'zoned' from within a local zone. |
619 */ | 619 */ |
620 if (!INGLOBALZONE(curproc)) | 620 if (!INGLOBALZONE(curproc)) |
621 return (EPERM); | 621 return (SET_ERROR(EPERM)); |
622 break; | 622 break; |
623 | 623 |
624 case ZFS_PROP_QUOTA: | 624 case ZFS_PROP_QUOTA: |
625 if (!INGLOBALZONE(curproc)) { | 625 if (!INGLOBALZONE(curproc)) { |
626 uint64_t zoned; | 626 uint64_t zoned; |
630 * quota on things *under* (ie. contained by) | 630 * quota on things *under* (ie. contained by) |
631 * the thing they own. | 631 * the thing they own. |
632 */ | 632 */ |
633 if (dsl_prop_get_integer(dsname, "zoned", &zoned, | 633 if (dsl_prop_get_integer(dsname, "zoned", &zoned, |
634 setpoint)) | 634 setpoint)) |
635 return (EPERM); | 635 return (SET_ERROR(EPERM)); |
636 if (!zoned || strlen(dsname) <= strlen(setpoint)) | 636 if (!zoned || strlen(dsname) <= strlen(setpoint)) |
637 return (EPERM); | 637 return (SET_ERROR(EPERM)); |
638 } | 638 } |
639 break; | 639 break; |
640 | 640 |
641 case ZFS_PROP_MLSLABEL: | 641 case ZFS_PROP_MLSLABEL: |
642 if (!is_system_labeled()) | 642 if (!is_system_labeled()) |
643 return (EPERM); | 643 return (SET_ERROR(EPERM)); |
644 | 644 |
645 if (nvpair_value_string(propval, &strval) == 0) { | 645 if (nvpair_value_string(propval, &strval) == 0) { |
646 int err; | 646 int err; |
647 | 647 |
648 err = zfs_set_slabel_policy(dsname, strval, CRED()); | 648 err = zfs_set_slabel_policy(dsname, strval, CRED()); |
693 * Generate the current snapshot name from the given objsetid, then | 693 * Generate the current snapshot name from the given objsetid, then |
694 * use that name for the secpolicy/zone checks. | 694 * use that name for the secpolicy/zone checks. |
695 */ | 695 */ |
696 cp = strchr(zc->zc_name, '@'); | 696 cp = strchr(zc->zc_name, '@'); |
697 if (cp == NULL) | 697 if (cp == NULL) |
698 return (EINVAL); | 698 return (SET_ERROR(EINVAL)); |
699 error = dsl_pool_hold(zc->zc_name, FTAG, &dp); | 699 error = dsl_pool_hold(zc->zc_name, FTAG, &dp); |
700 if (error != 0) | 700 if (error != 0) |
701 return (error); | 701 return (error); |
702 | 702 |
703 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds); | 703 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds); |
739 | 739 |
740 if (vp->v_vfsp->vfs_fstype != zfsfstype || | 740 if (vp->v_vfsp->vfs_fstype != zfsfstype || |
741 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource), | 741 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource), |
742 zc->zc_name) != 0)) { | 742 zc->zc_name) != 0)) { |
743 VN_RELE(vp); | 743 VN_RELE(vp); |
744 return (EPERM); | 744 return (SET_ERROR(EPERM)); |
745 } | 745 } |
746 | 746 |
747 VN_RELE(vp); | 747 VN_RELE(vp); |
748 return (dsl_deleg_access(zc->zc_name, | 748 return (dsl_deleg_access(zc->zc_name, |
749 ZFS_DELEG_PERM_SHARE, cr)); | 749 ZFS_DELEG_PERM_SHARE, cr)); |
751 | 751 |
752 int | 752 int |
753 zfs_secpolicy_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) | 753 zfs_secpolicy_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) |
754 { | 754 { |
755 if (!INGLOBALZONE(curproc)) | 755 if (!INGLOBALZONE(curproc)) |
756 return (EPERM); | 756 return (SET_ERROR(EPERM)); |
757 | 757 |
758 if (secpolicy_nfs(cr) == 0) { | 758 if (secpolicy_nfs(cr) == 0) { |
759 return (0); | 759 return (0); |
760 } else { | 760 } else { |
761 return (zfs_secpolicy_deleg_share(zc, innvl, cr)); | 761 return (zfs_secpolicy_deleg_share(zc, innvl, cr)); |
764 | 764 |
765 int | 765 int |
766 zfs_secpolicy_smb_acl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) | 766 zfs_secpolicy_smb_acl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) |
767 { | 767 { |
768 if (!INGLOBALZONE(curproc)) | 768 if (!INGLOBALZONE(curproc)) |
769 return (EPERM); | 769 return (SET_ERROR(EPERM)); |
770 | 770 |
771 if (secpolicy_smb(cr) == 0) { | 771 if (secpolicy_smb(cr) == 0) { |
772 return (0); | 772 return (0); |
773 } else { | 773 } else { |
774 return (zfs_secpolicy_deleg_share(zc, innvl, cr)); | 774 return (zfs_secpolicy_deleg_share(zc, innvl, cr)); |
788 if (cp != NULL) { | 788 if (cp != NULL) { |
789 cp[0] = '\0'; | 789 cp[0] = '\0'; |
790 } else { | 790 } else { |
791 cp = strrchr(parent, '/'); | 791 cp = strrchr(parent, '/'); |
792 if (cp == NULL) | 792 if (cp == NULL) |
793 return (ENOENT); | 793 return (SET_ERROR(ENOENT)); |
794 cp[0] = '\0'; | 794 cp[0] = '\0'; |
795 } | 795 } |
796 | 796 |
797 return (0); | 797 return (0); |
798 } | 798 } |
827 nvlist_t *snaps; | 827 nvlist_t *snaps; |
828 nvpair_t *pair, *nextpair; | 828 nvpair_t *pair, *nextpair; |
829 int error = 0; | 829 int error = 0; |
830 | 830 |
831 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0) | 831 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0) |
832 return (EINVAL); | 832 return (SET_ERROR(EINVAL)); |
833 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; | 833 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; |
834 pair = nextpair) { | 834 pair = nextpair) { |
835 dsl_pool_t *dp; | 835 dsl_pool_t *dp; |
836 dsl_dataset_t *ds; | 836 dsl_dataset_t *ds; |
837 | 837 |
985 nvlist_t *snaps; | 985 nvlist_t *snaps; |
986 int error = 0; | 986 int error = 0; |
987 nvpair_t *pair; | 987 nvpair_t *pair; |
988 | 988 |
989 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0) | 989 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0) |
990 return (EINVAL); | 990 return (SET_ERROR(EINVAL)); |
991 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; | 991 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; |
992 pair = nvlist_next_nvpair(snaps, pair)) { | 992 pair = nvlist_next_nvpair(snaps, pair)) { |
993 char *name = nvpair_name(pair); | 993 char *name = nvpair_name(pair); |
994 char *atp = strchr(name, '@'); | 994 char *atp = strchr(name, '@'); |
995 | 995 |
996 if (atp == NULL) { | 996 if (atp == NULL) { |
997 error = EINVAL; | 997 error = SET_ERROR(EINVAL); |
998 break; | 998 break; |
999 } | 999 } |
1000 *atp = '\0'; | 1000 *atp = '\0'; |
1001 error = zfs_secpolicy_snapshot_perms(name, cr); | 1001 error = zfs_secpolicy_snapshot_perms(name, cr); |
1002 *atp = '@'; | 1002 *atp = '@'; |
1013 /* | 1013 /* |
1014 * Even root must have a proper TSD so that we know what pool | 1014 * Even root must have a proper TSD so that we know what pool |
1015 * to log to. | 1015 * to log to. |
1016 */ | 1016 */ |
1017 if (tsd_get(zfs_allow_log_key) == NULL) | 1017 if (tsd_get(zfs_allow_log_key) == NULL) |
1018 return (EPERM); | 1018 return (SET_ERROR(EPERM)); |
1019 return (0); | 1019 return (0); |
1020 } | 1020 } |
1021 | 1021 |
1022 static int | 1022 static int |
1023 zfs_secpolicy_create_clone(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) | 1023 zfs_secpolicy_create_clone(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) |
1050 /* ARGSUSED */ | 1050 /* ARGSUSED */ |
1051 static int | 1051 static int |
1052 zfs_secpolicy_config(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) | 1052 zfs_secpolicy_config(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr) |
1053 { | 1053 { |
1054 if (secpolicy_sys_config(cr, B_FALSE) != 0) | 1054 if (secpolicy_sys_config(cr, B_FALSE) != 0) |
1055 return (EPERM); | 1055 return (SET_ERROR(EPERM)); |
1056 | 1056 |
1057 return (0); | 1057 return (0); |
1058 } | 1058 } |
1059 | 1059 |
1060 /* | 1060 /* |
1089 { | 1089 { |
1090 zfs_prop_t prop = zfs_name_to_prop(zc->zc_value); | 1090 zfs_prop_t prop = zfs_name_to_prop(zc->zc_value); |
1091 | 1091 |
1092 if (prop == ZPROP_INVAL) { | 1092 if (prop == ZPROP_INVAL) { |
1093 if (!zfs_prop_user(zc->zc_value)) | 1093 if (!zfs_prop_user(zc->zc_value)) |
1094 return (EINVAL); | 1094 return (SET_ERROR(EINVAL)); |
1095 return (zfs_secpolicy_write_perms(zc->zc_name, | 1095 return (zfs_secpolicy_write_perms(zc->zc_name, |
1096 ZFS_DELEG_PERM_USERPROP, cr)); | 1096 ZFS_DELEG_PERM_USERPROP, cr)); |
1097 } else { | 1097 } else { |
1098 return (zfs_secpolicy_setprop(zc->zc_name, prop, | 1098 return (zfs_secpolicy_setprop(zc->zc_name, prop, |
1099 NULL, cr)); | 1099 NULL, cr)); |
1106 int err = zfs_secpolicy_read(zc, innvl, cr); | 1106 int err = zfs_secpolicy_read(zc, innvl, cr); |
1107 if (err) | 1107 if (err) |
1108 return (err); | 1108 return (err); |
1109 | 1109 |
1110 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS) | 1110 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS) |
1111 return (EINVAL); | 1111 return (SET_ERROR(EINVAL)); |
1112 | 1112 |
1113 if (zc->zc_value[0] == 0) { | 1113 if (zc->zc_value[0] == 0) { |
1114 /* | 1114 /* |
1115 * They are asking about a posix uid/gid. If it's | 1115 * They are asking about a posix uid/gid. If it's |
1116 * themself, allow it. | 1116 * themself, allow it. |
1135 int err = zfs_secpolicy_read(zc, innvl, cr); | 1135 int err = zfs_secpolicy_read(zc, innvl, cr); |
1136 if (err) | 1136 if (err) |
1137 return (err); | 1137 return (err); |
1138 | 1138 |
1139 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS) | 1139 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS) |
1140 return (EINVAL); | 1140 return (SET_ERROR(EINVAL)); |
1141 | 1141 |
1142 return (zfs_secpolicy_write_perms(zc->zc_name, | 1142 return (zfs_secpolicy_write_perms(zc->zc_name, |
1143 userquota_perms[zc->zc_objset_type], cr)); | 1143 userquota_perms[zc->zc_objset_type], cr)); |
1144 } | 1144 } |
1145 | 1145 |
1159 nvlist_t *holds; | 1159 nvlist_t *holds; |
1160 int error; | 1160 int error; |
1161 | 1161 |
1162 error = nvlist_lookup_nvlist(innvl, "holds", &holds); | 1162 error = nvlist_lookup_nvlist(innvl, "holds", &holds); |
1163 if (error != 0) | 1163 if (error != 0) |
1164 return (EINVAL); | 1164 return (SET_ERROR(EINVAL)); |
1165 | 1165 |
1166 for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL; | 1166 for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL; |
1167 pair = nvlist_next_nvpair(holds, pair)) { | 1167 pair = nvlist_next_nvpair(holds, pair)) { |
1168 char fsname[MAXNAMELEN]; | 1168 char fsname[MAXNAMELEN]; |
1169 error = dmu_fsname(nvpair_name(pair), fsname); | 1169 error = dmu_fsname(nvpair_name(pair), fsname); |
1237 | 1237 |
1238 /* | 1238 /* |
1239 * Read in and unpack the user-supplied nvlist. | 1239 * Read in and unpack the user-supplied nvlist. |
1240 */ | 1240 */ |
1241 if (size == 0) | 1241 if (size == 0) |
1242 return (EINVAL); | 1242 return (SET_ERROR(EINVAL)); |
1243 | 1243 |
1244 packed = kmem_alloc(size, KM_SLEEP); | 1244 packed = kmem_alloc(size, KM_SLEEP); |
1245 | 1245 |
1246 if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size, | 1246 if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size, |
1247 iflag)) != 0) { | 1247 iflag)) != 0) { |
1276 if (size > max) { | 1276 if (size > max) { |
1277 nvpair_t *more_errors; | 1277 nvpair_t *more_errors; |
1278 int n = 0; | 1278 int n = 0; |
1279 | 1279 |
1280 if (max < 1024) | 1280 if (max < 1024) |
1281 return (ENOMEM); | 1281 return (SET_ERROR(ENOMEM)); |
1282 | 1282 |
1283 fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, 0); | 1283 fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, 0); |
1284 more_errors = nvlist_prev_nvpair(errors, NULL); | 1284 more_errors = nvlist_prev_nvpair(errors, NULL); |
1285 | 1285 |
1286 do { | 1286 do { |
1307 size_t size; | 1307 size_t size; |
1308 | 1308 |
1309 size = fnvlist_size(nvl); | 1309 size = fnvlist_size(nvl); |
1310 | 1310 |
1311 if (size > zc->zc_nvlist_dst_size) { | 1311 if (size > zc->zc_nvlist_dst_size) { |
1312 error = ENOMEM; | 1312 error = SET_ERROR(ENOMEM); |
1313 } else { | 1313 } else { |
1314 packed = fnvlist_pack(nvl, &size); | 1314 packed = fnvlist_pack(nvl, &size); |
1315 if (ddi_copyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst, | 1315 if (ddi_copyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst, |
1316 size, zc->zc_iflags) != 0) | 1316 size, zc->zc_iflags) != 0) |
1317 error = EFAULT; | 1317 error = SET_ERROR(EFAULT); |
1318 fnvlist_pack_free(packed, size); | 1318 fnvlist_pack_free(packed, size); |
1319 } | 1319 } |
1320 | 1320 |
1321 zc->zc_nvlist_dst_size = size; | 1321 zc->zc_nvlist_dst_size = size; |
1322 zc->zc_nvlist_dst_filled = B_TRUE; | 1322 zc->zc_nvlist_dst_filled = B_TRUE; |
1332 error = dmu_objset_hold(dsname, FTAG, &os); | 1332 error = dmu_objset_hold(dsname, FTAG, &os); |
1333 if (error != 0) | 1333 if (error != 0) |
1334 return (error); | 1334 return (error); |
1335 if (dmu_objset_type(os) != DMU_OST_ZFS) { | 1335 if (dmu_objset_type(os) != DMU_OST_ZFS) { |
1336 dmu_objset_rele(os, FTAG); | 1336 dmu_objset_rele(os, FTAG); |
1337 return (EINVAL); | 1337 return (SET_ERROR(EINVAL)); |
1338 } | 1338 } |
1339 | 1339 |
1340 mutex_enter(&os->os_user_ptr_lock); | 1340 mutex_enter(&os->os_user_ptr_lock); |
1341 *zfvp = dmu_objset_get_user(os); | 1341 *zfvp = dmu_objset_get_user(os); |
1342 if (*zfvp) { | 1342 if (*zfvp) { |
1343 VFS_HOLD((*zfvp)->z_vfs); | 1343 VFS_HOLD((*zfvp)->z_vfs); |
1344 } else { | 1344 } else { |
1345 error = ESRCH; | 1345 error = SET_ERROR(ESRCH); |
1346 } | 1346 } |
1347 mutex_exit(&os->os_user_ptr_lock); | 1347 mutex_exit(&os->os_user_ptr_lock); |
1348 dmu_objset_rele(os, FTAG); | 1348 dmu_objset_rele(os, FTAG); |
1349 return (error); | 1349 return (error); |
1350 } | 1350 } |
1370 * XXX we could probably try again, since the unmounting | 1370 * XXX we could probably try again, since the unmounting |
1371 * thread should be just about to disassociate the | 1371 * thread should be just about to disassociate the |
1372 * objset from the zfsvfs. | 1372 * objset from the zfsvfs. |
1373 */ | 1373 */ |
1374 rrw_exit(&(*zfvp)->z_teardown_lock, tag); | 1374 rrw_exit(&(*zfvp)->z_teardown_lock, tag); |
1375 return (EBUSY); | 1375 return (SET_ERROR(EBUSY)); |
1376 } | 1376 } |
1377 } | 1377 } |
1378 return (error); | 1378 return (error); |
1379 } | 1379 } |
1380 | 1380 |
1415 uint64_t version = SPA_VERSION; | 1415 uint64_t version = SPA_VERSION; |
1416 | 1416 |
1417 (void) nvlist_lookup_uint64(props, | 1417 (void) nvlist_lookup_uint64(props, |
1418 zpool_prop_to_name(ZPOOL_PROP_VERSION), &version); | 1418 zpool_prop_to_name(ZPOOL_PROP_VERSION), &version); |
1419 if (!SPA_VERSION_IS_SUPPORTED(version)) { | 1419 if (!SPA_VERSION_IS_SUPPORTED(version)) { |
1420 error = EINVAL; | 1420 error = SET_ERROR(EINVAL); |
1421 goto pool_props_bad; | 1421 goto pool_props_bad; |
1422 } | 1422 } |
1423 (void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl); | 1423 (void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl); |
1424 if (nvl) { | 1424 if (nvl) { |
1425 error = nvlist_dup(nvl, &rootprops, KM_SLEEP); | 1425 error = nvlist_dup(nvl, &rootprops, KM_SLEEP); |
1484 return (error); | 1484 return (error); |
1485 } | 1485 } |
1486 | 1486 |
1487 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 || | 1487 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 || |
1488 guid != zc->zc_guid) | 1488 guid != zc->zc_guid) |
1489 error = EINVAL; | 1489 error = SET_ERROR(EINVAL); |
1490 else | 1490 else |
1491 error = spa_import(zc->zc_name, config, props, zc->zc_cookie); | 1491 error = spa_import(zc->zc_name, config, props, zc->zc_cookie); |
1492 | 1492 |
1493 if (zc->zc_nvlist_dst != 0) { | 1493 if (zc->zc_nvlist_dst != 0) { |
1494 int err; | 1494 int err; |
1524 { | 1524 { |
1525 nvlist_t *configs; | 1525 nvlist_t *configs; |
1526 int error; | 1526 int error; |
1527 | 1527 |
1528 if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL) | 1528 if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL) |
1529 return (EEXIST); | 1529 return (SET_ERROR(EEXIST)); |
1530 | 1530 |
1531 error = put_nvlist(zc, configs); | 1531 error = put_nvlist(zc, configs); |
1532 | 1532 |
1533 nvlist_free(configs); | 1533 nvlist_free(configs); |
1534 | 1534 |
1588 config = spa_tryimport(tryconfig); | 1588 config = spa_tryimport(tryconfig); |
1589 | 1589 |
1590 nvlist_free(tryconfig); | 1590 nvlist_free(tryconfig); |
1591 | 1591 |
1592 if (config == NULL) | 1592 if (config == NULL) |
1593 return (EINVAL); | 1593 return (SET_ERROR(EINVAL)); |
1594 | 1594 |
1595 error = put_nvlist(zc, config); | 1595 error = put_nvlist(zc, config); |
1596 nvlist_free(config); | 1596 nvlist_free(config); |
1597 | 1597 |
1598 return (error); | 1598 return (error); |
1646 return (error); | 1646 return (error); |
1647 | 1647 |
1648 if (zc->zc_cookie < spa_version(spa) || | 1648 if (zc->zc_cookie < spa_version(spa) || |
1649 !SPA_VERSION_IS_SUPPORTED(zc->zc_cookie)) { | 1649 !SPA_VERSION_IS_SUPPORTED(zc->zc_cookie)) { |
1650 spa_close(spa, FTAG); | 1650 spa_close(spa, FTAG); |
1651 return (EINVAL); | 1651 return (SET_ERROR(EINVAL)); |
1652 } | 1652 } |
1653 | 1653 |
1654 spa_upgrade(spa, zc->zc_cookie); | 1654 spa_upgrade(spa, zc->zc_cookie); |
1655 spa_close(spa, FTAG); | 1655 spa_close(spa, FTAG); |
1656 | 1656 |
1664 char *hist_buf; | 1664 char *hist_buf; |
1665 uint64_t size; | 1665 uint64_t size; |
1666 int error; | 1666 int error; |
1667 | 1667 |
1668 if ((size = zc->zc_history_len) == 0) | 1668 if ((size = zc->zc_history_len) == 0) |
1669 return (EINVAL); | 1669 return (SET_ERROR(EINVAL)); |
1670 | 1670 |
1671 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) | 1671 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) |
1672 return (error); | 1672 return (error); |
1673 | 1673 |
1674 if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) { | 1674 if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) { |
1675 spa_close(spa, FTAG); | 1675 spa_close(spa, FTAG); |
1676 return (ENOTSUP); | 1676 return (SET_ERROR(ENOTSUP)); |
1677 } | 1677 } |
1678 | 1678 |
1679 hist_buf = kmem_alloc(size, KM_SLEEP); | 1679 hist_buf = kmem_alloc(size, KM_SLEEP); |
1680 if ((error = spa_history_get(spa, &zc->zc_history_offset, | 1680 if ((error = spa_history_get(spa, &zc->zc_history_offset, |
1681 &zc->zc_history_len, hist_buf)) == 0) { | 1681 &zc->zc_history_len, hist_buf)) == 0) { |
1726 /* XXX reading from objset not owned */ | 1726 /* XXX reading from objset not owned */ |
1727 if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0) | 1727 if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0) |
1728 return (error); | 1728 return (error); |
1729 if (dmu_objset_type(os) != DMU_OST_ZFS) { | 1729 if (dmu_objset_type(os) != DMU_OST_ZFS) { |
1730 dmu_objset_rele(os, FTAG); | 1730 dmu_objset_rele(os, FTAG); |
1731 return (EINVAL); | 1731 return (SET_ERROR(EINVAL)); |
1732 } | 1732 } |
1733 error = zfs_obj_to_path(os, zc->zc_obj, zc->zc_value, | 1733 error = zfs_obj_to_path(os, zc->zc_obj, zc->zc_value, |
1734 sizeof (zc->zc_value)); | 1734 sizeof (zc->zc_value)); |
1735 dmu_objset_rele(os, FTAG); | 1735 dmu_objset_rele(os, FTAG); |
1736 | 1736 |
1755 /* XXX reading from objset not owned */ | 1755 /* XXX reading from objset not owned */ |
1756 if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0) | 1756 if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0) |
1757 return (error); | 1757 return (error); |
1758 if (dmu_objset_type(os) != DMU_OST_ZFS) { | 1758 if (dmu_objset_type(os) != DMU_OST_ZFS) { |
1759 dmu_objset_rele(os, FTAG); | 1759 dmu_objset_rele(os, FTAG); |
1760 return (EINVAL); | 1760 return (SET_ERROR(EINVAL)); |
1761 } | 1761 } |
1762 error = zfs_obj_to_stats(os, zc->zc_obj, &zc->zc_stat, zc->zc_value, | 1762 error = zfs_obj_to_stats(os, zc->zc_obj, &zc->zc_stat, zc->zc_value, |
1763 sizeof (zc->zc_value)); | 1763 sizeof (zc->zc_value)); |
1764 dmu_objset_rele(os, FTAG); | 1764 dmu_objset_rele(os, FTAG); |
1765 | 1765 |
1797 * l2cache and spare devices are ok to be added to a rootpool. | 1797 * l2cache and spare devices are ok to be added to a rootpool. |
1798 */ | 1798 */ |
1799 if (spa_bootfs(spa) != 0 && nl2cache == 0 && nspares == 0) { | 1799 if (spa_bootfs(spa) != 0 && nl2cache == 0 && nspares == 0) { |
1800 nvlist_free(config); | 1800 nvlist_free(config); |
1801 spa_close(spa, FTAG); | 1801 spa_close(spa, FTAG); |
1802 return (EDOM); | 1802 return (SET_ERROR(EDOM)); |
1803 } | 1803 } |
1804 | 1804 |
1805 if (error == 0) { | 1805 if (error == 0) { |
1806 error = spa_vdev_add(spa, config); | 1806 error = spa_vdev_add(spa, config); |
1807 nvlist_free(config); | 1807 nvlist_free(config); |
1863 | 1863 |
1864 error = vdev_degrade(spa, zc->zc_guid, zc->zc_obj); | 1864 error = vdev_degrade(spa, zc->zc_guid, zc->zc_obj); |
1865 break; | 1865 break; |
1866 | 1866 |
1867 default: | 1867 default: |
1868 error = EINVAL; | 1868 error = SET_ERROR(EINVAL); |
1869 } | 1869 } |
1870 zc->zc_cookie = newstate; | 1870 zc->zc_cookie = newstate; |
1871 spa_close(spa, FTAG); | 1871 spa_close(spa, FTAG); |
1872 return (error); | 1872 return (error); |
1873 } | 1873 } |
2057 * Without this check, we would return local property values if the | 2057 * Without this check, we would return local property values if the |
2058 * caller has not already received properties on or after | 2058 * caller has not already received properties on or after |
2059 * SPA_VERSION_RECVD_PROPS. | 2059 * SPA_VERSION_RECVD_PROPS. |
2060 */ | 2060 */ |
2061 if (!dsl_prop_get_hasrecvd(zc->zc_name)) | 2061 if (!dsl_prop_get_hasrecvd(zc->zc_name)) |
2062 return (ENOTSUP); | 2062 return (SET_ERROR(ENOTSUP)); |
2063 | 2063 |
2064 if (zc->zc_nvlist_dst != 0 && | 2064 if (zc->zc_nvlist_dst != 0 && |
2065 (error = dsl_prop_get_received(zc->zc_name, &nv)) == 0) { | 2065 (error = dsl_prop_get_received(zc->zc_name, &nv)) == 0) { |
2066 error = put_nvlist(zc, nv); | 2066 error = put_nvlist(zc, nv); |
2067 nvlist_free(nv); | 2067 nvlist_free(nv); |
2123 (err = nvl_add_zplprop(os, nv, ZFS_PROP_UTF8ONLY)) == 0 && | 2123 (err = nvl_add_zplprop(os, nv, ZFS_PROP_UTF8ONLY)) == 0 && |
2124 (err = nvl_add_zplprop(os, nv, ZFS_PROP_CASE)) == 0) | 2124 (err = nvl_add_zplprop(os, nv, ZFS_PROP_CASE)) == 0) |
2125 err = put_nvlist(zc, nv); | 2125 err = put_nvlist(zc, nv); |
2126 nvlist_free(nv); | 2126 nvlist_free(nv); |
2127 } else { | 2127 } else { |
2128 err = ENOENT; | 2128 err = SET_ERROR(ENOENT); |
2129 } | 2129 } |
2130 dmu_objset_rele(os, FTAG); | 2130 dmu_objset_rele(os, FTAG); |
2131 return (err); | 2131 return (err); |
2132 } | 2132 } |
2133 | 2133 |
2170 size_t orig_len = strlen(zc->zc_name); | 2170 size_t orig_len = strlen(zc->zc_name); |
2171 | 2171 |
2172 top: | 2172 top: |
2173 if (error = dmu_objset_hold(zc->zc_name, FTAG, &os)) { | 2173 if (error = dmu_objset_hold(zc->zc_name, FTAG, &os)) { |
2174 if (error == ENOENT) | 2174 if (error == ENOENT) |
2175 error = ESRCH; | 2175 error = SET_ERROR(ESRCH); |
2176 return (error); | 2176 return (error); |
2177 } | 2177 } |
2178 | 2178 |
2179 p = strrchr(zc->zc_name, '/'); | 2179 p = strrchr(zc->zc_name, '/'); |
2180 if (p == NULL || p[1] != '\0') | 2180 if (p == NULL || p[1] != '\0') |
2184 do { | 2184 do { |
2185 error = dmu_dir_list_next(os, | 2185 error = dmu_dir_list_next(os, |
2186 sizeof (zc->zc_name) - (p - zc->zc_name), p, | 2186 sizeof (zc->zc_name) - (p - zc->zc_name), p, |
2187 NULL, &zc->zc_cookie); | 2187 NULL, &zc->zc_cookie); |
2188 if (error == ENOENT) | 2188 if (error == ENOENT) |
2189 error = ESRCH; | 2189 error = SET_ERROR(ESRCH); |
2190 } while (error == 0 && dataset_name_hidden(zc->zc_name)); | 2190 } while (error == 0 && dataset_name_hidden(zc->zc_name)); |
2191 dmu_objset_rele(os, FTAG); | 2191 dmu_objset_rele(os, FTAG); |
2192 | 2192 |
2193 /* | 2193 /* |
2194 * If it's an internal dataset (ie. with a '$' in its name), | 2194 * If it's an internal dataset (ie. with a '$' in its name), |
2232 * A dataset name of maximum length cannot have any snapshots, | 2232 * A dataset name of maximum length cannot have any snapshots, |
2233 * so exit immediately. | 2233 * so exit immediately. |
2234 */ | 2234 */ |
2235 if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) { | 2235 if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) { |
2236 dmu_objset_rele(os, FTAG); | 2236 dmu_objset_rele(os, FTAG); |
2237 return (ESRCH); | 2237 return (SET_ERROR(ESRCH)); |
2238 } | 2238 } |
2239 | 2239 |
2240 error = dmu_snapshot_list_next(os, | 2240 error = dmu_snapshot_list_next(os, |
2241 sizeof (zc->zc_name) - strlen(zc->zc_name), | 2241 sizeof (zc->zc_name) - strlen(zc->zc_name), |
2242 zc->zc_name + strlen(zc->zc_name), &zc->zc_obj, &zc->zc_cookie, | 2242 zc->zc_name + strlen(zc->zc_name), &zc->zc_obj, &zc->zc_cookie, |
2254 if (error == 0) | 2254 if (error == 0) |
2255 error = zfs_ioc_objset_stats_impl(zc, ossnap); | 2255 error = zfs_ioc_objset_stats_impl(zc, ossnap); |
2256 dsl_dataset_rele(ds, FTAG); | 2256 dsl_dataset_rele(ds, FTAG); |
2257 } | 2257 } |
2258 } else if (error == ENOENT) { | 2258 } else if (error == ENOENT) { |
2259 error = ESRCH; | 2259 error = SET_ERROR(ESRCH); |
2260 } | 2260 } |
2261 | 2261 |
2262 dmu_objset_rele(os, FTAG); | 2262 dmu_objset_rele(os, FTAG); |
2263 /* if we failed, undo the @ that we tacked on to zc_name */ | 2263 /* if we failed, undo the @ that we tacked on to zc_name */ |
2264 if (error != 0) | 2264 if (error != 0) |
2283 if (nvpair_type(pair) == DATA_TYPE_NVLIST) { | 2283 if (nvpair_type(pair) == DATA_TYPE_NVLIST) { |
2284 nvlist_t *attrs; | 2284 nvlist_t *attrs; |
2285 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0); | 2285 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0); |
2286 if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE, | 2286 if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE, |
2287 &pair) != 0) | 2287 &pair) != 0) |
2288 return (EINVAL); | 2288 return (SET_ERROR(EINVAL)); |
2289 } | 2289 } |
2290 | 2290 |
2291 /* | 2291 /* |
2292 * A correctly constructed propname is encoded as | 2292 * A correctly constructed propname is encoded as |
2293 * userquota@<rid>-<domain>. | 2293 * userquota@<rid>-<domain>. |
2294 */ | 2294 */ |
2295 if ((dash = strchr(propname, '-')) == NULL || | 2295 if ((dash = strchr(propname, '-')) == NULL || |
2296 nvpair_value_uint64_array(pair, &valary, &vallen) != 0 || | 2296 nvpair_value_uint64_array(pair, &valary, &vallen) != 0 || |
2297 vallen != 3) | 2297 vallen != 3) |
2298 return (EINVAL); | 2298 return (SET_ERROR(EINVAL)); |
2299 | 2299 |
2300 domain = dash + 1; | 2300 domain = dash + 1; |
2301 type = valary[0]; | 2301 type = valary[0]; |
2302 rid = valary[1]; | 2302 rid = valary[1]; |
2303 quota = valary[2]; | 2303 quota = valary[2]; |
2455 if (nvpair_type(pair) == DATA_TYPE_NVLIST) { | 2455 if (nvpair_type(pair) == DATA_TYPE_NVLIST) { |
2456 nvlist_t *attrs; | 2456 nvlist_t *attrs; |
2457 attrs = fnvpair_value_nvlist(pair); | 2457 attrs = fnvpair_value_nvlist(pair); |
2458 if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE, | 2458 if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE, |
2459 &propval) != 0) | 2459 &propval) != 0) |
2460 err = EINVAL; | 2460 err = SET_ERROR(EINVAL); |
2461 } | 2461 } |
2462 | 2462 |
2463 /* Validate value type */ | 2463 /* Validate value type */ |
2464 if (err == 0 && prop == ZPROP_INVAL) { | 2464 if (err == 0 && prop == ZPROP_INVAL) { |
2465 if (zfs_prop_user(propname)) { | 2465 if (zfs_prop_user(propname)) { |
2466 if (nvpair_type(propval) != DATA_TYPE_STRING) | 2466 if (nvpair_type(propval) != DATA_TYPE_STRING) |
2467 err = EINVAL; | 2467 err = SET_ERROR(EINVAL); |
2468 } else if (zfs_prop_userquota(propname)) { | 2468 } else if (zfs_prop_userquota(propname)) { |
2469 if (nvpair_type(propval) != | 2469 if (nvpair_type(propval) != |
2470 DATA_TYPE_UINT64_ARRAY) | 2470 DATA_TYPE_UINT64_ARRAY) |
2471 err = EINVAL; | 2471 err = SET_ERROR(EINVAL); |
2472 } else { | 2472 } else { |
2473 err = EINVAL; | 2473 err = SET_ERROR(EINVAL); |
2474 } | 2474 } |
2475 } else if (err == 0) { | 2475 } else if (err == 0) { |
2476 if (nvpair_type(propval) == DATA_TYPE_STRING) { | 2476 if (nvpair_type(propval) == DATA_TYPE_STRING) { |
2477 if (zfs_prop_get_type(prop) != PROP_TYPE_STRING) | 2477 if (zfs_prop_get_type(prop) != PROP_TYPE_STRING) |
2478 err = EINVAL; | 2478 err = SET_ERROR(EINVAL); |
2479 } else if (nvpair_type(propval) == DATA_TYPE_UINT64) { | 2479 } else if (nvpair_type(propval) == DATA_TYPE_UINT64) { |
2480 const char *unused; | 2480 const char *unused; |
2481 | 2481 |
2482 intval = fnvpair_value_uint64(propval); | 2482 intval = fnvpair_value_uint64(propval); |
2483 | 2483 |
2484 switch (zfs_prop_get_type(prop)) { | 2484 switch (zfs_prop_get_type(prop)) { |
2485 case PROP_TYPE_NUMBER: | 2485 case PROP_TYPE_NUMBER: |
2486 break; | 2486 break; |
2487 case PROP_TYPE_STRING: | 2487 case PROP_TYPE_STRING: |
2488 err = EINVAL; | 2488 err = SET_ERROR(EINVAL); |
2489 break; | 2489 break; |
2490 case PROP_TYPE_INDEX: | 2490 case PROP_TYPE_INDEX: |
2491 if (zfs_prop_index_to_string(prop, | 2491 if (zfs_prop_index_to_string(prop, |
2492 intval, &unused) != 0) | 2492 intval, &unused) != 0) |
2493 err = EINVAL; | 2493 err = SET_ERROR(EINVAL); |
2494 break; | 2494 break; |
2495 default: | 2495 default: |
2496 cmn_err(CE_PANIC, | 2496 cmn_err(CE_PANIC, |
2497 "unknown property type"); | 2497 "unknown property type"); |
2498 } | 2498 } |
2499 } else { | 2499 } else { |
2500 err = EINVAL; | 2500 err = SET_ERROR(EINVAL); |
2501 } | 2501 } |
2502 } | 2502 } |
2503 | 2503 |
2504 /* Validate permissions */ | 2504 /* Validate permissions */ |
2505 if (err == 0) | 2505 if (err == 0) |
2592 const char *propname = nvpair_name(pair); | 2592 const char *propname = nvpair_name(pair); |
2593 char *valstr; | 2593 char *valstr; |
2594 | 2594 |
2595 if (!zfs_prop_user(propname) || | 2595 if (!zfs_prop_user(propname) || |
2596 nvpair_type(pair) != DATA_TYPE_STRING) | 2596 nvpair_type(pair) != DATA_TYPE_STRING) |
2597 return (EINVAL); | 2597 return (SET_ERROR(EINVAL)); |
2598 | 2598 |
2599 if (error = zfs_secpolicy_write_perms(fsname, | 2599 if (error = zfs_secpolicy_write_perms(fsname, |
2600 ZFS_DELEG_PERM_USERPROP, CRED())) | 2600 ZFS_DELEG_PERM_USERPROP, CRED())) |
2601 return (error); | 2601 return (error); |
2602 | 2602 |
2603 if (strlen(propname) >= ZAP_MAXNAMELEN) | 2603 if (strlen(propname) >= ZAP_MAXNAMELEN) |
2604 return (ENAMETOOLONG); | 2604 return (SET_ERROR(ENAMETOOLONG)); |
2605 | 2605 |
2606 VERIFY(nvpair_value_string(pair, &valstr) == 0); | 2606 VERIFY(nvpair_value_string(pair, &valstr) == 0); |
2607 if (strlen(valstr) >= ZAP_MAXVALUELEN) | 2607 if (strlen(valstr) >= ZAP_MAXVALUELEN) |
2608 return (E2BIG); | 2608 return (E2BIG); |
2609 } | 2609 } |
2723 * zfs_prop_set_special() expects properties in the form of an | 2723 * zfs_prop_set_special() expects properties in the form of an |
2724 * nvpair with type info. | 2724 * nvpair with type info. |
2725 */ | 2725 */ |
2726 if (prop == ZPROP_INVAL) { | 2726 if (prop == ZPROP_INVAL) { |
2727 if (!zfs_prop_user(propname)) | 2727 if (!zfs_prop_user(propname)) |
2728 return (EINVAL); | 2728 return (SET_ERROR(EINVAL)); |
2729 | 2729 |
2730 type = PROP_TYPE_STRING; | 2730 type = PROP_TYPE_STRING; |
2731 } else if (prop == ZFS_PROP_VOLSIZE || | 2731 } else if (prop == ZFS_PROP_VOLSIZE || |
2732 prop == ZFS_PROP_VERSION) { | 2732 prop == ZFS_PROP_VERSION) { |
2733 return (EINVAL); | 2733 return (SET_ERROR(EINVAL)); |
2734 } else { | 2734 } else { |
2735 type = zfs_prop_get_type(prop); | 2735 type = zfs_prop_get_type(prop); |
2736 } | 2736 } |
2737 | 2737 |
2738 VERIFY(nvlist_alloc(&dummy, NV_UNIQUE_NAME, KM_SLEEP) == 0); | 2738 VERIFY(nvlist_alloc(&dummy, NV_UNIQUE_NAME, KM_SLEEP) == 0); |
2745 case PROP_TYPE_INDEX: | 2745 case PROP_TYPE_INDEX: |
2746 VERIFY(0 == nvlist_add_uint64(dummy, propname, 0)); | 2746 VERIFY(0 == nvlist_add_uint64(dummy, propname, 0)); |
2747 break; | 2747 break; |
2748 default: | 2748 default: |
2749 nvlist_free(dummy); | 2749 nvlist_free(dummy); |
2750 return (EINVAL); | 2750 return (SET_ERROR(EINVAL)); |
2751 } | 2751 } |
2752 | 2752 |
2753 pair = nvlist_next_nvpair(dummy, NULL); | 2753 pair = nvlist_next_nvpair(dummy, NULL); |
2754 err = zfs_prop_set_special(zc->zc_name, source, pair); | 2754 err = zfs_prop_set_special(zc->zc_name, source, pair); |
2755 nvlist_free(dummy); | 2755 nvlist_free(dummy); |
2761 * 'inherit -S' to revert non-inheritable properties like quota | 2761 * 'inherit -S' to revert non-inheritable properties like quota |
2762 * and reservation to the received or default values even though | 2762 * and reservation to the received or default values even though |
2763 * they are not considered inheritable. | 2763 * they are not considered inheritable. |
2764 */ | 2764 */ |
2765 if (prop != ZPROP_INVAL && !zfs_prop_inheritable(prop)) | 2765 if (prop != ZPROP_INVAL && !zfs_prop_inheritable(prop)) |
2766 return (EINVAL); | 2766 return (SET_ERROR(EINVAL)); |
2767 } | 2767 } |
2768 | 2768 |
2769 /* property name has been validated by zfs_secpolicy_inherit_prop() */ | 2769 /* property name has been validated by zfs_secpolicy_inherit_prop() */ |
2770 return (dsl_prop_inherit(zc->zc_name, zc->zc_value, source)); | 2770 return (dsl_prop_inherit(zc->zc_name, zc->zc_value, source)); |
2771 } | 2771 } |
2838 } | 2838 } |
2839 | 2839 |
2840 if (error == 0 && zc->zc_nvlist_dst != NULL) | 2840 if (error == 0 && zc->zc_nvlist_dst != NULL) |
2841 error = put_nvlist(zc, nvp); | 2841 error = put_nvlist(zc, nvp); |
2842 else | 2842 else |
2843 error = EFAULT; | 2843 error = SET_ERROR(EFAULT); |
2844 | 2844 |
2845 nvlist_free(nvp); | 2845 nvlist_free(nvp); |
2846 return (error); | 2846 return (error); |
2847 } | 2847 } |
2848 | 2848 |
2867 /* | 2867 /* |
2868 * Verify nvlist is constructed correctly | 2868 * Verify nvlist is constructed correctly |
2869 */ | 2869 */ |
2870 if ((error = zfs_deleg_verify_nvlist(fsaclnv)) != 0) { | 2870 if ((error = zfs_deleg_verify_nvlist(fsaclnv)) != 0) { |
2871 nvlist_free(fsaclnv); | 2871 nvlist_free(fsaclnv); |
2872 return (EINVAL); | 2872 return (SET_ERROR(EINVAL)); |
2873 } | 2873 } |
2874 | 2874 |
2875 /* | 2875 /* |
2876 * If we don't have PRIV_SYS_MOUNT, then validate | 2876 * If we don't have PRIV_SYS_MOUNT, then validate |
2877 * that user is allowed to hand out each permission in | 2877 * that user is allowed to hand out each permission in |
3014 (zplver >= ZPL_VERSION_FUID && !fuids_ok) || | 3014 (zplver >= ZPL_VERSION_FUID && !fuids_ok) || |
3015 (zplver >= ZPL_VERSION_SA && !sa_ok) || | 3015 (zplver >= ZPL_VERSION_SA && !sa_ok) || |
3016 (zplver < ZPL_VERSION_NORMALIZATION && | 3016 (zplver < ZPL_VERSION_NORMALIZATION && |
3017 (norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED || | 3017 (norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED || |
3018 sense != ZFS_PROP_UNDEFINED))) | 3018 sense != ZFS_PROP_UNDEFINED))) |
3019 return (ENOTSUP); | 3019 return (SET_ERROR(ENOTSUP)); |
3020 | 3020 |
3021 /* | 3021 /* |
3022 * Put the version in the zplprops | 3022 * Put the version in the zplprops |
3023 */ | 3023 */ |
3024 VERIFY(nvlist_add_uint64(zplprops, | 3024 VERIFY(nvlist_add_uint64(zplprops, |
3126 int32_t type32; | 3126 int32_t type32; |
3127 dmu_objset_type_t type; | 3127 dmu_objset_type_t type; |
3128 boolean_t is_insensitive = B_FALSE; | 3128 boolean_t is_insensitive = B_FALSE; |
3129 | 3129 |
3130 if (nvlist_lookup_int32(innvl, "type", &type32) != 0) | 3130 if (nvlist_lookup_int32(innvl, "type", &type32) != 0) |
3131 return (EINVAL); | 3131 return (SET_ERROR(EINVAL)); |
3132 type = type32; | 3132 type = type32; |
3133 (void) nvlist_lookup_nvlist(innvl, "props", &nvprops); | 3133 (void) nvlist_lookup_nvlist(innvl, "props", &nvprops); |
3134 | 3134 |
3135 switch (type) { | 3135 switch (type) { |
3136 case DMU_OST_ZFS: | 3136 case DMU_OST_ZFS: |
3145 cbfunc = NULL; | 3145 cbfunc = NULL; |
3146 break; | 3146 break; |
3147 } | 3147 } |
3148 if (strchr(fsname, '@') || | 3148 if (strchr(fsname, '@') || |
3149 strchr(fsname, '%')) | 3149 strchr(fsname, '%')) |
3150 return (EINVAL); | 3150 return (SET_ERROR(EINVAL)); |
3151 | 3151 |
3152 zct.zct_props = nvprops; | 3152 zct.zct_props = nvprops; |
3153 | 3153 |
3154 if (cbfunc == NULL) | 3154 if (cbfunc == NULL) |
3155 return (EINVAL); | 3155 return (SET_ERROR(EINVAL)); |
3156 | 3156 |
3157 if (type == DMU_OST_ZVOL) { | 3157 if (type == DMU_OST_ZVOL) { |
3158 uint64_t volsize, volblocksize; | 3158 uint64_t volsize, volblocksize; |
3159 | 3159 |
3160 if (nvprops == NULL) | 3160 if (nvprops == NULL) |
3161 return (EINVAL); | 3161 return (SET_ERROR(EINVAL)); |
3162 if (nvlist_lookup_uint64(nvprops, | 3162 if (nvlist_lookup_uint64(nvprops, |
3163 zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) != 0) | 3163 zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) != 0) |
3164 return (EINVAL); | 3164 return (SET_ERROR(EINVAL)); |
3165 | 3165 |
3166 if ((error = nvlist_lookup_uint64(nvprops, | 3166 if ((error = nvlist_lookup_uint64(nvprops, |
3167 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), | 3167 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), |
3168 &volblocksize)) != 0 && error != ENOENT) | 3168 &volblocksize)) != 0 && error != ENOENT) |
3169 return (EINVAL); | 3169 return (SET_ERROR(EINVAL)); |
3170 | 3170 |
3171 if (error != 0) | 3171 if (error != 0) |
3172 volblocksize = zfs_prop_default_numeric( | 3172 volblocksize = zfs_prop_default_numeric( |
3173 ZFS_PROP_VOLBLOCKSIZE); | 3173 ZFS_PROP_VOLBLOCKSIZE); |
3174 | 3174 |
3226 int error = 0; | 3226 int error = 0; |
3227 nvlist_t *nvprops = NULL; | 3227 nvlist_t *nvprops = NULL; |
3228 char *origin_name; | 3228 char *origin_name; |
3229 | 3229 |
3230 if (nvlist_lookup_string(innvl, "origin", &origin_name) != 0) | 3230 if (nvlist_lookup_string(innvl, "origin", &origin_name) != 0) |
3231 return (EINVAL); | 3231 return (SET_ERROR(EINVAL)); |
3232 (void) nvlist_lookup_nvlist(innvl, "props", &nvprops); | 3232 (void) nvlist_lookup_nvlist(innvl, "props", &nvprops); |
3233 | 3233 |
3234 if (strchr(fsname, '@') || | 3234 if (strchr(fsname, '@') || |
3235 strchr(fsname, '%')) | 3235 strchr(fsname, '%')) |
3236 return (EINVAL); | 3236 return (SET_ERROR(EINVAL)); |
3237 | 3237 |
3238 if (dataset_namecheck(origin_name, NULL, NULL) != 0) | 3238 if (dataset_namecheck(origin_name, NULL, NULL) != 0) |
3239 return (EINVAL); | 3239 return (SET_ERROR(EINVAL)); |
3240 error = dmu_objset_clone(fsname, origin_name); | 3240 error = dmu_objset_clone(fsname, origin_name); |
3241 if (error != 0) | 3241 if (error != 0) |
3242 return (error); | 3242 return (error); |
3243 | 3243 |
3244 /* | 3244 /* |
3273 if ((error = zfs_check_userprops(poolname, props)) != 0) | 3273 if ((error = zfs_check_userprops(poolname, props)) != 0) |
3274 return (error); | 3274 return (error); |
3275 | 3275 |
3276 if (!nvlist_empty(props) && | 3276 if (!nvlist_empty(props) && |
3277 zfs_earlier_version(poolname, SPA_VERSION_SNAP_PROPS)) | 3277 zfs_earlier_version(poolname, SPA_VERSION_SNAP_PROPS)) |
3278 return (ENOTSUP); | 3278 return (SET_ERROR(ENOTSUP)); |
3279 | 3279 |
3280 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0) | 3280 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0) |
3281 return (EINVAL); | 3281 return (SET_ERROR(EINVAL)); |
3282 poollen = strlen(poolname); | 3282 poollen = strlen(poolname); |
3283 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; | 3283 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; |
3284 pair = nvlist_next_nvpair(snaps, pair)) { | 3284 pair = nvlist_next_nvpair(snaps, pair)) { |
3285 const char *name = nvpair_name(pair); | 3285 const char *name = nvpair_name(pair); |
3286 const char *cp = strchr(name, '@'); | 3286 const char *cp = strchr(name, '@'); |
3288 /* | 3288 /* |
3289 * The snap name must contain an @, and the part after it must | 3289 * The snap name must contain an @, and the part after it must |
3290 * contain only valid characters. | 3290 * contain only valid characters. |
3291 */ | 3291 */ |
3292 if (cp == NULL || snapshot_namecheck(cp + 1, NULL, NULL) != 0) | 3292 if (cp == NULL || snapshot_namecheck(cp + 1, NULL, NULL) != 0) |
3293 return (EINVAL); | 3293 return (SET_ERROR(EINVAL)); |
3294 | 3294 |
3295 /* | 3295 /* |
3296 * The snap must be in the specified pool. | 3296 * The snap must be in the specified pool. |
3297 */ | 3297 */ |
3298 if (strncmp(name, poolname, poollen) != 0 || | 3298 if (strncmp(name, poolname, poollen) != 0 || |
3299 (name[poollen] != '/' && name[poollen] != '@')) | 3299 (name[poollen] != '/' && name[poollen] != '@')) |
3300 return (EXDEV); | 3300 return (SET_ERROR(EXDEV)); |
3301 | 3301 |
3302 /* This must be the only snap of this fs. */ | 3302 /* This must be the only snap of this fs. */ |
3303 for (nvpair_t *pair2 = nvlist_next_nvpair(snaps, pair); | 3303 for (nvpair_t *pair2 = nvlist_next_nvpair(snaps, pair); |
3304 pair2 != NULL; pair2 = nvlist_next_nvpair(snaps, pair2)) { | 3304 pair2 != NULL; pair2 = nvlist_next_nvpair(snaps, pair2)) { |
3305 if (strncmp(name, nvpair_name(pair2), cp - name + 1) | 3305 if (strncmp(name, nvpair_name(pair2), cp - name + 1) |
3306 == 0) { | 3306 == 0) { |
3307 return (EXDEV); | 3307 return (SET_ERROR(EXDEV)); |
3308 } | 3308 } |
3309 } | 3309 } |
3310 } | 3310 } |
3311 | 3311 |
3312 error = dsl_dataset_snapshot(snaps, props, outnvl); | 3312 error = dsl_dataset_snapshot(snaps, props, outnvl); |
3339 if (error != 0) | 3339 if (error != 0) |
3340 return (error); | 3340 return (error); |
3341 | 3341 |
3342 if (nvlist_lookup_string(innvl, "message", &message) != 0) { | 3342 if (nvlist_lookup_string(innvl, "message", &message) != 0) { |
3343 spa_close(spa, FTAG); | 3343 spa_close(spa, FTAG); |
3344 return (EINVAL); | 3344 return (SET_ERROR(EINVAL)); |
3345 } | 3345 } |
3346 | 3346 |
3347 if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) { | 3347 if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) { |
3348 spa_close(spa, FTAG); | 3348 spa_close(spa, FTAG); |
3349 return (ENOTSUP); | 3349 return (SET_ERROR(ENOTSUP)); |
3350 } | 3350 } |
3351 | 3351 |
3352 error = spa_history_log(spa, message); | 3352 error = spa_history_log(spa, message); |
3353 spa_close(spa, FTAG); | 3353 spa_close(spa, FTAG); |
3354 return (error); | 3354 return (error); |
3439 nvlist_t *snaps; | 3439 nvlist_t *snaps; |
3440 nvpair_t *pair; | 3440 nvpair_t *pair; |
3441 boolean_t defer; | 3441 boolean_t defer; |
3442 | 3442 |
3443 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0) | 3443 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0) |
3444 return (EINVAL); | 3444 return (SET_ERROR(EINVAL)); |
3445 defer = nvlist_exists(innvl, "defer"); | 3445 defer = nvlist_exists(innvl, "defer"); |
3446 | 3446 |
3447 poollen = strlen(poolname); | 3447 poollen = strlen(poolname); |
3448 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; | 3448 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; |
3449 pair = nvlist_next_nvpair(snaps, pair)) { | 3449 pair = nvlist_next_nvpair(snaps, pair)) { |
3452 /* | 3452 /* |
3453 * The snap must be in the specified pool. | 3453 * The snap must be in the specified pool. |
3454 */ | 3454 */ |
3455 if (strncmp(name, poolname, poollen) != 0 || | 3455 if (strncmp(name, poolname, poollen) != 0 || |
3456 (name[poollen] != '/' && name[poollen] != '@')) | 3456 (name[poollen] != '/' && name[poollen] != '@')) |
3457 return (EXDEV); | 3457 return (SET_ERROR(EXDEV)); |
3458 | 3458 |
3459 zfs_unmount_snap(name); | 3459 zfs_unmount_snap(name); |
3460 } | 3460 } |
3461 | 3461 |
3462 return (dsl_destroy_snapshots_nvl(snaps, defer, outnvl)); | 3462 return (dsl_destroy_snapshots_nvl(snaps, defer, outnvl)); |
3540 char *at; | 3540 char *at; |
3541 | 3541 |
3542 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; | 3542 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; |
3543 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || | 3543 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || |
3544 strchr(zc->zc_value, '%')) | 3544 strchr(zc->zc_value, '%')) |
3545 return (EINVAL); | 3545 return (SET_ERROR(EINVAL)); |
3546 | 3546 |
3547 at = strchr(zc->zc_name, '@'); | 3547 at = strchr(zc->zc_name, '@'); |
3548 if (at != NULL) { | 3548 if (at != NULL) { |
3549 /* snaps must be in same fs */ | 3549 /* snaps must be in same fs */ |
3550 if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1)) | 3550 if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1)) |
3551 return (EXDEV); | 3551 return (SET_ERROR(EXDEV)); |
3552 *at = '\0'; | 3552 *at = '\0'; |
3553 if (zc->zc_objset_type == DMU_OST_ZFS) { | 3553 if (zc->zc_objset_type == DMU_OST_ZFS) { |
3554 int error = dmu_objset_find(zc->zc_name, | 3554 int error = dmu_objset_find(zc->zc_name, |
3555 recursive_unmount, at + 1, | 3555 recursive_unmount, at + 1, |
3556 recursive ? DS_FIND_CHILDREN : 0); | 3556 recursive ? DS_FIND_CHILDREN : 0); |
3596 } else if (strncmp(propname, gq_prefix, | 3596 } else if (strncmp(propname, gq_prefix, |
3597 strlen(gq_prefix)) == 0) { | 3597 strlen(gq_prefix)) == 0) { |
3598 perm = ZFS_DELEG_PERM_GROUPQUOTA; | 3598 perm = ZFS_DELEG_PERM_GROUPQUOTA; |
3599 } else { | 3599 } else { |
3600 /* USERUSED and GROUPUSED are read-only */ | 3600 /* USERUSED and GROUPUSED are read-only */ |
3601 return (EINVAL); | 3601 return (SET_ERROR(EINVAL)); |
3602 } | 3602 } |
3603 | 3603 |
3604 if (err = zfs_secpolicy_write_perms(dsname, perm, cr)) | 3604 if (err = zfs_secpolicy_write_perms(dsname, perm, cr)) |
3605 return (err); | 3605 return (err); |
3606 return (0); | 3606 return (0); |
3607 } | 3607 } |
3608 | 3608 |
3609 return (EINVAL); | 3609 return (SET_ERROR(EINVAL)); |
3610 } | 3610 } |
3611 | 3611 |
3612 if (issnap) | 3612 if (issnap) |
3613 return (EINVAL); | 3613 return (SET_ERROR(EINVAL)); |
3614 | 3614 |
3615 if (nvpair_type(pair) == DATA_TYPE_NVLIST) { | 3615 if (nvpair_type(pair) == DATA_TYPE_NVLIST) { |
3616 /* | 3616 /* |
3617 * dsl_prop_get_all_impl() returns properties in this | 3617 * dsl_prop_get_all_impl() returns properties in this |
3618 * format. | 3618 * format. |
3637 nvpair_value_uint64(pair, &intval) == 0) { | 3637 nvpair_value_uint64(pair, &intval) == 0) { |
3638 if (intval >= ZIO_COMPRESS_GZIP_1 && | 3638 if (intval >= ZIO_COMPRESS_GZIP_1 && |
3639 intval <= ZIO_COMPRESS_GZIP_9 && | 3639 intval <= ZIO_COMPRESS_GZIP_9 && |
3640 zfs_earlier_version(dsname, | 3640 zfs_earlier_version(dsname, |
3641 SPA_VERSION_GZIP_COMPRESSION)) { | 3641 SPA_VERSION_GZIP_COMPRESSION)) { |
3642 return (ENOTSUP); | 3642 return (SET_ERROR(ENOTSUP)); |
3643 } | 3643 } |
3644 | 3644 |
3645 if (intval == ZIO_COMPRESS_ZLE && | 3645 if (intval == ZIO_COMPRESS_ZLE && |
3646 zfs_earlier_version(dsname, | 3646 zfs_earlier_version(dsname, |
3647 SPA_VERSION_ZLE_COMPRESSION)) | 3647 SPA_VERSION_ZLE_COMPRESSION)) |
3648 return (ENOTSUP); | 3648 return (SET_ERROR(ENOTSUP)); |
3649 | 3649 |
3650 if (intval == ZIO_COMPRESS_LZ4) { | 3650 if (intval == ZIO_COMPRESS_LZ4) { |
3651 zfeature_info_t *feature = | 3651 zfeature_info_t *feature = |
3652 &spa_feature_table[ | 3652 &spa_feature_table[ |
3653 SPA_FEATURE_LZ4_COMPRESS]; | 3653 SPA_FEATURE_LZ4_COMPRESS]; |
3656 if ((err = spa_open(dsname, &spa, FTAG)) != 0) | 3656 if ((err = spa_open(dsname, &spa, FTAG)) != 0) |
3657 return (err); | 3657 return (err); |
3658 | 3658 |
3659 if (!spa_feature_is_enabled(spa, feature)) { | 3659 if (!spa_feature_is_enabled(spa, feature)) { |
3660 spa_close(spa, FTAG); | 3660 spa_close(spa, FTAG); |
3661 return (ENOTSUP); | 3661 return (SET_ERROR(ENOTSUP)); |
3662 } | 3662 } |
3663 spa_close(spa, FTAG); | 3663 spa_close(spa, FTAG); |
3664 } | 3664 } |
3665 | 3665 |
3666 /* | 3666 /* |
3670 * something other than ENOTSUP since it | 3670 * something other than ENOTSUP since it |
3671 * implies a downrev pool version. | 3671 * implies a downrev pool version. |
3672 */ | 3672 */ |
3673 if (zfs_is_bootfs(dsname) && | 3673 if (zfs_is_bootfs(dsname) && |
3674 !BOOTFS_COMPRESS_VALID(intval)) { | 3674 !BOOTFS_COMPRESS_VALID(intval)) { |
3675 return (ERANGE); | 3675 return (SET_ERROR(ERANGE)); |
3676 } | 3676 } |
3677 } | 3677 } |
3678 break; | 3678 break; |
3679 | 3679 |
3680 case ZFS_PROP_COPIES: | 3680 case ZFS_PROP_COPIES: |
3681 if (zfs_earlier_version(dsname, SPA_VERSION_DITTO_BLOCKS)) | 3681 if (zfs_earlier_version(dsname, SPA_VERSION_DITTO_BLOCKS)) |
3682 return (ENOTSUP); | 3682 return (SET_ERROR(ENOTSUP)); |
3683 break; | 3683 break; |
3684 | 3684 |
3685 case ZFS_PROP_DEDUP: | 3685 case ZFS_PROP_DEDUP: |
3686 if (zfs_earlier_version(dsname, SPA_VERSION_DEDUP)) | 3686 if (zfs_earlier_version(dsname, SPA_VERSION_DEDUP)) |
3687 return (ENOTSUP); | 3687 return (SET_ERROR(ENOTSUP)); |
3688 break; | 3688 break; |
3689 | 3689 |
3690 case ZFS_PROP_SHARESMB: | 3690 case ZFS_PROP_SHARESMB: |
3691 if (zpl_earlier_version(dsname, ZPL_VERSION_FUID)) | 3691 if (zpl_earlier_version(dsname, ZPL_VERSION_FUID)) |
3692 return (ENOTSUP); | 3692 return (SET_ERROR(ENOTSUP)); |
3693 break; | 3693 break; |
3694 | 3694 |
3695 case ZFS_PROP_ACLINHERIT: | 3695 case ZFS_PROP_ACLINHERIT: |
3696 if (nvpair_type(pair) == DATA_TYPE_UINT64 && | 3696 if (nvpair_type(pair) == DATA_TYPE_UINT64 && |
3697 nvpair_value_uint64(pair, &intval) == 0) { | 3697 nvpair_value_uint64(pair, &intval) == 0) { |
3698 if (intval == ZFS_ACL_PASSTHROUGH_X && | 3698 if (intval == ZFS_ACL_PASSTHROUGH_X && |
3699 zfs_earlier_version(dsname, | 3699 zfs_earlier_version(dsname, |
3700 SPA_VERSION_PASSTHROUGH_X)) | 3700 SPA_VERSION_PASSTHROUGH_X)) |
3701 return (ENOTSUP); | 3701 return (SET_ERROR(ENOTSUP)); |
3702 } | 3702 } |
3703 break; | 3703 break; |
3704 } | 3704 } |
3705 | 3705 |
3706 return (zfs_secpolicy_setprop(dsname, prop, pair, CRED())); | 3706 return (zfs_secpolicy_setprop(dsname, prop, pair, CRED())); |
3717 zfeature_info_t *feature = arg; | 3717 zfeature_info_t *feature = arg; |
3718 | 3718 |
3719 if (!spa_feature_is_active(spa, feature)) | 3719 if (!spa_feature_is_active(spa, feature)) |
3720 return (0); | 3720 return (0); |
3721 else | 3721 else |
3722 return (EBUSY); | 3722 return (SET_ERROR(EBUSY)); |
3723 } | 3723 } |
3724 | 3724 |
3725 /* | 3725 /* |
3726 * The callback invoked on feature activation in the sync task caused by | 3726 * The callback invoked on feature activation in the sync task caused by |
3727 * zfs_prop_activate_feature. | 3727 * zfs_prop_activate_feature. |
3925 boolean_t first_recvd_props = B_FALSE; | 3925 boolean_t first_recvd_props = B_FALSE; |
3926 | 3926 |
3927 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || | 3927 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || |
3928 strchr(zc->zc_value, '@') == NULL || | 3928 strchr(zc->zc_value, '@') == NULL || |
3929 strchr(zc->zc_value, '%')) | 3929 strchr(zc->zc_value, '%')) |
3930 return (EINVAL); | 3930 return (SET_ERROR(EINVAL)); |
3931 | 3931 |
3932 (void) strcpy(tofs, zc->zc_value); | 3932 (void) strcpy(tofs, zc->zc_value); |
3933 tosnap = strchr(tofs, '@'); | 3933 tosnap = strchr(tofs, '@'); |
3934 *tosnap++ = '\0'; | 3934 *tosnap++ = '\0'; |
3935 | 3935 |
3940 | 3940 |
3941 fd = zc->zc_cookie; | 3941 fd = zc->zc_cookie; |
3942 fp = getf(fd); | 3942 fp = getf(fd); |
3943 if (fp == NULL) { | 3943 if (fp == NULL) { |
3944 nvlist_free(props); | 3944 nvlist_free(props); |
3945 return (EBADF); | 3945 return (SET_ERROR(EBADF)); |
3946 } | 3946 } |
3947 | 3947 |
3948 VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0); | 3948 VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0); |
3949 | 3949 |
3950 if (zc->zc_string[0]) | 3950 if (zc->zc_string[0]) |
4009 put_nvlist(zc, errors) != 0)) { | 4009 put_nvlist(zc, errors) != 0)) { |
4010 /* | 4010 /* |
4011 * Caller made zc->zc_nvlist_dst less than the minimum expected | 4011 * Caller made zc->zc_nvlist_dst less than the minimum expected |
4012 * size or supplied an invalid address. | 4012 * size or supplied an invalid address. |
4013 */ | 4013 */ |
4014 props_error = EINVAL; | 4014 props_error = SET_ERROR(EINVAL); |
4015 } | 4015 } |
4016 | 4016 |
4017 off = fp->f_offset; | 4017 off = fp->f_offset; |
4018 error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd, | 4018 error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd, |
4019 &zc->zc_action_handle); | 4019 &zc->zc_action_handle); |
4171 dsl_dataset_rele(tosnap, FTAG); | 4171 dsl_dataset_rele(tosnap, FTAG); |
4172 dsl_pool_rele(dp, FTAG); | 4172 dsl_pool_rele(dp, FTAG); |
4173 } else { | 4173 } else { |
4174 file_t *fp = getf(zc->zc_cookie); | 4174 file_t *fp = getf(zc->zc_cookie); |
4175 if (fp == NULL) | 4175 if (fp == NULL) |
4176 return (EBADF); | 4176 return (SET_ERROR(EBADF)); |
4177 | 4177 |
4178 off = fp->f_offset; | 4178 off = fp->f_offset; |
4179 error = dmu_send_obj(zc->zc_name, zc->zc_sendobj, | 4179 error = dmu_send_obj(zc->zc_name, zc->zc_sendobj, |
4180 zc->zc_fromobj, zc->zc_cookie, fp->f_vnode, &off); | 4180 zc->zc_fromobj, zc->zc_cookie, fp->f_vnode, &off); |
4181 | 4181 |
4228 } | 4228 } |
4229 | 4229 |
4230 if (dsp != NULL) | 4230 if (dsp != NULL) |
4231 zc->zc_cookie = *(dsp->dsa_off); | 4231 zc->zc_cookie = *(dsp->dsa_off); |
4232 else | 4232 else |
4233 error = ENOENT; | 4233 error = SET_ERROR(ENOENT); |
4234 | 4234 |
4235 mutex_exit(&ds->ds_sendstream_lock); | 4235 mutex_exit(&ds->ds_sendstream_lock); |
4236 dsl_dataset_rele(ds, FTAG); | 4236 dsl_dataset_rele(ds, FTAG); |
4237 dsl_pool_rele(dp, FTAG); | 4237 dsl_pool_rele(dp, FTAG); |
4238 return (error); | 4238 return (error); |
4306 */ | 4306 */ |
4307 mutex_enter(&spa_namespace_lock); | 4307 mutex_enter(&spa_namespace_lock); |
4308 spa = spa_lookup(zc->zc_name); | 4308 spa = spa_lookup(zc->zc_name); |
4309 if (spa == NULL) { | 4309 if (spa == NULL) { |
4310 mutex_exit(&spa_namespace_lock); | 4310 mutex_exit(&spa_namespace_lock); |
4311 return (EIO); | 4311 return (SET_ERROR(EIO)); |
4312 } | 4312 } |
4313 if (spa_get_log_state(spa) == SPA_LOG_MISSING) { | 4313 if (spa_get_log_state(spa) == SPA_LOG_MISSING) { |
4314 /* we need to let spa_open/spa_load clear the chains */ | 4314 /* we need to let spa_open/spa_load clear the chains */ |
4315 spa_set_log_state(spa, SPA_LOG_CLEAR); | 4315 spa_set_log_state(spa, SPA_LOG_CLEAR); |
4316 } | 4316 } |
4322 } else { | 4322 } else { |
4323 nvlist_t *policy; | 4323 nvlist_t *policy; |
4324 nvlist_t *config = NULL; | 4324 nvlist_t *config = NULL; |
4325 | 4325 |
4326 if (zc->zc_nvlist_src == NULL) | 4326 if (zc->zc_nvlist_src == NULL) |
4327 return (EINVAL); | 4327 return (SET_ERROR(EINVAL)); |
4328 | 4328 |
4329 if ((error = get_nvlist(zc->zc_nvlist_src, | 4329 if ((error = get_nvlist(zc->zc_nvlist_src, |
4330 zc->zc_nvlist_src_size, zc->zc_iflags, &policy)) == 0) { | 4330 zc->zc_nvlist_src_size, zc->zc_iflags, &policy)) == 0) { |
4331 error = spa_open_rewind(zc->zc_name, &spa, FTAG, | 4331 error = spa_open_rewind(zc->zc_name, &spa, FTAG, |
4332 policy, &config); | 4332 policy, &config); |
4351 } else { | 4351 } else { |
4352 vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE); | 4352 vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE); |
4353 if (vd == NULL) { | 4353 if (vd == NULL) { |
4354 (void) spa_vdev_state_exit(spa, NULL, ENODEV); | 4354 (void) spa_vdev_state_exit(spa, NULL, ENODEV); |
4355 spa_close(spa, FTAG); | 4355 spa_close(spa, FTAG); |
4356 return (ENODEV); | 4356 return (SET_ERROR(ENODEV)); |
4357 } | 4357 } |
4358 } | 4358 } |
4359 | 4359 |
4360 vdev_clear(spa, vd); | 4360 vdev_clear(spa, vd); |
4361 | 4361 |
4363 | 4363 |
4364 /* | 4364 /* |
4365 * Resume any suspended I/Os. | 4365 * Resume any suspended I/Os. |
4366 */ | 4366 */ |
4367 if (zio_resume(spa) != 0) | 4367 if (zio_resume(spa) != 0) |
4368 error = EIO; | 4368 error = SET_ERROR(EIO); |
4369 | 4369 |
4370 spa_close(spa, FTAG); | 4370 spa_close(spa, FTAG); |
4371 | 4371 |
4372 return (error); | 4372 return (error); |
4373 } | 4373 } |
4440 { | 4440 { |
4441 zfsvfs_t *zfsvfs; | 4441 zfsvfs_t *zfsvfs; |
4442 int error; | 4442 int error; |
4443 | 4443 |
4444 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS) | 4444 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS) |
4445 return (EINVAL); | 4445 return (SET_ERROR(EINVAL)); |
4446 | 4446 |
4447 error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); | 4447 error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); |
4448 if (error != 0) | 4448 if (error != 0) |
4449 return (error); | 4449 return (error); |
4450 | 4450 |
4471 { | 4471 { |
4472 zfsvfs_t *zfsvfs; | 4472 zfsvfs_t *zfsvfs; |
4473 int bufsize = zc->zc_nvlist_dst_size; | 4473 int bufsize = zc->zc_nvlist_dst_size; |
4474 | 4474 |
4475 if (bufsize <= 0) | 4475 if (bufsize <= 0) |
4476 return (ENOMEM); | 4476 return (SET_ERROR(ENOMEM)); |
4477 | 4477 |
4478 int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); | 4478 int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); |
4479 if (error != 0) | 4479 if (error != 0) |
4480 return (error); | 4480 return (error); |
4481 | 4481 |
4563 ASSERT(MUTEX_HELD(&zfs_share_lock)); | 4563 ASSERT(MUTEX_HELD(&zfs_share_lock)); |
4564 /* Both NFS and SMB shares also require sharetab support. */ | 4564 /* Both NFS and SMB shares also require sharetab support. */ |
4565 if (sharefs_mod == NULL && ((sharefs_mod = | 4565 if (sharefs_mod == NULL && ((sharefs_mod = |
4566 ddi_modopen("fs/sharefs", | 4566 ddi_modopen("fs/sharefs", |
4567 KRTLD_MODE_FIRST, &error)) == NULL)) { | 4567 KRTLD_MODE_FIRST, &error)) == NULL)) { |
4568 return (ENOSYS); | 4568 return (SET_ERROR(ENOSYS)); |
4569 } | 4569 } |
4570 if (zshare_fs == NULL && ((zshare_fs = | 4570 if (zshare_fs == NULL && ((zshare_fs = |
4571 (int (*)(enum sharefs_sys_op, share_t *, uint32_t)) | 4571 (int (*)(enum sharefs_sys_op, share_t *, uint32_t)) |
4572 ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) { | 4572 ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) { |
4573 return (ENOSYS); | 4573 return (SET_ERROR(ENOSYS)); |
4574 } | 4574 } |
4575 return (0); | 4575 return (0); |
4576 } | 4576 } |
4577 | 4577 |
4578 static int | 4578 static int |
4587 if (zfs_nfsshare_inited == 0) { | 4587 if (zfs_nfsshare_inited == 0) { |
4588 mutex_enter(&zfs_share_lock); | 4588 mutex_enter(&zfs_share_lock); |
4589 if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs", | 4589 if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs", |
4590 KRTLD_MODE_FIRST, &error)) == NULL)) { | 4590 KRTLD_MODE_FIRST, &error)) == NULL)) { |
4591 mutex_exit(&zfs_share_lock); | 4591 mutex_exit(&zfs_share_lock); |
4592 return (ENOSYS); | 4592 return (SET_ERROR(ENOSYS)); |
4593 } | 4593 } |
4594 if (znfsexport_fs == NULL && | 4594 if (znfsexport_fs == NULL && |
4595 ((znfsexport_fs = (int (*)(void *)) | 4595 ((znfsexport_fs = (int (*)(void *)) |
4596 ddi_modsym(nfs_mod, | 4596 ddi_modsym(nfs_mod, |
4597 "nfs_export", &error)) == NULL)) { | 4597 "nfs_export", &error)) == NULL)) { |
4598 mutex_exit(&zfs_share_lock); | 4598 mutex_exit(&zfs_share_lock); |
4599 return (ENOSYS); | 4599 return (SET_ERROR(ENOSYS)); |
4600 } | 4600 } |
4601 error = zfs_init_sharefs(); | 4601 error = zfs_init_sharefs(); |
4602 if (error != 0) { | 4602 if (error != 0) { |
4603 mutex_exit(&zfs_share_lock); | 4603 mutex_exit(&zfs_share_lock); |
4604 return (ENOSYS); | 4604 return (SET_ERROR(ENOSYS)); |
4605 } | 4605 } |
4606 zfs_nfsshare_inited = 1; | 4606 zfs_nfsshare_inited = 1; |
4607 mutex_exit(&zfs_share_lock); | 4607 mutex_exit(&zfs_share_lock); |
4608 } | 4608 } |
4609 break; | 4609 break; |
4613 mutex_enter(&zfs_share_lock); | 4613 mutex_enter(&zfs_share_lock); |
4614 if (smbsrv_mod == NULL && ((smbsrv_mod = | 4614 if (smbsrv_mod == NULL && ((smbsrv_mod = |
4615 ddi_modopen("drv/smbsrv", | 4615 ddi_modopen("drv/smbsrv", |
4616 KRTLD_MODE_FIRST, &error)) == NULL)) { | 4616 KRTLD_MODE_FIRST, &error)) == NULL)) { |
4617 mutex_exit(&zfs_share_lock); | 4617 mutex_exit(&zfs_share_lock); |
4618 return (ENOSYS); | 4618 return (SET_ERROR(ENOSYS)); |
4619 } | 4619 } |
4620 if (zsmbexport_fs == NULL && ((zsmbexport_fs = | 4620 if (zsmbexport_fs == NULL && ((zsmbexport_fs = |
4621 (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod, | 4621 (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod, |
4622 "smb_server_share", &error)) == NULL)) { | 4622 "smb_server_share", &error)) == NULL)) { |
4623 mutex_exit(&zfs_share_lock); | 4623 mutex_exit(&zfs_share_lock); |
4624 return (ENOSYS); | 4624 return (SET_ERROR(ENOSYS)); |
4625 } | 4625 } |
4626 error = zfs_init_sharefs(); | 4626 error = zfs_init_sharefs(); |
4627 if (error != 0) { | 4627 if (error != 0) { |
4628 mutex_exit(&zfs_share_lock); | 4628 mutex_exit(&zfs_share_lock); |
4629 return (ENOSYS); | 4629 return (SET_ERROR(ENOSYS)); |
4630 } | 4630 } |
4631 zfs_smbshare_inited = 1; | 4631 zfs_smbshare_inited = 1; |
4632 mutex_exit(&zfs_share_lock); | 4632 mutex_exit(&zfs_share_lock); |
4633 } | 4633 } |
4634 break; | 4634 break; |
4635 default: | 4635 default: |
4636 return (EINVAL); | 4636 return (SET_ERROR(EINVAL)); |
4637 } | 4637 } |
4638 | 4638 |
4639 switch (zc->zc_share.z_sharetype) { | 4639 switch (zc->zc_share.z_sharetype) { |
4640 case ZFS_SHARE_NFS: | 4640 case ZFS_SHARE_NFS: |
4641 case ZFS_UNSHARE_NFS: | 4641 case ZFS_UNSHARE_NFS: |
4750 offset_t off; | 4750 offset_t off; |
4751 int error; | 4751 int error; |
4752 | 4752 |
4753 fp = getf(zc->zc_cookie); | 4753 fp = getf(zc->zc_cookie); |
4754 if (fp == NULL) | 4754 if (fp == NULL) |
4755 return (EBADF); | 4755 return (SET_ERROR(EBADF)); |
4756 | 4756 |
4757 off = fp->f_offset; | 4757 off = fp->f_offset; |
4758 | 4758 |
4759 error = dmu_diff(zc->zc_name, zc->zc_value, fp->f_vnode, &off); | 4759 error = dmu_diff(zc->zc_name, zc->zc_value, fp->f_vnode, &off); |
4760 | 4760 |
4809 | 4809 |
4810 if (vp->v_vfsp->vfs_fstype != zfsfstype || | 4810 if (vp->v_vfsp->vfs_fstype != zfsfstype || |
4811 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource), | 4811 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource), |
4812 zc->zc_name) != 0)) { | 4812 zc->zc_name) != 0)) { |
4813 VN_RELE(vp); | 4813 VN_RELE(vp); |
4814 return (EINVAL); | 4814 return (SET_ERROR(EINVAL)); |
4815 } | 4815 } |
4816 | 4816 |
4817 dzp = VTOZ(vp); | 4817 dzp = VTOZ(vp); |
4818 zfsvfs = dzp->z_zfsvfs; | 4818 zfsvfs = dzp->z_zfsvfs; |
4819 ZFS_ENTER(zfsvfs); | 4819 ZFS_ENTER(zfsvfs); |
4900 case ZFS_SMB_ACL_PURGE: | 4900 case ZFS_SMB_ACL_PURGE: |
4901 error = zfs_smb_acl_purge(sharedir); | 4901 error = zfs_smb_acl_purge(sharedir); |
4902 break; | 4902 break; |
4903 | 4903 |
4904 default: | 4904 default: |
4905 error = EINVAL; | 4905 error = SET_ERROR(EINVAL); |
4906 break; | 4906 break; |
4907 } | 4907 } |
4908 | 4908 |
4909 VN_RELE(vp); | 4909 VN_RELE(vp); |
4910 VN_RELE(ZTOV(sharedir)); | 4910 VN_RELE(ZTOV(sharedir)); |
4934 int error; | 4934 int error; |
4935 minor_t minor = 0; | 4935 minor_t minor = 0; |
4936 | 4936 |
4937 error = nvlist_lookup_nvlist(args, "holds", &holds); | 4937 error = nvlist_lookup_nvlist(args, "holds", &holds); |
4938 if (error != 0) | 4938 if (error != 0) |
4939 return (EINVAL); | 4939 return (SET_ERROR(EINVAL)); |
4940 | 4940 |
4941 if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) { | 4941 if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) { |
4942 error = zfs_onexit_fd_hold(cleanup_fd, &minor); | 4942 error = zfs_onexit_fd_hold(cleanup_fd, &minor); |
4943 if (error != 0) | 4943 if (error != 0) |
4944 return (error); | 4944 return (error); |
5052 dsl_dataset_t *new, *old; | 5052 dsl_dataset_t *new, *old; |
5053 char *firstsnap; | 5053 char *firstsnap; |
5054 uint64_t used, comp, uncomp; | 5054 uint64_t used, comp, uncomp; |
5055 | 5055 |
5056 if (nvlist_lookup_string(innvl, "firstsnap", &firstsnap) != 0) | 5056 if (nvlist_lookup_string(innvl, "firstsnap", &firstsnap) != 0) |
5057 return (EINVAL); | 5057 return (SET_ERROR(EINVAL)); |
5058 | 5058 |
5059 error = dsl_pool_hold(lastsnap, FTAG, &dp); | 5059 error = dsl_pool_hold(lastsnap, FTAG, &dp); |
5060 if (error != 0) | 5060 if (error != 0) |
5061 return (error); | 5061 return (error); |
5062 | 5062 |
5099 char *fromname = NULL; | 5099 char *fromname = NULL; |
5100 int fd; | 5100 int fd; |
5101 | 5101 |
5102 error = nvlist_lookup_int32(innvl, "fd", &fd); | 5102 error = nvlist_lookup_int32(innvl, "fd", &fd); |
5103 if (error != 0) | 5103 if (error != 0) |
5104 return (EINVAL); | 5104 return (SET_ERROR(EINVAL)); |
5105 | 5105 |
5106 (void) nvlist_lookup_string(innvl, "fromsnap", &fromname); | 5106 (void) nvlist_lookup_string(innvl, "fromsnap", &fromname); |
5107 | 5107 |
5108 file_t *fp = getf(fd); | 5108 file_t *fp = getf(fd); |
5109 if (fp == NULL) | 5109 if (fp == NULL) |
5110 return (EBADF); | 5110 return (SET_ERROR(EBADF)); |
5111 | 5111 |
5112 off = fp->f_offset; | 5112 off = fp->f_offset; |
5113 error = dmu_send(snapname, fromname, fd, fp->f_vnode, &off); | 5113 error = dmu_send(snapname, fromname, fd, fp->f_vnode, &off); |
5114 | 5114 |
5115 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0) | 5115 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0) |
5471 return (0); | 5471 return (0); |
5472 | 5472 |
5473 error = spa_open(name, &spa, FTAG); | 5473 error = spa_open(name, &spa, FTAG); |
5474 if (error == 0) { | 5474 if (error == 0) { |
5475 if ((check & POOL_CHECK_SUSPENDED) && spa_suspended(spa)) | 5475 if ((check & POOL_CHECK_SUSPENDED) && spa_suspended(spa)) |
5476 error = EAGAIN; | 5476 error = SET_ERROR(EAGAIN); |
5477 else if ((check & POOL_CHECK_READONLY) && !spa_writeable(spa)) | 5477 else if ((check & POOL_CHECK_READONLY) && !spa_writeable(spa)) |
5478 error = EROFS; | 5478 error = SET_ERROR(EROFS); |
5479 spa_close(spa, FTAG); | 5479 spa_close(spa, FTAG); |
5480 } | 5480 } |
5481 return (error); | 5481 return (error); |
5482 } | 5482 } |
5483 | 5483 |
5513 ASSERT(MUTEX_HELD(&zfsdev_state_lock)); | 5513 ASSERT(MUTEX_HELD(&zfsdev_state_lock)); |
5514 ASSERT(getminor(*devp) == 0); | 5514 ASSERT(getminor(*devp) == 0); |
5515 | 5515 |
5516 minor = zfsdev_minor_alloc(); | 5516 minor = zfsdev_minor_alloc(); |
5517 if (minor == 0) | 5517 if (minor == 0) |
5518 return (ENXIO); | 5518 return (SET_ERROR(ENXIO)); |
5519 | 5519 |
5520 if (ddi_soft_state_zalloc(zfsdev_state, minor) != DDI_SUCCESS) | 5520 if (ddi_soft_state_zalloc(zfsdev_state, minor) != DDI_SUCCESS) |
5521 return (EAGAIN); | 5521 return (SET_ERROR(EAGAIN)); |
5522 | 5522 |
5523 *devp = makedevice(getemajor(*devp), minor); | 5523 *devp = makedevice(getemajor(*devp), minor); |
5524 | 5524 |
5525 zs = ddi_get_soft_state(zfsdev_state, minor); | 5525 zs = ddi_get_soft_state(zfsdev_state, minor); |
5526 zs->zss_type = ZSST_CTLDEV; | 5526 zs->zss_type = ZSST_CTLDEV; |
5606 | 5606 |
5607 vecnum = cmd - ZFS_IOC_FIRST; | 5607 vecnum = cmd - ZFS_IOC_FIRST; |
5608 ASSERT3U(getmajor(dev), ==, ddi_driver_major(zfs_dip)); | 5608 ASSERT3U(getmajor(dev), ==, ddi_driver_major(zfs_dip)); |
5609 | 5609 |
5610 if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0])) | 5610 if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0])) |
5611 return (EINVAL); | 5611 return (SET_ERROR(EINVAL)); |
5612 vec = &zfs_ioc_vec[vecnum]; | 5612 vec = &zfs_ioc_vec[vecnum]; |
5613 | 5613 |
5614 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); | 5614 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); |
5615 | 5615 |
5616 error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag); | 5616 error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag); |
5617 if (error != 0) { | 5617 if (error != 0) { |
5618 error = EFAULT; | 5618 error = SET_ERROR(EFAULT); |
5619 goto out; | 5619 goto out; |
5620 } | 5620 } |
5621 | 5621 |
5622 zc->zc_iflags = flag & FKIOCTL; | 5622 zc->zc_iflags = flag & FKIOCTL; |
5623 if (zc->zc_nvlist_src_size != 0) { | 5623 if (zc->zc_nvlist_src_size != 0) { |
5633 */ | 5633 */ |
5634 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0'; | 5634 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0'; |
5635 switch (vec->zvec_namecheck) { | 5635 switch (vec->zvec_namecheck) { |
5636 case POOL_NAME: | 5636 case POOL_NAME: |
5637 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0) | 5637 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0) |
5638 error = EINVAL; | 5638 error = SET_ERROR(EINVAL); |
5639 else | 5639 else |
5640 error = pool_status_check(zc->zc_name, | 5640 error = pool_status_check(zc->zc_name, |
5641 vec->zvec_namecheck, vec->zvec_pool_check); | 5641 vec->zvec_namecheck, vec->zvec_pool_check); |
5642 break; | 5642 break; |
5643 | 5643 |
5644 case DATASET_NAME: | 5644 case DATASET_NAME: |
5645 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0) | 5645 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0) |
5646 error = EINVAL; | 5646 error = SET_ERROR(EINVAL); |
5647 else | 5647 else |
5648 error = pool_status_check(zc->zc_name, | 5648 error = pool_status_check(zc->zc_name, |
5649 vec->zvec_namecheck, vec->zvec_pool_check); | 5649 vec->zvec_namecheck, vec->zvec_pool_check); |
5650 break; | 5650 break; |
5651 | 5651 |
5721 | 5721 |
5722 out: | 5722 out: |
5723 nvlist_free(innvl); | 5723 nvlist_free(innvl); |
5724 rc = ddi_copyout(zc, (void *)arg, sizeof (zfs_cmd_t), flag); | 5724 rc = ddi_copyout(zc, (void *)arg, sizeof (zfs_cmd_t), flag); |
5725 if (error == 0 && rc != 0) | 5725 if (error == 0 && rc != 0) |
5726 error = EFAULT; | 5726 error = SET_ERROR(EFAULT); |
5727 if (error == 0 && vec->zvec_allow_log) { | 5727 if (error == 0 && vec->zvec_allow_log) { |
5728 char *s = tsd_get(zfs_allow_log_key); | 5728 char *s = tsd_get(zfs_allow_log_key); |
5729 if (s != NULL) | 5729 if (s != NULL) |
5730 strfree(s); | 5730 strfree(s); |
5731 (void) tsd_set(zfs_allow_log_key, saved_poolname); | 5731 (void) tsd_set(zfs_allow_log_key, saved_poolname); |
5886 _fini(void) | 5886 _fini(void) |
5887 { | 5887 { |
5888 int error; | 5888 int error; |
5889 | 5889 |
5890 if (spa_busy() || zfs_busy() || zvol_busy() || zio_injection_enabled) | 5890 if (spa_busy() || zfs_busy() || zvol_busy() || zio_injection_enabled) |
5891 return (EBUSY); | 5891 return (SET_ERROR(EBUSY)); |
5892 | 5892 |
5893 if ((error = mod_remove(&modlinkage)) != 0) | 5893 if ((error = mod_remove(&modlinkage)) != 0) |
5894 return (error); | 5894 return (error); |
5895 | 5895 |
5896 zvol_fini(); | 5896 zvol_fini(); |