diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c @@ -815,6 +815,7 @@ .vop_vptocnp = zfsctl_root_vptocnp, .vop_pathconf = zfsctl_common_pathconf, .vop_getacl = zfsctl_common_getacl, + .vop_add_writecount = vop_stdadd_writecount_nomsync, }; VFS_VOP_VECTOR_REGISTER(zfsctl_ops_root); @@ -1134,6 +1135,7 @@ .vop_print = zfsctl_common_print, .vop_pathconf = zfsctl_common_pathconf, .vop_getacl = zfsctl_common_getacl, + .vop_add_writecount = vop_stdadd_writecount_nomsync, }; VFS_VOP_VECTOR_REGISTER(zfsctl_ops_snapdir); @@ -1238,6 +1240,7 @@ .vop_islocked = vop_stdislocked, .vop_advlockpurge = vop_stdadvlockpurge, /* called by vgone */ .vop_print = zfsctl_common_print, + .vop_add_writecount = vop_stdadd_writecount_nomsync, }; VFS_VOP_VECTOR_REGISTER(zfsctl_ops_snapshot); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c @@ -6172,6 +6172,7 @@ .vop_unlock = vop_unlock, .vop_islocked = vop_islocked, #endif + .vop_add_writecount = vop_stdadd_writecount_nomsync, }; VFS_VOP_VECTOR_REGISTER(zfs_vnodeops); @@ -6196,6 +6197,7 @@ .vop_getacl = zfs_freebsd_getacl, .vop_setacl = zfs_freebsd_setacl, .vop_aclcheck = zfs_freebsd_aclcheck, + .vop_add_writecount = vop_stdadd_writecount_nomsync, }; VFS_VOP_VECTOR_REGISTER(zfs_fifoops); @@ -6215,5 +6217,6 @@ .vop_reclaim = zfs_freebsd_reclaim, .vop_fid = zfs_freebsd_fid, .vop_pathconf = zfs_freebsd_pathconf, + .vop_add_writecount = vop_stdadd_writecount_nomsync, }; VFS_VOP_VECTOR_REGISTER(zfs_shareops); diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -2064,6 +2064,7 @@ .vop_lock1 = vop_lock, .vop_unlock = vop_unlock, .vop_islocked = vop_islocked, + .vop_add_writecount = vop_stdadd_writecount_nomsync, }; VFS_VOP_VECTOR_REGISTER(devfs_vnodeops); @@ -2105,6 +2106,7 @@ .vop_lock1 = vop_lock, .vop_unlock = vop_unlock, .vop_islocked = vop_islocked, + .vop_add_writecount = vop_stdadd_writecount_nomsync, }; VFS_VOP_VECTOR_REGISTER(devfs_specops); diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c --- a/sys/fs/pseudofs/pseudofs_vnops.c +++ b/sys/fs/pseudofs/pseudofs_vnops.c @@ -1167,6 +1167,7 @@ .vop_symlink = VOP_EOPNOTSUPP, .vop_vptocnp = pfs_vptocnp, .vop_write = pfs_write, + .vop_add_writecount = vop_stdadd_writecount_nomsync, /* XXX I've probably forgotten a few that need VOP_EOPNOTSUPP */ }; VFS_VOP_VECTOR_REGISTER(pfs_vnodeops); diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -1868,6 +1868,7 @@ .vop_lock1 = vop_lock, .vop_unlock = vop_unlock, .vop_islocked = vop_islocked, + .vop_add_writecount = vop_stdadd_writecount_nomsync, }; VFS_VOP_VECTOR_REGISTER(tmpfs_vnodeop_entries); diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -1382,24 +1382,34 @@ return (error); } -static int -vop_stdadd_writecount(struct vop_add_writecount_args *ap) +static int __always_inline +vop_stdadd_writecount_impl(struct vop_add_writecount_args *ap, bool handle_msync) { struct vnode *vp; - struct mount *mp; + struct mount *mp __diagused; int error; vp = ap->a_vp; + +#ifdef INVARIANTS + mp = vp->v_mount; + if (mp != NULL) { + if (handle_msync) { + VNPASS((mp->mnt_kern_flag & MNTK_NOMSYNC) == 0, vp); + } else { + VNPASS((mp->mnt_kern_flag & MNTK_NOMSYNC) != 0, vp); + } + } +#endif + VI_LOCK_FLAGS(vp, MTX_DUPOK); - if (vp->v_writecount < 0) { + if (__predict_false(vp->v_writecount < 0)) { error = ETXTBSY; } else { VNASSERT(vp->v_writecount + ap->a_inc >= 0, vp, ("neg writecount increment %d", ap->a_inc)); - if (vp->v_writecount == 0) { - mp = vp->v_mount; - if (mp != NULL && (mp->mnt_kern_flag & MNTK_NOMSYNC) == 0) - vlazy(vp); + if (handle_msync && vp->v_writecount == 0) { + vlazy(vp); } vp->v_writecount += ap->a_inc; error = 0; @@ -1408,6 +1418,20 @@ return (error); } +int +vop_stdadd_writecount(struct vop_add_writecount_args *ap) +{ + + return (vop_stdadd_writecount_impl(ap, true)); +} + +int +vop_stdadd_writecount_nomsync(struct vop_add_writecount_args *ap) +{ + + return (vop_stdadd_writecount_impl(ap, false)); +} + int vop_stdneed_inactive(struct vop_need_inactive_args *ap) { diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -879,6 +879,7 @@ int vop_stdunp_bind(struct vop_unp_bind_args *ap); int vop_stdunp_connect(struct vop_unp_connect_args *ap); int vop_stdunp_detach(struct vop_unp_detach_args *ap); +int vop_stdadd_writecount_nomsync(struct vop_add_writecount_args *ap); int vop_eopnotsupp(struct vop_generic_args *ap); int vop_ebadf(struct vop_generic_args *ap); int vop_einval(struct vop_generic_args *ap);