nullfs: provide custom bypass for VOP_READ_PGCACHE().
Normal bypass expects locked vnode, which is not true for VOP_READ_PGCACHE(). Ensure liveness of the lower vnode by taking the upper vnode interlock, which is also taked by null_reclaim() when setting v_data to NULL. Reported and tested by: pho Reviewed by: markj, mjg Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D27327
This commit is contained in:
parent
1cede83674
commit
3d3de5ce17
@ -947,6 +947,28 @@ null_vptocnp(struct vop_vptocnp_args *ap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
null_read_pgcache(struct vop_read_pgcache_args *ap)
|
||||
{
|
||||
struct vnode *lvp, *vp;
|
||||
struct null_node *xp;
|
||||
int error;
|
||||
|
||||
vp = ap->a_vp;
|
||||
VI_LOCK(vp);
|
||||
xp = VTONULL(vp);
|
||||
if (xp == NULL) {
|
||||
VI_UNLOCK(vp);
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
lvp = xp->null_lowervp;
|
||||
vref(lvp);
|
||||
VI_UNLOCK(vp);
|
||||
error = VOP_READ_PGCACHE(lvp, ap->a_uio, ap->a_ioflag, ap->a_cred);
|
||||
vrele(lvp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Global vfs data structures
|
||||
*/
|
||||
@ -966,6 +988,7 @@ struct vop_vector null_vnodeops = {
|
||||
.vop_lookup = null_lookup,
|
||||
.vop_open = null_open,
|
||||
.vop_print = null_print,
|
||||
.vop_read_pgcache = null_read_pgcache,
|
||||
.vop_reclaim = null_reclaim,
|
||||
.vop_remove = null_remove,
|
||||
.vop_rename = null_rename,
|
||||
|
Loading…
Reference in New Issue
Block a user