Author: kib
Date: Thu Nov 26 18:16:32 2020
New Revision: 368077
URL: https://svnweb.freebsd.org/changeset/base/368077

Log:
  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

Modified:
  head/sys/fs/nullfs/null_vnops.c

Modified: head/sys/fs/nullfs/null_vnops.c
==============================================================================
--- head/sys/fs/nullfs/null_vnops.c     Thu Nov 26 18:13:33 2020        
(r368076)
+++ head/sys/fs/nullfs/null_vnops.c     Thu Nov 26 18:16:32 2020        
(r368077)
@@ -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,
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to