VMIO reads: enable for nullfs upper vnode if the lower vnode supports it.

Reviewed by:	markj
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
Differential revision:	https://reviews.freebsd.org/D25968
This commit is contained in:
Konstantin Belousov 2020-08-16 21:05:56 +00:00
parent fbca789fc3
commit 685cb01a18
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=364288
2 changed files with 31 additions and 1 deletions

View file

@ -258,6 +258,26 @@ null_nodeget(mp, lowervp, vpp)
if (lowervp == MOUNTTONULLMOUNT(mp)->nullm_lowerrootvp)
vp->v_vflag |= VV_ROOT;
/*
* We might miss the case where lower vnode sets VIRF_PGREAD
* some time after construction, which is typical case.
* null_open rechecks.
*/
if ((lowervp->v_irflag & VIRF_PGREAD) != 0) {
MPASS(lowervp->v_object != NULL);
if ((vp->v_irflag & 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);
} else {
MPASS(vp->v_object != NULL);
}
}
/*
* Atomically insert our new node into the hash or vget existing
* if someone else has beaten us to it.
@ -265,6 +285,7 @@ null_nodeget(mp, lowervp, vpp)
*vpp = null_hashins(mp, xp);
if (*vpp != NULL) {
vrele(lowervp);
vp->v_object = NULL; /* in case VIRF_PGREAD set it */
null_destroy_proto(vp, xp);
return (0);
}

View file

@ -439,8 +439,17 @@ null_open(struct vop_open_args *ap)
vp = ap->a_vp;
ldvp = NULLVPTOLOWERVP(vp);
retval = null_bypass(&ap->a_gen);
if (retval == 0)
if (retval == 0) {
vp->v_object = ldvp->v_object;
if ((ldvp->v_irflag & 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);
}
}
}
return (retval);
}