zfs_vfsops.c (209230) | zfs_vfsops.c (209962) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 5 unchanged lines hidden (view full) --- 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 5 unchanged lines hidden (view full) --- 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* |
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. | 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
23 * Use is subject to license terms. 24 */ 25 26#include <sys/types.h> 27#include <sys/param.h> 28#include <sys/systm.h> 29#include <sys/kernel.h> 30#include <sys/sysmacros.h> --- 19 unchanged lines hidden (view full) --- 50#include <sys/atomic.h> 51#include <sys/zfs_ioctl.h> 52#include <sys/zfs_ctldir.h> 53#include <sys/zfs_fuid.h> 54#include <sys/sunddi.h> 55#include <sys/dnlc.h> 56#include <sys/dmu_objset.h> 57#include <sys/spa_boot.h> | 23 * Use is subject to license terms. 24 */ 25 26#include <sys/types.h> 27#include <sys/param.h> 28#include <sys/systm.h> 29#include <sys/kernel.h> 30#include <sys/sysmacros.h> --- 19 unchanged lines hidden (view full) --- 50#include <sys/atomic.h> 51#include <sys/zfs_ioctl.h> 52#include <sys/zfs_ctldir.h> 53#include <sys/zfs_fuid.h> 54#include <sys/sunddi.h> 55#include <sys/dnlc.h> 56#include <sys/dmu_objset.h> 57#include <sys/spa_boot.h> |
58#include <sys/vdev_impl.h> /* VDEV_BOOT_VERSION */ | |
59 60struct mtx zfs_debug_mtx; 61MTX_SYSINIT(zfs_debug_mtx, &zfs_debug_mtx, "zfs_debug", MTX_DEF); 62 63SYSCTL_NODE(_vfs, OID_AUTO, zfs, CTLFLAG_RW, 0, "ZFS file system"); 64 65int zfs_super_owner = 0; 66SYSCTL_INT(_vfs_zfs, OID_AUTO, super_owner, CTLFLAG_RW, &zfs_super_owner, 0, --- 12 unchanged lines hidden (view full) --- 79SYSCTL_INT(_vfs_zfs_version, OID_AUTO, dmu_backup_header, CTLFLAG_RD, 80 &zfs_version_dmu_backup_header, 0, "DMU_BACKUP_HEADER_VERSION"); 81static int zfs_version_dmu_backup_stream = DMU_BACKUP_STREAM_VERSION; 82SYSCTL_INT(_vfs_zfs_version, OID_AUTO, dmu_backup_stream, CTLFLAG_RD, 83 &zfs_version_dmu_backup_stream, 0, "DMU_BACKUP_STREAM_VERSION"); 84static int zfs_version_spa = SPA_VERSION; 85SYSCTL_INT(_vfs_zfs_version, OID_AUTO, spa, CTLFLAG_RD, &zfs_version_spa, 0, 86 "SPA_VERSION"); | 58 59struct mtx zfs_debug_mtx; 60MTX_SYSINIT(zfs_debug_mtx, &zfs_debug_mtx, "zfs_debug", MTX_DEF); 61 62SYSCTL_NODE(_vfs, OID_AUTO, zfs, CTLFLAG_RW, 0, "ZFS file system"); 63 64int zfs_super_owner = 0; 65SYSCTL_INT(_vfs_zfs, OID_AUTO, super_owner, CTLFLAG_RW, &zfs_super_owner, 0, --- 12 unchanged lines hidden (view full) --- 78SYSCTL_INT(_vfs_zfs_version, OID_AUTO, dmu_backup_header, CTLFLAG_RD, 79 &zfs_version_dmu_backup_header, 0, "DMU_BACKUP_HEADER_VERSION"); 80static int zfs_version_dmu_backup_stream = DMU_BACKUP_STREAM_VERSION; 81SYSCTL_INT(_vfs_zfs_version, OID_AUTO, dmu_backup_stream, CTLFLAG_RD, 82 &zfs_version_dmu_backup_stream, 0, "DMU_BACKUP_STREAM_VERSION"); 83static int zfs_version_spa = SPA_VERSION; 84SYSCTL_INT(_vfs_zfs_version, OID_AUTO, spa, CTLFLAG_RD, &zfs_version_spa, 0, 85 "SPA_VERSION"); |
87static int zfs_version_vdev_boot = VDEV_BOOT_VERSION; 88SYSCTL_INT(_vfs_zfs_version, OID_AUTO, vdev_boot, CTLFLAG_RD, 89 &zfs_version_vdev_boot, 0, "VDEV_BOOT_VERSION"); | |
90static int zfs_version_zpl = ZPL_VERSION; 91SYSCTL_INT(_vfs_zfs_version, OID_AUTO, zpl, CTLFLAG_RD, &zfs_version_zpl, 0, 92 "ZPL_VERSION"); 93 94static int zfs_mount(vfs_t *vfsp); 95static int zfs_umount(vfs_t *vfsp, int fflag); 96static int zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp); 97static int zfs_statfs(vfs_t *vfsp, struct statfs *statp); --- 37 unchanged lines hidden (view full) --- 135 if (panicstr) 136 return (0); 137 138 if (vfsp != NULL) { 139 /* 140 * Sync a specific filesystem. 141 */ 142 zfsvfs_t *zfsvfs = vfsp->vfs_data; | 86static int zfs_version_zpl = ZPL_VERSION; 87SYSCTL_INT(_vfs_zfs_version, OID_AUTO, zpl, CTLFLAG_RD, &zfs_version_zpl, 0, 88 "ZPL_VERSION"); 89 90static int zfs_mount(vfs_t *vfsp); 91static int zfs_umount(vfs_t *vfsp, int fflag); 92static int zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp); 93static int zfs_statfs(vfs_t *vfsp, struct statfs *statp); --- 37 unchanged lines hidden (view full) --- 131 if (panicstr) 132 return (0); 133 134 if (vfsp != NULL) { 135 /* 136 * Sync a specific filesystem. 137 */ 138 zfsvfs_t *zfsvfs = vfsp->vfs_data; |
139 dsl_pool_t *dp; |
|
143 int error; 144 145 error = vfs_stdsync(vfsp, waitfor); 146 if (error != 0) 147 return (error); 148 149 ZFS_ENTER(zfsvfs); | 140 int error; 141 142 error = vfs_stdsync(vfsp, waitfor); 143 if (error != 0) 144 return (error); 145 146 ZFS_ENTER(zfsvfs); |
147 dp = dmu_objset_pool(zfsvfs->z_os); 148 149 /* 150 * If the system is shutting down, then skip any 151 * filesystems which may exist on a suspended pool. 152 */ 153 if (sys_shutdown && spa_suspended(dp->dp_spa)) { 154 ZFS_EXIT(zfsvfs); 155 return (0); 156 } 157 |
|
150 if (zfsvfs->z_log != NULL) 151 zil_commit(zfsvfs->z_log, UINT64_MAX, 0); 152 else | 158 if (zfsvfs->z_log != NULL) 159 zil_commit(zfsvfs->z_log, UINT64_MAX, 0); 160 else |
153 txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0); | 161 txg_wait_synced(dp, 0); |
154 ZFS_EXIT(zfsvfs); 155 } else { 156 /* 157 * Sync all ZFS filesystems. This is what happens when you 158 * run sync(1M). Unlike other filesystems, ZFS honors the 159 * request by waiting for all pools to commit all dirty data. 160 */ 161 spa_sync_allpools(); --- 316 unchanged lines hidden (view full) --- 478 (void) dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb, zfsvfs); 479 (void) dsl_prop_unregister(ds, "aclinherit", acl_inherit_changed_cb, 480 zfsvfs); 481 (void) dsl_prop_unregister(ds, "vscan", vscan_changed_cb, zfsvfs); 482 return (error); 483 484} 485 | 162 ZFS_EXIT(zfsvfs); 163 } else { 164 /* 165 * Sync all ZFS filesystems. This is what happens when you 166 * run sync(1M). Unlike other filesystems, ZFS honors the 167 * request by waiting for all pools to commit all dirty data. 168 */ 169 spa_sync_allpools(); --- 316 unchanged lines hidden (view full) --- 486 (void) dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb, zfsvfs); 487 (void) dsl_prop_unregister(ds, "aclinherit", acl_inherit_changed_cb, 488 zfsvfs); 489 (void) dsl_prop_unregister(ds, "vscan", vscan_changed_cb, zfsvfs); 490 return (error); 491 492} 493 |
494static void 495uidacct(objset_t *os, boolean_t isgroup, uint64_t fuid, 496 int64_t delta, dmu_tx_t *tx) 497{ 498 uint64_t used = 0; 499 char buf[32]; 500 int err; 501 uint64_t obj = isgroup ? DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT; 502 503 if (delta == 0) 504 return; 505 506 (void) snprintf(buf, sizeof (buf), "%llx", (longlong_t)fuid); 507 err = zap_lookup(os, obj, buf, 8, 1, &used); 508 ASSERT(err == 0 || err == ENOENT); 509 /* no underflow/overflow */ 510 ASSERT(delta > 0 || used >= -delta); 511 ASSERT(delta < 0 || used + delta > used); 512 used += delta; 513 if (used == 0) 514 err = zap_remove(os, obj, buf, tx); 515 else 516 err = zap_update(os, obj, buf, 8, 1, &used, tx); 517 ASSERT(err == 0); 518} 519 520static void 521zfs_space_delta_cb(objset_t *os, dmu_object_type_t bonustype, 522 void *oldbonus, void *newbonus, 523 uint64_t oldused, uint64_t newused, dmu_tx_t *tx) 524{ 525 znode_phys_t *oldznp = oldbonus; 526 znode_phys_t *newznp = newbonus; 527 528 if (bonustype != DMU_OT_ZNODE) 529 return; 530 531 /* We charge 512 for the dnode (if it's allocated). */ 532 if (oldznp->zp_gen != 0) 533 oldused += DNODE_SIZE; 534 if (newznp->zp_gen != 0) 535 newused += DNODE_SIZE; 536 537 if (oldznp->zp_uid == newznp->zp_uid) { 538 uidacct(os, B_FALSE, oldznp->zp_uid, newused-oldused, tx); 539 } else { 540 uidacct(os, B_FALSE, oldznp->zp_uid, -oldused, tx); 541 uidacct(os, B_FALSE, newznp->zp_uid, newused, tx); 542 } 543 544 if (oldznp->zp_gid == newznp->zp_gid) { 545 uidacct(os, B_TRUE, oldznp->zp_gid, newused-oldused, tx); 546 } else { 547 uidacct(os, B_TRUE, oldznp->zp_gid, -oldused, tx); 548 uidacct(os, B_TRUE, newznp->zp_gid, newused, tx); 549 } 550} 551 552static void 553fuidstr_to_sid(zfsvfs_t *zfsvfs, const char *fuidstr, 554 char *domainbuf, int buflen, uid_t *ridp) 555{ 556 uint64_t fuid; 557 const char *domain; 558 559 fuid = strtonum(fuidstr, NULL); 560 561 domain = zfs_fuid_find_by_idx(zfsvfs, FUID_INDEX(fuid)); 562 if (domain) 563 (void) strlcpy(domainbuf, domain, buflen); 564 else 565 domainbuf[0] = '\0'; 566 *ridp = FUID_RID(fuid); 567} 568 569static uint64_t 570zfs_userquota_prop_to_obj(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type) 571{ 572 switch (type) { 573 case ZFS_PROP_USERUSED: 574 return (DMU_USERUSED_OBJECT); 575 case ZFS_PROP_GROUPUSED: 576 return (DMU_GROUPUSED_OBJECT); 577 case ZFS_PROP_USERQUOTA: 578 return (zfsvfs->z_userquota_obj); 579 case ZFS_PROP_GROUPQUOTA: 580 return (zfsvfs->z_groupquota_obj); 581 } 582 return (0); 583} 584 585int 586zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, 587 uint64_t *cookiep, void *vbuf, uint64_t *bufsizep) 588{ 589 int error; 590 zap_cursor_t zc; 591 zap_attribute_t za; 592 zfs_useracct_t *buf = vbuf; 593 uint64_t obj; 594 595 if (!dmu_objset_userspace_present(zfsvfs->z_os)) 596 return (ENOTSUP); 597 598 obj = zfs_userquota_prop_to_obj(zfsvfs, type); 599 if (obj == 0) { 600 *bufsizep = 0; 601 return (0); 602 } 603 604 for (zap_cursor_init_serialized(&zc, zfsvfs->z_os, obj, *cookiep); 605 (error = zap_cursor_retrieve(&zc, &za)) == 0; 606 zap_cursor_advance(&zc)) { 607 if ((uintptr_t)buf - (uintptr_t)vbuf + sizeof (zfs_useracct_t) > 608 *bufsizep) 609 break; 610 611 fuidstr_to_sid(zfsvfs, za.za_name, 612 buf->zu_domain, sizeof (buf->zu_domain), &buf->zu_rid); 613 614 buf->zu_space = za.za_first_integer; 615 buf++; 616 } 617 if (error == ENOENT) 618 error = 0; 619 620 ASSERT3U((uintptr_t)buf - (uintptr_t)vbuf, <=, *bufsizep); 621 *bufsizep = (uintptr_t)buf - (uintptr_t)vbuf; 622 *cookiep = zap_cursor_serialize(&zc); 623 zap_cursor_fini(&zc); 624 return (error); 625} 626 627/* 628 * buf must be big enough (eg, 32 bytes) 629 */ |
|
486static int | 630static int |
631id_to_fuidstr(zfsvfs_t *zfsvfs, const char *domain, uid_t rid, 632 char *buf, boolean_t addok) 633{ 634 uint64_t fuid; 635 int domainid = 0; 636 637 if (domain && domain[0]) { 638 domainid = zfs_fuid_find_by_domain(zfsvfs, domain, NULL, addok); 639 if (domainid == -1) 640 return (ENOENT); 641 } 642 fuid = FUID_ENCODE(domainid, rid); 643 (void) sprintf(buf, "%llx", (longlong_t)fuid); 644 return (0); 645} 646 647int 648zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, 649 const char *domain, uint64_t rid, uint64_t *valp) 650{ 651 char buf[32]; 652 int err; 653 uint64_t obj; 654 655 *valp = 0; 656 657 if (!dmu_objset_userspace_present(zfsvfs->z_os)) 658 return (ENOTSUP); 659 660 obj = zfs_userquota_prop_to_obj(zfsvfs, type); 661 if (obj == 0) 662 return (0); 663 664 err = id_to_fuidstr(zfsvfs, domain, rid, buf, B_FALSE); 665 if (err) 666 return (err); 667 668 err = zap_lookup(zfsvfs->z_os, obj, buf, 8, 1, valp); 669 if (err == ENOENT) 670 err = 0; 671 return (err); 672} 673 674int 675zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, 676 const char *domain, uint64_t rid, uint64_t quota) 677{ 678 char buf[32]; 679 int err; 680 dmu_tx_t *tx; 681 uint64_t *objp; 682 boolean_t fuid_dirtied; 683 684 if (type != ZFS_PROP_USERQUOTA && type != ZFS_PROP_GROUPQUOTA) 685 return (EINVAL); 686 687 if (zfsvfs->z_version < ZPL_VERSION_USERSPACE) 688 return (ENOTSUP); 689 690 objp = (type == ZFS_PROP_USERQUOTA) ? &zfsvfs->z_userquota_obj : 691 &zfsvfs->z_groupquota_obj; 692 693 err = id_to_fuidstr(zfsvfs, domain, rid, buf, B_TRUE); 694 if (err) 695 return (err); 696 fuid_dirtied = zfsvfs->z_fuid_dirty; 697 698 tx = dmu_tx_create(zfsvfs->z_os); 699 dmu_tx_hold_zap(tx, *objp ? *objp : DMU_NEW_OBJECT, B_TRUE, NULL); 700 if (*objp == 0) { 701 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_TRUE, 702 zfs_userquota_prop_prefixes[type]); 703 } 704 if (fuid_dirtied) 705 zfs_fuid_txhold(zfsvfs, tx); 706 err = dmu_tx_assign(tx, TXG_WAIT); 707 if (err) { 708 dmu_tx_abort(tx); 709 return (err); 710 } 711 712 mutex_enter(&zfsvfs->z_lock); 713 if (*objp == 0) { 714 *objp = zap_create(zfsvfs->z_os, DMU_OT_USERGROUP_QUOTA, 715 DMU_OT_NONE, 0, tx); 716 VERIFY(0 == zap_add(zfsvfs->z_os, MASTER_NODE_OBJ, 717 zfs_userquota_prop_prefixes[type], 8, 1, objp, tx)); 718 } 719 mutex_exit(&zfsvfs->z_lock); 720 721 if (quota == 0) { 722 err = zap_remove(zfsvfs->z_os, *objp, buf, tx); 723 if (err == ENOENT) 724 err = 0; 725 } else { 726 err = zap_update(zfsvfs->z_os, *objp, buf, 8, 1, "a, tx); 727 } 728 ASSERT(err == 0); 729 if (fuid_dirtied) 730 zfs_fuid_sync(zfsvfs, tx); 731 dmu_tx_commit(tx); 732 return (err); 733} 734 735boolean_t 736zfs_usergroup_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid) 737{ 738 char buf[32]; 739 uint64_t used, quota, usedobj, quotaobj; 740 int err; 741 742 usedobj = isgroup ? DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT; 743 quotaobj = isgroup ? zfsvfs->z_groupquota_obj : zfsvfs->z_userquota_obj; 744 745 if (quotaobj == 0 || zfsvfs->z_replay) 746 return (B_FALSE); 747 748 (void) sprintf(buf, "%llx", (longlong_t)fuid); 749 err = zap_lookup(zfsvfs->z_os, quotaobj, buf, 8, 1, "a); 750 if (err != 0) 751 return (B_FALSE); 752 753 err = zap_lookup(zfsvfs->z_os, usedobj, buf, 8, 1, &used); 754 if (err != 0) 755 return (B_FALSE); 756 return (used >= quota); 757} 758 759int 760zfsvfs_create(const char *osname, int mode, zfsvfs_t **zvp) 761{ 762 objset_t *os; 763 zfsvfs_t *zfsvfs; 764 uint64_t zval; 765 int i, error; 766 767 if (error = dsl_prop_get_integer(osname, "readonly", &zval, NULL)) 768 return (error); 769 if (zval) 770 mode |= DS_MODE_READONLY; 771 772 error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &os); 773 if (error == EROFS) { 774 mode |= DS_MODE_READONLY; 775 error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &os); 776 } 777 if (error) 778 return (error); 779 780 /* 781 * Initialize the zfs-specific filesystem structure. 782 * Should probably make this a kmem cache, shuffle fields, 783 * and just bzero up to z_hold_mtx[]. 784 */ 785 zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP); 786 zfsvfs->z_vfs = NULL; 787 zfsvfs->z_parent = zfsvfs; 788 zfsvfs->z_max_blksz = SPA_MAXBLOCKSIZE; 789 zfsvfs->z_show_ctldir = ZFS_SNAPDIR_VISIBLE; 790 zfsvfs->z_os = os; 791 792 error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zfsvfs->z_version); 793 if (error) { 794 goto out; 795 } else if (zfsvfs->z_version > ZPL_VERSION) { 796 (void) printf("Mismatched versions: File system " 797 "is version %llu on-disk format, which is " 798 "incompatible with this software version %lld!", 799 (u_longlong_t)zfsvfs->z_version, ZPL_VERSION); 800 error = ENOTSUP; 801 goto out; 802 } 803 804 if ((error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &zval)) != 0) 805 goto out; 806 zfsvfs->z_norm = (int)zval; 807 808 if ((error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &zval)) != 0) 809 goto out; 810 zfsvfs->z_utf8 = (zval != 0); 811 812 if ((error = zfs_get_zplprop(os, ZFS_PROP_CASE, &zval)) != 0) 813 goto out; 814 zfsvfs->z_case = (uint_t)zval; 815 816 /* 817 * Fold case on file systems that are always or sometimes case 818 * insensitive. 819 */ 820 if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE || 821 zfsvfs->z_case == ZFS_CASE_MIXED) 822 zfsvfs->z_norm |= U8_TEXTPREP_TOUPPER; 823 824 zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os); 825 826 error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1, 827 &zfsvfs->z_root); 828 if (error) 829 goto out; 830 ASSERT(zfsvfs->z_root != 0); 831 832 error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1, 833 &zfsvfs->z_unlinkedobj); 834 if (error) 835 goto out; 836 837 error = zap_lookup(os, MASTER_NODE_OBJ, 838 zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA], 839 8, 1, &zfsvfs->z_userquota_obj); 840 if (error && error != ENOENT) 841 goto out; 842 843 error = zap_lookup(os, MASTER_NODE_OBJ, 844 zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA], 845 8, 1, &zfsvfs->z_groupquota_obj); 846 if (error && error != ENOENT) 847 goto out; 848 849 error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES, 8, 1, 850 &zfsvfs->z_fuid_obj); 851 if (error && error != ENOENT) 852 goto out; 853 854 error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SHARES_DIR, 8, 1, 855 &zfsvfs->z_shares_dir); 856 if (error && error != ENOENT) 857 goto out; 858 859 mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL); 860 mutex_init(&zfsvfs->z_online_recv_lock, NULL, MUTEX_DEFAULT, NULL); 861 mutex_init(&zfsvfs->z_lock, NULL, MUTEX_DEFAULT, NULL); 862 list_create(&zfsvfs->z_all_znodes, sizeof (znode_t), 863 offsetof(znode_t, z_link_node)); 864 rrw_init(&zfsvfs->z_teardown_lock); 865 rw_init(&zfsvfs->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL); 866 rw_init(&zfsvfs->z_fuid_lock, NULL, RW_DEFAULT, NULL); 867 for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) 868 mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); 869 870 *zvp = zfsvfs; 871 return (0); 872 873out: 874 dmu_objset_close(os); 875 *zvp = NULL; 876 kmem_free(zfsvfs, sizeof (zfsvfs_t)); 877 return (error); 878} 879 880static int |
|
487zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) 488{ 489 int error; 490 491 error = zfs_register_callbacks(zfsvfs->z_vfs); 492 if (error) 493 return (error); 494 --- 51 unchanged lines hidden (view full) --- 546 * record. 547 * 548 * But when we are in ziltest mode, we advance the "open 549 * txg" without actually spa_sync()-ing the changes to 550 * disk. So we would see that object N is still 551 * allocated and in the unlinked set, and there is an 552 * intent log record saying to allocate it. 553 */ | 881zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) 882{ 883 int error; 884 885 error = zfs_register_callbacks(zfsvfs->z_vfs); 886 if (error) 887 return (error); 888 --- 51 unchanged lines hidden (view full) --- 940 * record. 941 * 942 * But when we are in ziltest mode, we advance the "open 943 * txg" without actually spa_sync()-ing the changes to 944 * disk. So we would see that object N is still 945 * allocated and in the unlinked set, and there is an 946 * intent log record saying to allocate it. 947 */ |
554 zil_replay(zfsvfs->z_os, zfsvfs, &zfsvfs->z_assign, 555 zfs_replay_vector, zfs_unlinked_drain); | 948 zfsvfs->z_replay = B_TRUE; 949 zil_replay(zfsvfs->z_os, zfsvfs, zfs_replay_vector); 950 zfsvfs->z_replay = B_FALSE; |
556 } 557 zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */ 558 } 559 560 return (0); 561} 562 | 951 } 952 zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */ 953 } 954 955 return (0); 956} 957 |
563static void 564zfs_freezfsvfs(zfsvfs_t *zfsvfs) | 958void 959zfsvfs_free(zfsvfs_t *zfsvfs) |
565{ | 960{ |
961 int i; 962 963 zfs_fuid_destroy(zfsvfs); 964 |
|
566 mutex_destroy(&zfsvfs->z_znodes_lock); 567 mutex_destroy(&zfsvfs->z_online_recv_lock); | 965 mutex_destroy(&zfsvfs->z_znodes_lock); 966 mutex_destroy(&zfsvfs->z_online_recv_lock); |
967 mutex_destroy(&zfsvfs->z_lock); |
|
568 list_destroy(&zfsvfs->z_all_znodes); 569 rrw_destroy(&zfsvfs->z_teardown_lock); 570 rw_destroy(&zfsvfs->z_teardown_inactive_lock); 571 rw_destroy(&zfsvfs->z_fuid_lock); | 968 list_destroy(&zfsvfs->z_all_znodes); 969 rrw_destroy(&zfsvfs->z_teardown_lock); 970 rw_destroy(&zfsvfs->z_teardown_inactive_lock); 971 rw_destroy(&zfsvfs->z_fuid_lock); |
972 for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) 973 mutex_destroy(&zfsvfs->z_hold_mtx[i]); |
|
572 kmem_free(zfsvfs, sizeof (zfsvfs_t)); 573} 574 | 974 kmem_free(zfsvfs, sizeof (zfsvfs_t)); 975} 976 |
977static void 978zfs_set_fuid_feature(zfsvfs_t *zfsvfs) 979{ 980 zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os); 981 if (zfsvfs->z_use_fuids && zfsvfs->z_vfs) { 982 vfs_set_feature(zfsvfs->z_vfs, VFSFT_XVATTR); 983 vfs_set_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS); 984 vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS); 985 vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE); 986 } 987} 988 |
|
575static int 576zfs_domount(vfs_t *vfsp, char *osname) 577{ | 989static int 990zfs_domount(vfs_t *vfsp, char *osname) 991{ |
578 uint64_t recordsize, readonly; | 992 uint64_t recordsize, fsid_guid; |
579 int error = 0; | 993 int error = 0; |
580 int mode; | |
581 zfsvfs_t *zfsvfs; | 994 zfsvfs_t *zfsvfs; |
582 znode_t *zp = NULL; | 995 vnode_t *vp; |
583 584 ASSERT(vfsp); 585 ASSERT(osname); 586 | 996 997 ASSERT(vfsp); 998 ASSERT(osname); 999 |
587 /* 588 * Initialize the zfs-specific filesystem structure. 589 * Should probably make this a kmem cache, shuffle fields, 590 * and just bzero up to z_hold_mtx[]. 591 */ 592 zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP); | 1000 error = zfsvfs_create(osname, DS_MODE_OWNER, &zfsvfs); 1001 if (error) 1002 return (error); |
593 zfsvfs->z_vfs = vfsp; | 1003 zfsvfs->z_vfs = vfsp; |
594 zfsvfs->z_parent = zfsvfs; 595 zfsvfs->z_assign = TXG_NOWAIT; 596 zfsvfs->z_max_blksz = SPA_MAXBLOCKSIZE; 597 zfsvfs->z_show_ctldir = ZFS_SNAPDIR_VISIBLE; | |
598 | 1004 |
599 mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL); 600 mutex_init(&zfsvfs->z_online_recv_lock, NULL, MUTEX_DEFAULT, NULL); 601 list_create(&zfsvfs->z_all_znodes, sizeof (znode_t), 602 offsetof(znode_t, z_link_node)); 603 rrw_init(&zfsvfs->z_teardown_lock); 604 rw_init(&zfsvfs->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL); 605 rw_init(&zfsvfs->z_fuid_lock, NULL, RW_DEFAULT, NULL); 606 | |
607 if (error = dsl_prop_get_integer(osname, "recordsize", &recordsize, 608 NULL)) 609 goto out; 610 zfsvfs->z_vfs->vfs_bsize = SPA_MINBLOCKSIZE; 611 zfsvfs->z_vfs->mnt_stat.f_iosize = recordsize; 612 613 vfsp->vfs_data = zfsvfs; 614 vfsp->mnt_flag |= MNT_LOCAL; 615 vfsp->mnt_kern_flag |= MNTK_MPSAFE; 616 vfsp->mnt_kern_flag |= MNTK_LOOKUP_SHARED; 617 vfsp->mnt_kern_flag |= MNTK_SHARED_WRITES; 618 | 1005 if (error = dsl_prop_get_integer(osname, "recordsize", &recordsize, 1006 NULL)) 1007 goto out; 1008 zfsvfs->z_vfs->vfs_bsize = SPA_MINBLOCKSIZE; 1009 zfsvfs->z_vfs->mnt_stat.f_iosize = recordsize; 1010 1011 vfsp->vfs_data = zfsvfs; 1012 vfsp->mnt_flag |= MNT_LOCAL; 1013 vfsp->mnt_kern_flag |= MNTK_MPSAFE; 1014 vfsp->mnt_kern_flag |= MNTK_LOOKUP_SHARED; 1015 vfsp->mnt_kern_flag |= MNTK_SHARED_WRITES; 1016 |
619 if (error = dsl_prop_get_integer(osname, "readonly", &readonly, NULL)) 620 goto out; | |
621 | 1017 |
622 mode = DS_MODE_OWNER; 623 if (readonly) 624 mode |= DS_MODE_READONLY; | 1018 /* 1019 * The fsid is 64 bits, composed of an 8-bit fs type, which 1020 * separates our fsid from any other filesystem types, and a 1021 * 56-bit objset unique ID. The objset unique ID is unique to 1022 * all objsets open on this system, provided by unique_create(). 1023 * The 8-bit fs type must be put in the low bits of fsid[1] 1024 * because that's where other Solaris filesystems put it. 1025 */ 1026 fsid_guid = dmu_objset_fsid_guid(zfsvfs->z_os); 1027 ASSERT((fsid_guid & ~((1ULL<<56)-1)) == 0); 1028 vfsp->vfs_fsid.val[0] = fsid_guid; 1029 vfsp->vfs_fsid.val[1] = ((fsid_guid>>32) << 8) | 1030 vfsp->mnt_vfc->vfc_typenum & 0xFF; |
625 | 1031 |
626 error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &zfsvfs->z_os); 627 if (error == EROFS) { 628 mode = DS_MODE_OWNER | DS_MODE_READONLY; 629 error = dmu_objset_open(osname, DMU_OST_ZFS, mode, 630 &zfsvfs->z_os); 631 } 632 633 if (error) 634 goto out; 635 636 if (error = zfs_init_fs(zfsvfs, &zp)) 637 goto out; 638 | |
639 /* 640 * Set features for file system. 641 */ | 1032 /* 1033 * Set features for file system. 1034 */ |
642 zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os); 643 if (zfsvfs->z_use_fuids) { 644 vfs_set_feature(vfsp, VFSFT_XVATTR); 645 vfs_set_feature(vfsp, VFSFT_SYSATTR_VIEWS); 646 vfs_set_feature(vfsp, VFSFT_ACEMASKONACCESS); 647 vfs_set_feature(vfsp, VFSFT_ACLONCREATE); 648 } | 1035 zfs_set_fuid_feature(zfsvfs); |
649 if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE) { 650 vfs_set_feature(vfsp, VFSFT_DIRENTFLAGS); 651 vfs_set_feature(vfsp, VFSFT_CASEINSENSITIVE); 652 vfs_set_feature(vfsp, VFSFT_NOCASESENSITIVE); 653 } else if (zfsvfs->z_case == ZFS_CASE_MIXED) { 654 vfs_set_feature(vfsp, VFSFT_DIRENTFLAGS); 655 vfs_set_feature(vfsp, VFSFT_CASEINSENSITIVE); 656 } 657 658 if (dmu_objset_is_snapshot(zfsvfs->z_os)) { 659 uint64_t pval; 660 | 1036 if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE) { 1037 vfs_set_feature(vfsp, VFSFT_DIRENTFLAGS); 1038 vfs_set_feature(vfsp, VFSFT_CASEINSENSITIVE); 1039 vfs_set_feature(vfsp, VFSFT_NOCASESENSITIVE); 1040 } else if (zfsvfs->z_case == ZFS_CASE_MIXED) { 1041 vfs_set_feature(vfsp, VFSFT_DIRENTFLAGS); 1042 vfs_set_feature(vfsp, VFSFT_CASEINSENSITIVE); 1043 } 1044 1045 if (dmu_objset_is_snapshot(zfsvfs->z_os)) { 1046 uint64_t pval; 1047 |
661 ASSERT(mode & DS_MODE_READONLY); | |
662 atime_changed_cb(zfsvfs, B_FALSE); 663 readonly_changed_cb(zfsvfs, B_TRUE); 664 if (error = dsl_prop_get_integer(osname, "xattr", &pval, NULL)) 665 goto out; 666 xattr_changed_cb(zfsvfs, pval); 667 zfsvfs->z_issnap = B_TRUE; | 1048 atime_changed_cb(zfsvfs, B_FALSE); 1049 readonly_changed_cb(zfsvfs, B_TRUE); 1050 if (error = dsl_prop_get_integer(osname, "xattr", &pval, NULL)) 1051 goto out; 1052 xattr_changed_cb(zfsvfs, pval); 1053 zfsvfs->z_issnap = B_TRUE; |
1054 1055 mutex_enter(&zfsvfs->z_os->os->os_user_ptr_lock); 1056 dmu_objset_set_user(zfsvfs->z_os, zfsvfs); 1057 mutex_exit(&zfsvfs->z_os->os->os_user_ptr_lock); |
|
668 } else { 669 error = zfsvfs_setup(zfsvfs, B_TRUE); 670 } 671 672 vfs_mountedfrom(vfsp, osname); | 1058 } else { 1059 error = zfsvfs_setup(zfsvfs, B_TRUE); 1060 } 1061 1062 vfs_mountedfrom(vfsp, osname); |
1063 /* Grab extra reference. */ 1064 VERIFY(VFS_ROOT(vfsp, LK_EXCLUSIVE, &vp) == 0); 1065 VOP_UNLOCK(vp, 0); |
|
673 674 if (!zfsvfs->z_issnap) 675 zfsctl_create(zfsvfs); 676out: 677 if (error) { | 1066 1067 if (!zfsvfs->z_issnap) 1068 zfsctl_create(zfsvfs); 1069out: 1070 if (error) { |
678 if (zfsvfs->z_os) 679 dmu_objset_close(zfsvfs->z_os); 680 zfs_freezfsvfs(zfsvfs); | 1071 dmu_objset_close(zfsvfs->z_os); 1072 zfsvfs_free(zfsvfs); |
681 } else { 682 atomic_add_32(&zfs_active_fs_count, 1); 683 } 684 685 return (error); 686} 687 688void --- 85 unchanged lines hidden (view full) --- 774 vattr.va_mask = AT_UID; 775 776 vn_lock(mvp, LK_SHARED | LK_RETRY); 777 if (error = VOP_GETATTR(mvp, &vattr, cr)) { 778 VOP_UNLOCK(mvp, 0); 779 goto out; 780 } 781 | 1073 } else { 1074 atomic_add_32(&zfs_active_fs_count, 1); 1075 } 1076 1077 return (error); 1078} 1079 1080void --- 85 unchanged lines hidden (view full) --- 1166 vattr.va_mask = AT_UID; 1167 1168 vn_lock(mvp, LK_SHARED | LK_RETRY); 1169 if (error = VOP_GETATTR(mvp, &vattr, cr)) { 1170 VOP_UNLOCK(mvp, 0); 1171 goto out; 1172 } 1173 |
782#if 0 /* CHECK THIS! Is probably needed for zfs_suser. */ | |
783 if (secpolicy_vnode_owner(mvp, cr, vattr.va_uid) != 0 && 784 VOP_ACCESS(mvp, VWRITE, cr, td) != 0) { | 1174 if (secpolicy_vnode_owner(mvp, cr, vattr.va_uid) != 0 && 1175 VOP_ACCESS(mvp, VWRITE, cr, td) != 0) { |
785 error = EPERM; 786 goto out; 787 } 788#else 789 if (error = secpolicy_vnode_owner(mvp, cr, vattr.va_uid)) { | |
790 VOP_UNLOCK(mvp, 0); 791 goto out; 792 } | 1176 VOP_UNLOCK(mvp, 0); 1177 goto out; 1178 } |
793 794 if (error = VOP_ACCESS(mvp, VWRITE, cr, td)) { 795 VOP_UNLOCK(mvp, 0); 796 goto out; 797 } | |
798 VOP_UNLOCK(mvp, 0); | 1179 VOP_UNLOCK(mvp, 0); |
799#endif | |
800 } 801 802 secpolicy_fs_mount_clearopts(cr, vfsp); 803 } 804 805 /* 806 * Refuse to mount a filesystem if we are in a local zone and the 807 * dataset is not visible. --- 13 unchanged lines hidden (view full) --- 821 zfs_unregister_callbacks(vfsp->vfs_data); 822 error = zfs_register_callbacks(vfsp); 823 goto out; 824 } 825 826 DROP_GIANT(); 827 error = zfs_domount(vfsp, osname); 828 PICKUP_GIANT(); | 1180 } 1181 1182 secpolicy_fs_mount_clearopts(cr, vfsp); 1183 } 1184 1185 /* 1186 * Refuse to mount a filesystem if we are in a local zone and the 1187 * dataset is not visible. --- 13 unchanged lines hidden (view full) --- 1201 zfs_unregister_callbacks(vfsp->vfs_data); 1202 error = zfs_register_callbacks(vfsp); 1203 goto out; 1204 } 1205 1206 DROP_GIANT(); 1207 error = zfs_domount(vfsp, osname); 1208 PICKUP_GIANT(); |
1209 1210 /* 1211 * Add an extra VFS_HOLD on our parent vfs so that it can't 1212 * disappear due to a forced unmount. 1213 */ 1214 if (error == 0 && ((zfsvfs_t *)vfsp->vfs_data)->z_issnap) 1215 VFS_HOLD(mvp->v_vfsp); 1216 1217 /* 1218 * Add an extra VFS_HOLD on our parent vfs so that it can't 1219 * disappear due to a forced unmount. 1220 */ 1221 if (error == 0 && ((zfsvfs_t *)vfsp->vfs_data)->z_issnap) 1222 VFS_HOLD(mvp->v_vfsp); 1223 |
|
829out: 830 return (error); 831} 832 833static int 834zfs_statfs(vfs_t *vfsp, struct statfs *statp) 835{ 836 zfsvfs_t *zfsvfs = vfsp->vfs_data; --- 183 unchanged lines hidden (view full) --- 1020 1021 return (0); 1022} 1023 1024/*ARGSUSED*/ 1025static int 1026zfs_umount(vfs_t *vfsp, int fflag) 1027{ | 1224out: 1225 return (error); 1226} 1227 1228static int 1229zfs_statfs(vfs_t *vfsp, struct statfs *statp) 1230{ 1231 zfsvfs_t *zfsvfs = vfsp->vfs_data; --- 183 unchanged lines hidden (view full) --- 1415 1416 return (0); 1417} 1418 1419/*ARGSUSED*/ 1420static int 1421zfs_umount(vfs_t *vfsp, int fflag) 1422{ |
1423 kthread_t *td = curthread; |
|
1028 zfsvfs_t *zfsvfs = vfsp->vfs_data; 1029 objset_t *os; | 1424 zfsvfs_t *zfsvfs = vfsp->vfs_data; 1425 objset_t *os; |
1030 cred_t *cr = curthread->td_ucred; | 1426 cred_t *cr = td->td_ucred; |
1031 int ret; 1032 1033 ret = secpolicy_fs_unmount(cr, vfsp); 1034 if (ret) { 1035 ret = dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource), 1036 ZFS_DELEG_PERM_MOUNT, cr); 1037 if (ret) 1038 return (ret); --- 8 unchanged lines hidden (view full) --- 1047 1048 /* 1049 * Unmount any snapshots mounted under .zfs before unmounting the 1050 * dataset itself. 1051 */ 1052 if (zfsvfs->z_ctldir != NULL) { 1053 if ((ret = zfsctl_umount_snapshots(vfsp, fflag, cr)) != 0) 1054 return (ret); | 1427 int ret; 1428 1429 ret = secpolicy_fs_unmount(cr, vfsp); 1430 if (ret) { 1431 ret = dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource), 1432 ZFS_DELEG_PERM_MOUNT, cr); 1433 if (ret) 1434 return (ret); --- 8 unchanged lines hidden (view full) --- 1443 1444 /* 1445 * Unmount any snapshots mounted under .zfs before unmounting the 1446 * dataset itself. 1447 */ 1448 if (zfsvfs->z_ctldir != NULL) { 1449 if ((ret = zfsctl_umount_snapshots(vfsp, fflag, cr)) != 0) 1450 return (ret); |
1055 ret = vflush(vfsp, 0, 0, curthread); | 1451 ret = vflush(vfsp, 0, 0, td); |
1056 ASSERT(ret == EBUSY); 1057 if (!(fflag & MS_FORCE)) { 1058 if (zfsvfs->z_ctldir->v_count > 1) 1059 return (EBUSY); 1060 ASSERT(zfsvfs->z_ctldir->v_count == 1); 1061 } 1062 zfsctl_destroy(zfsvfs); 1063 ASSERT(zfsvfs->z_ctldir == NULL); --- 8 unchanged lines hidden (view full) --- 1072 rrw_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG); 1073 zfsvfs->z_unmounted = B_TRUE; 1074 rrw_exit(&zfsvfs->z_teardown_lock, FTAG); 1075 } 1076 1077 /* 1078 * Flush all the files. 1079 */ | 1452 ASSERT(ret == EBUSY); 1453 if (!(fflag & MS_FORCE)) { 1454 if (zfsvfs->z_ctldir->v_count > 1) 1455 return (EBUSY); 1456 ASSERT(zfsvfs->z_ctldir->v_count == 1); 1457 } 1458 zfsctl_destroy(zfsvfs); 1459 ASSERT(zfsvfs->z_ctldir == NULL); --- 8 unchanged lines hidden (view full) --- 1468 rrw_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG); 1469 zfsvfs->z_unmounted = B_TRUE; 1470 rrw_exit(&zfsvfs->z_teardown_lock, FTAG); 1471 } 1472 1473 /* 1474 * Flush all the files. 1475 */ |
1080 ret = vflush(vfsp, 1, (fflag & MS_FORCE) ? FORCECLOSE : 0, curthread); | 1476 ret = vflush(vfsp, 1, (fflag & MS_FORCE) ? FORCECLOSE : 0, td); |
1081 if (ret != 0) { 1082 if (!zfsvfs->z_issnap) { 1083 zfsctl_create(zfsvfs); 1084 ASSERT(zfsvfs->z_ctldir != NULL); 1085 } 1086 return (ret); 1087 } 1088 --- 210 unchanged lines hidden (view full) --- 1299 1300/* 1301 * Block out VOPs and close zfsvfs_t::z_os 1302 * 1303 * Note, if successful, then we return with the 'z_teardown_lock' and 1304 * 'z_teardown_inactive_lock' write held. 1305 */ 1306int | 1477 if (ret != 0) { 1478 if (!zfsvfs->z_issnap) { 1479 zfsctl_create(zfsvfs); 1480 ASSERT(zfsvfs->z_ctldir != NULL); 1481 } 1482 return (ret); 1483 } 1484 --- 210 unchanged lines hidden (view full) --- 1695 1696/* 1697 * Block out VOPs and close zfsvfs_t::z_os 1698 * 1699 * Note, if successful, then we return with the 'z_teardown_lock' and 1700 * 'z_teardown_inactive_lock' write held. 1701 */ 1702int |
1307zfs_suspend_fs(zfsvfs_t *zfsvfs, char *name, int *mode) | 1703zfs_suspend_fs(zfsvfs_t *zfsvfs, char *name, int *modep) |
1308{ 1309 int error; 1310 1311 if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0) 1312 return (error); 1313 | 1704{ 1705 int error; 1706 1707 if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0) 1708 return (error); 1709 |
1314 *mode = zfsvfs->z_os->os_mode; 1315 dmu_objset_name(zfsvfs->z_os, name); | 1710 *modep = zfsvfs->z_os->os_mode; 1711 if (name) 1712 dmu_objset_name(zfsvfs->z_os, name); |
1316 dmu_objset_close(zfsvfs->z_os); 1317 1318 return (0); 1319} 1320 1321/* 1322 * Reopen zfsvfs_t::z_os and release VOPs. 1323 */ --- 42 unchanged lines hidden (view full) --- 1366 } 1367 return (err); 1368} 1369 1370static void 1371zfs_freevfs(vfs_t *vfsp) 1372{ 1373 zfsvfs_t *zfsvfs = vfsp->vfs_data; | 1713 dmu_objset_close(zfsvfs->z_os); 1714 1715 return (0); 1716} 1717 1718/* 1719 * Reopen zfsvfs_t::z_os and release VOPs. 1720 */ --- 42 unchanged lines hidden (view full) --- 1763 } 1764 return (err); 1765} 1766 1767static void 1768zfs_freevfs(vfs_t *vfsp) 1769{ 1770 zfsvfs_t *zfsvfs = vfsp->vfs_data; |
1374 int i; | |
1375 | 1771 |
1376 for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) 1377 mutex_destroy(&zfsvfs->z_hold_mtx[i]); | 1772 /* 1773 * If this is a snapshot, we have an extra VFS_HOLD on our parent 1774 * from zfs_mount(). Release it here. 1775 */ 1776 if (zfsvfs->z_issnap) 1777 VFS_RELE(zfsvfs->z_parent->z_vfs); |
1378 | 1778 |
1379 zfs_fuid_destroy(zfsvfs); 1380 zfs_freezfsvfs(zfsvfs); | 1779 zfsvfs_free(zfsvfs); |
1381 1382 atomic_add_32(&zfs_active_fs_count, -1); 1383} 1384 1385#ifdef __i386__ 1386static int desiredvnodes_backup; 1387#endif 1388 --- 44 unchanged lines hidden (view full) --- 1433 zfsctl_init(); 1434 1435 /* 1436 * Reduce number of vnode. Originally number of vnodes is calculated 1437 * with UFS inode in mind. We reduce it here, because it's too big for 1438 * ZFS/i386. 1439 */ 1440 zfs_vnodes_adjust(); | 1780 1781 atomic_add_32(&zfs_active_fs_count, -1); 1782} 1783 1784#ifdef __i386__ 1785static int desiredvnodes_backup; 1786#endif 1787 --- 44 unchanged lines hidden (view full) --- 1832 zfsctl_init(); 1833 1834 /* 1835 * Reduce number of vnode. Originally number of vnodes is calculated 1836 * with UFS inode in mind. We reduce it here, because it's too big for 1837 * ZFS/i386. 1838 */ 1839 zfs_vnodes_adjust(); |
1840 1841 dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb); |
|
1441} 1442 1443void 1444zfs_fini(void) 1445{ 1446 zfsctl_fini(); 1447 zfs_znode_fini(); 1448 zfs_vnodes_adjust_back(); 1449} 1450 1451int 1452zfs_busy(void) 1453{ 1454 return (zfs_active_fs_count != 0); 1455} 1456 1457int | 1842} 1843 1844void 1845zfs_fini(void) 1846{ 1847 zfsctl_fini(); 1848 zfs_znode_fini(); 1849 zfs_vnodes_adjust_back(); 1850} 1851 1852int 1853zfs_busy(void) 1854{ 1855 return (zfs_active_fs_count != 0); 1856} 1857 1858int |
1458zfs_set_version(const char *name, uint64_t newvers) | 1859zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers) |
1459{ 1460 int error; | 1860{ 1861 int error; |
1461 objset_t *os; | 1862 objset_t *os = zfsvfs->z_os; |
1462 dmu_tx_t *tx; | 1863 dmu_tx_t *tx; |
1463 uint64_t curvers; | |
1464 | 1864 |
1465 /* 1466 * XXX for now, require that the filesystem be unmounted. Would 1467 * be nice to find the zfsvfs_t and just update that if 1468 * possible. 1469 */ 1470 | |
1471 if (newvers < ZPL_VERSION_INITIAL || newvers > ZPL_VERSION) 1472 return (EINVAL); 1473 | 1865 if (newvers < ZPL_VERSION_INITIAL || newvers > ZPL_VERSION) 1866 return (EINVAL); 1867 |
1474 error = dmu_objset_open(name, DMU_OST_ZFS, DS_MODE_OWNER, &os); 1475 if (error) 1476 return (error); | 1868 if (newvers < zfsvfs->z_version) 1869 return (EINVAL); |
1477 | 1870 |
1478 error = zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR, 1479 8, 1, &curvers); 1480 if (error) 1481 goto out; 1482 if (newvers < curvers) { 1483 error = EINVAL; 1484 goto out; 1485 } 1486 | |
1487 tx = dmu_tx_create(os); | 1871 tx = dmu_tx_create(os); |
1488 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, 0, ZPL_VERSION_STR); | 1872 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_FALSE, ZPL_VERSION_STR); |
1489 error = dmu_tx_assign(tx, TXG_WAIT); 1490 if (error) { 1491 dmu_tx_abort(tx); | 1873 error = dmu_tx_assign(tx, TXG_WAIT); 1874 if (error) { 1875 dmu_tx_abort(tx); |
1492 goto out; | 1876 return (error); |
1493 } | 1877 } |
1494 error = zap_update(os, MASTER_NODE_OBJ, ZPL_VERSION_STR, 8, 1, 1495 &newvers, tx); | 1878 error = zap_update(os, MASTER_NODE_OBJ, ZPL_VERSION_STR, 1879 8, 1, &newvers, tx); |
1496 | 1880 |
1881 if (error) { 1882 dmu_tx_commit(tx); 1883 return (error); 1884 } 1885 |
|
1497 spa_history_internal_log(LOG_DS_UPGRADE, 1498 dmu_objset_spa(os), tx, CRED(), | 1886 spa_history_internal_log(LOG_DS_UPGRADE, 1887 dmu_objset_spa(os), tx, CRED(), |
1499 "oldver=%llu newver=%llu dataset = %llu", curvers, newvers, 1500 dmu_objset_id(os)); | 1888 "oldver=%llu newver=%llu dataset = %llu", 1889 zfsvfs->z_version, newvers, dmu_objset_id(os)); 1890 |
1501 dmu_tx_commit(tx); 1502 | 1891 dmu_tx_commit(tx); 1892 |
1503out: 1504 dmu_objset_close(os); 1505 return (error); | 1893 zfsvfs->z_version = newvers; 1894 1895 if (zfsvfs->z_version >= ZPL_VERSION_FUID) 1896 zfs_set_fuid_feature(zfsvfs); 1897 1898 return (0); |
1506} 1507/* 1508 * Read a property stored within the master node. 1509 */ 1510int 1511zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value) 1512{ 1513 const char *pname; --- 34 unchanged lines hidden --- | 1899} 1900/* 1901 * Read a property stored within the master node. 1902 */ 1903int 1904zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value) 1905{ 1906 const char *pname; --- 34 unchanged lines hidden --- |