Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Jan 2021 06:53:12 GMT
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 3e506a67bbcc - main - vfs: add v_irflag accessors
Message-ID:  <202101030653.1036rCVt023118@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mjg:

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

commit 3e506a67bbcc76aada3c3fa4e499502184272c07
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2020-12-28 03:01:15 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2021-01-03 06:50:06 +0000

    vfs: add v_irflag accessors
    
    Reviewed by:    kib (previous version)
    Differential Revision:  https://reviews.freebsd.org/D27793
---
 sys/fs/nullfs/null_subr.c  |  8 ++---
 sys/fs/nullfs/null_vnops.c |  8 ++---
 sys/fs/tmpfs/tmpfs_subr.c  |  2 +-
 sys/fs/tmpfs/tmpfs_vnops.c |  2 +-
 sys/kern/vfs_subr.c        | 77 ++++++++++++++++++++++++++++++++++++++++++----
 sys/kern/vfs_vnops.c       |  2 +-
 sys/sys/vnode.h            | 10 +++++-
 sys/ufs/ufs/ufs_vnops.c    |  8 ++---
 8 files changed, 92 insertions(+), 25 deletions(-)

diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c
index 80f6943ac7c3..fb6a13449df7 100644
--- a/sys/fs/nullfs/null_subr.c
+++ b/sys/fs/nullfs/null_subr.c
@@ -263,16 +263,14 @@ null_nodeget(mp, lowervp, vpp)
 	 * some time after construction, which is typical case.
 	 * null_open rechecks.
 	 */
