Deleted Added
full compact
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, &quota, 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, &quota);
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 ---