Mon Jun 17 08:09:57 2019 UTC ()
Add native vfs_suspend()/vfs_resume() before and after
zfs_suspend_fs()/zfs_resume_fs() and get rid of dead "z_sa_hdl == NULL"
znodes before vfs_resume() to keep the vnode cache consistent.

Live rollback should work now.

PR port-xen/54273 ("zpool create pool xbd2" panics DOMU kernel)


(hannken)
diff -r1.23 -r1.24 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c

cvs diff -r1.23 -r1.24 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c (expand / switch to unified diff)

--- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c 2019/05/22 08:45:32 1.23
+++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c 2019/06/17 08:09:57 1.24
@@ -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
118VFS_SET(zfs_vfsops, zfs, VFCF_JAIL | VFCF_DELEGADMIN); 118VFS_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
127int zfs_debug_level; 128int zfs_debug_level;
128kmutex_t zfs_debug_mtx; 129kmutex_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
134static int zfs_mount(vfs_t *vfsp, const char *path, void *data, size_t *data_len); 135static int zfs_mount(vfs_t *vfsp, const char *path, void *data, size_t *data_len);
135static int zfs_umount(vfs_t *vfsp, int fflag); 136static int zfs_umount(vfs_t *vfsp, int fflag);
136static int zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp); 137static 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 */
2667int 2668int
2668zfs_suspend_fs(zfsvfs_t *zfsvfs) 2669zfs_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__
 2696static bool
 2697zfs_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
2685int 2705int
2686zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds) 2706zfs_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
2724bail: 2744bail:
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}