-	if ((lowervp->v_irflag & VIRF_PGREAD) != 0) {
+	if ((vn_irflag_read(lowervp) & VIRF_PGREAD) != 0) {
 		MPASS(lowervp->v_object != NULL);
-		if ((vp->v_irflag & VIRF_PGREAD) == 0) {
+		if ((vn_irflag_read(vp) & VIRF_PGREAD) == 0) {
 			if (vp->v_object == NULL)
 				vp->v_object = lowervp->v_object;
 			else
 				MPASS(vp->v_object == lowervp->v_object);
-			VI_LOCK(vp);
-			vp->v_irflag |= VIRF_PGREAD;
-			VI_UNLOCK(vp);
+			vn_irflag_set_cond(vp, VIRF_PGREAD);
 		} else {
 			MPASS(vp->v_object != NULL);
 		}
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index b79bbb96e371..1de0cdfca9ac 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -458,12 +458,10 @@ null_open(struct vop_open_args *ap)
 	retval = null_bypass(&ap->a_gen);
 	if (retval == 0) {
 		vp->v_object = ldvp->v_object;
-		if ((ldvp->v_irflag & VIRF_PGREAD) != 0) {
+		if ((vn_irflag_read(ldvp) & VIRF_PGREAD) != 0) {
 			MPASS(vp->v_object != NULL);
-			if ((vp->v_irflag & VIRF_PGREAD) == 0) {
-				VI_LOCK(vp);
-				vp->v_irflag |= VIRF_PGREAD;
-				VI_UNLOCK(vp);
+			if ((vn_irflag_read(vp) & VIRF_PGREAD) == 0) {
+				vn_irflag_set_cond(vp, VIRF_PGREAD);
 			}
 		}
 	}
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index e285f8d57989..156211e35186 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -698,7 +698,7 @@ loop:
 		vp->v_object = object;
 		object->un_pager.swp.swp_tmpfs = vp;
 		vm_object_set_flag(object, OBJ_TMPFS);
-		vp->v_irflag |= VIRF_PGREAD;
+		vn_irflag_set_locked(vp, VIRF_PGREAD);
 		VI_UNLOCK(vp);
 		VM_OBJECT_WUNLOCK(object);
 		break;
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
index 6782d71d9207..3c80c33ea047 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -600,7 +600,7 @@ tmpfs_read_pgcache(struct vop_read_pgcache_args *v)
 	int error;
 
 	vp = v->a_vp;
-	VNPASS((vp->v_irflag & VIRF_PGREAD) != 0, vp);
+	VNPASS((vn_irflag_read(vp) & VIRF_PGREAD) != 0, vp);
 
 	if (v->a_uio->uio_offset < 0)
 		return (EINVAL);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 0f9fb5fe263c..8896b542a499 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1717,6 +1717,7 @@ getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops,
 	KASSERT(vp->v_pollinfo == NULL, ("stale v_pollinfo %p", vp));
 	vp->v_type = VNON;
 	vp->v_op = vops;
+	vp->v_irflag = 0;
 	v_init_counters(vp);
 	vp->v_bufobj.bo_ops = &buf_ops_bio;
 #ifdef DIAGNOSTIC
@@ -1821,7 +1822,6 @@ freevnode(struct vnode *vp)
 	vp->v_rdev = NULL;
 	vp->v_fifoinfo = NULL;
 	vp->v_lasta = vp->v_clen = vp->v_cstart = vp->v_lastw = 0;
-	vp->v_irflag = 0;
 	vp->v_iflag = 0;
 	vp->v_vflag = 0;
 	bo->bo_flag = 0;
@@ -3868,14 +3868,14 @@ vgonel(struct vnode *vp)
 	/*
 	 * Don't vgonel if we're already doomed.
 	 */
-	if (vp->v_irflag & VIRF_DOOMED)
+	if (VN_IS_DOOMED(vp))
 		return;
 	/*
 	 * Paired with freevnode.
 	 */
 	vn_seqc_write_begin_locked(vp);
 	vunlazy_gone(vp);
-	vp->v_irflag |= VIRF_DOOMED;
+	vn_irflag_set_locked(vp, VIRF_DOOMED);
 
 	/*
 	 * Check to see if the vnode is in use.  If so, we have to
@@ -4001,6 +4001,7 @@ vn_printf(struct vnode *vp, const char *fmt, ...)
 	char buf[256], buf2[16];
 	u_long flags;
 	u_int holdcnt;
+	short irflag;
 
 	va_start(ap, fmt);
 	vprintf(fmt, ap);
@@ -4036,11 +4037,12 @@ vn_printf(struct vnode *vp, const char *fmt, ...)
 
 	buf[0] = '\0';
 	buf[1] = '\0';
-	if (vp->v_irflag & VIRF_DOOMED)
+	irflag = vn_irflag_read(vp);
+	if (irflag & VIRF_DOOMED)
 		strlcat(buf, "|VIRF_DOOMED", sizeof(buf));
-	if (vp->v_irflag & VIRF_PGREAD)
+	if (irflag & VIRF_PGREAD)
 		strlcat(buf, "|VIRF_PGREAD", sizeof(buf));
-	flags = vp->v_irflag & ~(VIRF_DOOMED | VIRF_PGREAD);
+	flags = irflag & ~(VIRF_DOOMED | VIRF_PGREAD);
 	if (flags != 0) {
 		snprintf(buf2, sizeof(buf2), "|VIRF(0x%lx)", flags);
 		strlcat(buf, buf2, sizeof(buf));
@@ -6794,3 +6796,66 @@ vn_seqc_write_end(struct vnode *vp)
 	vn_seqc_write_end_locked(vp);
 	VI_UNLOCK(vp);
 }
+
+void
+vn_irflag_set_locked(struct vnode *vp, short toset)
+{
+	short flags;
+
+	ASSERT_VI_LOCKED(vp, __func__);
+	flags = vn_irflag_read(vp);
+	VNASSERT((flags & toset) == 0, vp,
+	    ("%s: some of the passed flags already set (have %d, passed %d)\n",
+	    __func__, flags, toset));
+	atomic_store_short(&vp->v_irflag, flags | toset);
+}
+
+void
+vn_irflag_set(struct vnode *vp, short toset)
+{
+
+	VI_LOCK(vp);
+	vn_irflag_set_locked(vp, toset);
+	VI_UNLOCK(vp);
+}
+
+void
+vn_irflag_set_cond_locked(struct vnode *vp, short toset)
+{
+	short flags;
+
+	ASSERT_VI_LOCKED(vp, __func__);
+	flags = vn_irflag_read(vp);
+	atomic_store_short(&vp->v_irflag, flags | toset);
+}
+
+void
+vn_irflag_set_cond(struct vnode *vp, short toset)
+{
+
+	VI_LOCK(vp);
+	vn_irflag_set_cond_locked(vp, toset);
+	VI_UNLOCK(vp);
+}
+
+void
+vn_irflag_unset_locked(struct vnode *vp, short tounset)
+{
+	short flags;
+
+	ASSERT_VI_LOCKED(vp, __func__);
+	flags = vn_irflag_read(vp);
+	VNASSERT((flags & tounset) == tounset, vp,
+	    ("%s: some of the passed flags not set (have %d, passed %d)\n",
+	    __func__, flags, tounset));
+	atomic_store_short(&vp->v_irflag, flags & ~tounset);
+}
+
+void
+vn_irflag_unset(struct vnode *vp, short tounset)
+{
+
+	VI_LOCK(vp);
+	vn_irflag_unset_locked(vp, tounset);
+	VI_UNLOCK(vp);
+}
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 832ff9ac34a5..f69115047eba 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -991,7 +991,7 @@ vn_read(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags,
 	 * allows us to avoid unneeded work outright.
 	 */
 	if (vn_io_pgcache_read_enable && !mac_vnode_check_read_enabled() &&
-	    (vp->v_irflag & (VIRF_DOOMED | VIRF_PGREAD)) == VIRF_PGREAD) {
+	    (vn_irflag_read(vp) & (VIRF_DOOMED | VIRF_PGREAD)) == VIRF_PGREAD) {
 		error = VOP_READ_PGCACHE(vp, uio, ioflag, fp->f_cred);
 		if (error == 0) {
 			fp->f_nextoff[UIO_READ] = uio->uio_offset;
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index f77c5bc4827a..107cf45f9602 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -797,6 +797,14 @@ void	vn_seqc_write_end(struct vnode *vp);
 #define	vn_rangelock_trywlock(vp, start, end)				\
 	rangelock_trywlock(&(vp)->v_rl, (start), (end), VI_MTX(vp))
 
+#define	vn_irflag_read(vp)	atomic_load_short(&(vp)->v_irflag)
+void	vn_irflag_set_locked(struct vnode *vp, short toset);
+void	vn_irflag_set(struct vnode *vp, short toset);
+void	vn_irflag_set_cond_locked(struct vnode *vp, short toset);
+void	vn_irflag_set_cond(struct vnode *vp, short toset);
+void	vn_irflag_unset_locked(struct vnode *vp, short tounset);
+void	vn_irflag_unset(struct vnode *vp, short tounset);
+
 int	vfs_cache_lookup(struct vop_lookup_args *ap);
 int	vfs_cache_root(struct mount *mp, int flags, struct vnode **vpp);
 void	vfs_timestamp(struct timespec *);
@@ -979,7 +987,7 @@ do {									\
 #define	VOP_UNSET_TEXT_CHECKED(vp)		VOP_UNSET_TEXT((vp))
 #endif
 
-#define	VN_IS_DOOMED(vp)	__predict_false((vp)->v_irflag & VIRF_DOOMED)
+#define	VN_IS_DOOMED(vp)	__predict_false((vn_irflag_read(vp) & VIRF_DOOMED) != 0)
 
 void	vput(struct vnode *vp);
 void	vrele(struct vnode *vp);
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 3280e29f43a1..a3f790e16685 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -283,10 +283,8 @@ ufs_open(struct vop_open_args *ap)
 
 	ip = VTOI(vp);
 	vnode_create_vobject(vp, DIP(ip, i_size), ap->a_td);
-	if (vp->v_type == VREG && (vp->v_irflag & VIRF_PGREAD) == 0) {
-		VI_LOCK(vp);
-		vp->v_irflag |= VIRF_PGREAD;
-		VI_UNLOCK(vp);
+	if (vp->v_type == VREG && (vn_irflag_read(vp) & VIRF_PGREAD) == 0) {
+		vn_irflag_set_cond(vp, VIRF_PGREAD);
 	}
 
 	/*
@@ -2947,7 +2945,7 @@ ufs_read_pgcache(struct vop_read_pgcache_args *ap)
 
 	uio = ap->a_uio;
 	vp = ap->a_vp;
-	VNPASS((vp->v_irflag & VIRF_PGREAD) != 0, vp);
+	VNPASS((vn_irflag_read(vp) & VIRF_PGREAD) != 0, vp);
 
 	if (uio->uio_resid > ptoa(io_hold_cnt) || uio->uio_offset < 0 ||
 	    (ap->a_ioflag & IO_DIRECT) != 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101030653.1036rCVt023118>