git: 3ffcfa599e29 - main - vfs: add vop_stdadd_writecount_nomsync

From: Mateusz Guzik <mjg_at_FreeBSD.org>
Date: Fri, 26 Nov 2021 12:07:11 UTC
The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=3ffcfa599e29686cf2b3c1a6087408c37acaed78

commit 3ffcfa599e29686cf2b3c1a6087408c37acaed78
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2021-11-26 09:02:19 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2021-11-26 12:06:08 +0000

    vfs: add vop_stdadd_writecount_nomsync
    
    This avoids needing to inspect the mount point every time.
    
    Reviewed by:    kib (previous version)
    Differential Revision:  https://reviews.freebsd.org/D33125
---
 .../openzfs/module/os/freebsd/zfs/zfs_ctldir.c     |  3 ++
 .../openzfs/module/os/freebsd/zfs/zfs_vnops_os.c   |  3 ++
 sys/fs/devfs/devfs_vnops.c                         |  2 ++
 sys/fs/pseudofs/pseudofs_vnops.c                   |  1 +
 sys/fs/tmpfs/tmpfs_vnops.c                         |  1 +
 sys/kern/vfs_default.c                             | 40 +++++++++++++++++-----
 sys/sys/vnode.h                                    |  1 +
 7 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c
index 3b405e9d68eb..28d98e788263 100644
--- 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 @@ static struct vop_vector zfsctl_ops_root = {
 	.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 @@ static struct vop_vector zfsctl_ops_snapdir = {
 	.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 @@ static struct vop_vector zfsctl_ops_snapshot = {
 	.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
index 11bbda5452a1..2f7019b92498 100644
--- 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 @@ struct vop_vector zfs_vnodeops = {
 	.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 @@ struct vop_vector zfs_fifoops = {
 	.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 @@ struct vop_vector zfs_shareops = {
 	.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
index 964d288324b4..594dc087aab3 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -2064,6 +2064,7 @@ static struct vop_vector devfs_vnodeops = {
 	.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 @@ static struct vop_vector devfs_specops = {
 	.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
index 29bb1544e7ad..eae4c1c71ab9 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -1167,6 +1167,7 @@ struct vop_vector pfs_vnodeops = {
 	.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
index 3b498bf27a79..a59a522d85ab 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -1868,6 +1868,7 @@ struct vop_vector tmpfs_vnodeop_entries = {
 	.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
index 763e9a943f7d..50829ad3044e 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -1382,24 +1382,34 @@ vop_stdunset_text(struct vop_unset_text_args *ap)
 	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 @@ vop_stdadd_writecount(struct vop_add_writecount_args *ap)
 	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
index 3d04b6f68784..c84d015b011c 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -879,6 +879,7 @@ int	vop_stdvptofh(struct vop_vptofh_args *ap);
 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);