| @@ -111,26 +111,27 @@ struct vfsops zfs_vfsops = { | | | @@ -111,26 +111,27 @@ struct vfsops zfs_vfsops = { |
111 | .vfs_statfs = zfs_statfs, | | 111 | .vfs_statfs = zfs_statfs, |
112 | .vfs_vget = zfs_vget, | | 112 | .vfs_vget = zfs_vget, |
113 | .vfs_sync = zfs_sync, | | 113 | .vfs_sync = zfs_sync, |
114 | .vfs_checkexp = zfs_checkexp, | | 114 | .vfs_checkexp = zfs_checkexp, |
115 | .vfs_fhtovp = zfs_fhtovp, | | 115 | .vfs_fhtovp = zfs_fhtovp, |
116 | }; | | 116 | }; |
117 | | | 117 | |
118 | VFS_SET(zfs_vfsops, zfs, VFCF_JAIL | VFCF_DELEGADMIN); | | 118 | VFS_SET(zfs_vfsops, zfs, VFCF_JAIL | VFCF_DELEGADMIN); |
119 | | | 119 | |
120 | #endif /* __FreeBSD_kernel__ */ | | 120 | #endif /* __FreeBSD_kernel__ */ |
121 | | | 121 | |
122 | #ifdef __NetBSD__ | | 122 | #ifdef __NetBSD__ |
123 | | | 123 | |
| | | 124 | #include <sys/fstrans.h> |
124 | #include <sys/mkdev.h> | | 125 | #include <sys/mkdev.h> |
125 | #include <miscfs/genfs/genfs.h> | | 126 | #include <miscfs/genfs/genfs.h> |
126 | | | 127 | |
127 | int zfs_debug_level; | | 128 | int zfs_debug_level; |
128 | kmutex_t zfs_debug_mtx; | | 129 | kmutex_t zfs_debug_mtx; |
129 | | | 130 | |
130 | #define DROP_GIANT() /* nothing */ | | 131 | #define DROP_GIANT() /* nothing */ |
131 | #define PICKUP_GIANT() /* nothing */ | | 132 | #define PICKUP_GIANT() /* nothing */ |
132 | #define vfs_stdsync(a, b) 0 | | 133 | #define vfs_stdsync(a, b) 0 |
133 | | | 134 | |
134 | static int zfs_mount(vfs_t *vfsp, const char *path, void *data, size_t *data_len); | | 135 | static int zfs_mount(vfs_t *vfsp, const char *path, void *data, size_t *data_len); |
135 | static int zfs_umount(vfs_t *vfsp, int fflag); | | 136 | static int zfs_umount(vfs_t *vfsp, int fflag); |
136 | static int zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp); | | 137 | static int zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp); |
| @@ -2659,39 +2660,58 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int | | | @@ -2659,39 +2660,58 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int |
2659 | /* | | 2660 | /* |
2660 | * Block out VOPs and close zfsvfs_t::z_os | | 2661 | * Block out VOPs and close zfsvfs_t::z_os |
2661 | * | | 2662 | * |
2662 | * Note, if successful, then we return with the 'z_teardown_lock' and | | 2663 | * Note, if successful, then we return with the 'z_teardown_lock' and |
2663 | * 'z_teardown_inactive_lock' write held. We leave ownership of the underlying | | 2664 | * 'z_teardown_inactive_lock' write held. We leave ownership of the underlying |
2664 | * dataset and objset intact so that they can be atomically handed off during | | 2665 | * dataset and objset intact so that they can be atomically handed off during |
2665 | * a subsequent rollback or recv operation and the resume thereafter. | | 2666 | * a subsequent rollback or recv operation and the resume thereafter. |
2666 | */ | | 2667 | */ |
2667 | int | | 2668 | int |
2668 | zfs_suspend_fs(zfsvfs_t *zfsvfs) | | 2669 | zfs_suspend_fs(zfsvfs_t *zfsvfs) |
2669 | { | | 2670 | { |
2670 | int error; | | 2671 | int error; |
2671 | | | 2672 | |
| | | 2673 | #ifdef __NetBSD__ |
| | | 2674 | if ((error = vfs_suspend(zfsvfs->z_vfs, 0)) != 0) |
| | | 2675 | return error; |
| | | 2676 | if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0) { |
| | | 2677 | vfs_resume(zfsvfs->z_vfs); |
| | | 2678 | return (error); |
| | | 2679 | } |
| | | 2680 | #else |
2672 | if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0) | | 2681 | if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0) |
2673 | return (error); | | 2682 | return (error); |
| | | 2683 | #endif |
2674 | | | 2684 | |
2675 | return (0); | | 2685 | return (0); |
2676 | } | | 2686 | } |
2677 | | | 2687 | |
2678 | /* | | 2688 | /* |
2679 | * Rebuild SA and release VOPs. Note that ownership of the underlying dataset | | 2689 | * Rebuild SA and release VOPs. Note that ownership of the underlying dataset |
2680 | * is an invariant across any of the operations that can be performed while the | | 2690 | * is an invariant across any of the operations that can be performed while the |
2681 | * filesystem was suspended. Whether it succeeded or failed, the preconditions | | 2691 | * filesystem was suspended. Whether it succeeded or failed, the preconditions |
2682 | * are the same: the relevant objset and associated dataset are owned by | | 2692 | * are the same: the relevant objset and associated dataset are owned by |
2683 | * zfsvfs, held, and long held on entry. | | 2693 | * zfsvfs, held, and long held on entry. |
2684 | */ | | 2694 | */ |
| | | 2695 | #ifdef __NetBSD__ |
| | | 2696 | static bool |
| | | 2697 | zfs_resume_selector(void *cl, struct vnode *vp) |
| | | 2698 | { |
| | | 2699 | |
| | | 2700 | if (zfsctl_is_node(vp)) |
| | | 2701 | return false; |
| | | 2702 | return (VTOZ(vp)->z_sa_hdl == NULL); |
| | | 2703 | } |
| | | 2704 | #endif |
2685 | int | | 2705 | int |
2686 | zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds) | | 2706 | zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds) |
2687 | { | | 2707 | { |
2688 | int err; | | 2708 | int err; |
2689 | znode_t *zp; | | 2709 | znode_t *zp; |
2690 | | | 2710 | |
2691 | ASSERT(RRM_WRITE_HELD(&zfsvfs->z_teardown_lock)); | | 2711 | ASSERT(RRM_WRITE_HELD(&zfsvfs->z_teardown_lock)); |
2692 | ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock)); | | 2712 | ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock)); |
2693 | | | 2713 | |
2694 | /* | | 2714 | /* |
2695 | * We already own this, so just update the objset_t, as the one we | | 2715 | * We already own this, so just update the objset_t, as the one we |
2696 | * had before may have been evicted. | | 2716 | * had before may have been evicted. |
2697 | */ | | 2717 | */ |
| @@ -2715,26 +2735,38 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_data | | | @@ -2715,26 +2735,38 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_data |
2715 | * when they try to use their znode. | | 2735 | * when they try to use their znode. |
2716 | */ | | 2736 | */ |
2717 | mutex_enter(&zfsvfs->z_znodes_lock); | | 2737 | mutex_enter(&zfsvfs->z_znodes_lock); |
2718 | for (zp = list_head(&zfsvfs->z_all_znodes); zp; | | 2738 | for (zp = list_head(&zfsvfs->z_all_znodes); zp; |
2719 | zp = list_next(&zfsvfs->z_all_znodes, zp)) { | | 2739 | zp = list_next(&zfsvfs->z_all_znodes, zp)) { |
2720 | (void) zfs_rezget(zp); | | 2740 | (void) zfs_rezget(zp); |
2721 | } | | 2741 | } |
2722 | mutex_exit(&zfsvfs->z_znodes_lock); | | 2742 | mutex_exit(&zfsvfs->z_znodes_lock); |
2723 | | | 2743 | |
2724 | bail: | | 2744 | bail: |
2725 | /* release the VOPs */ | | 2745 | /* release the VOPs */ |
2726 | rw_exit(&zfsvfs->z_teardown_inactive_lock); | | 2746 | rw_exit(&zfsvfs->z_teardown_inactive_lock); |
2727 | rrm_exit(&zfsvfs->z_teardown_lock, FTAG); | | 2747 | rrm_exit(&zfsvfs->z_teardown_lock, FTAG); |
| | | 2748 | #ifdef __NetBSD__ |
| | | 2749 | struct vnode_iterator *marker; |
| | | 2750 | vnode_t *vp; |
| | | 2751 | |
| | | 2752 | vfs_vnode_iterator_init(zfsvfs->z_vfs, &marker); |
| | | 2753 | while ((vp = vfs_vnode_iterator_next(marker, |
| | | 2754 | zfs_resume_selector, NULL))) { |
| | | 2755 | vgone(vp); |
| | | 2756 | } |
| | | 2757 | vfs_vnode_iterator_destroy(marker); |
| | | 2758 | vfs_resume(zfsvfs->z_vfs); |
| | | 2759 | #endif |
2728 | | | 2760 | |
2729 | if (err) { | | 2761 | if (err) { |
2730 | /* | | 2762 | /* |
2731 | * Since we couldn't setup the sa framework, try to force | | 2763 | * Since we couldn't setup the sa framework, try to force |
2732 | * unmount this file system. | | 2764 | * unmount this file system. |
2733 | */ | | 2765 | */ |
2734 | if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0) { | | 2766 | if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0) { |
2735 | vfs_ref(zfsvfs->z_vfs); | | 2767 | vfs_ref(zfsvfs->z_vfs); |
2736 | (void) dounmount(zfsvfs->z_vfs, MS_FORCE, curthread); | | 2768 | (void) dounmount(zfsvfs->z_vfs, MS_FORCE, curthread); |
2737 | } | | 2769 | } |
2738 | } | | 2770 | } |
2739 | return (err); | | 2771 | return (err); |
2740 | } | | 2772 | } |