Print this page
5382 pvn_getpages handles lengths <= PAGESIZE just fine


  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  *      Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
  28  *      All rights reserved.
  29  */
  30 
  31 /*
  32  * Copyright (c) 2013, Joyent, Inc. All rights reserved.

  33  */
  34 
  35 #include <sys/param.h>
  36 #include <sys/types.h>
  37 #include <sys/systm.h>
  38 #include <sys/cred.h>
  39 #include <sys/time.h>
  40 #include <sys/vnode.h>
  41 #include <sys/vfs.h>
  42 #include <sys/vfs_opreg.h>
  43 #include <sys/file.h>
  44 #include <sys/filio.h>
  45 #include <sys/uio.h>
  46 #include <sys/buf.h>
  47 #include <sys/mman.h>
  48 #include <sys/pathname.h>
  49 #include <sys/dirent.h>
  50 #include <sys/debug.h>
  51 #include <sys/vmsystm.h>
  52 #include <sys/fcntl.h>


4568          */
4569         if (rw == S_CREATE) {
4570                 while ((mi->mi_max_threads != 0 &&
4571                     rp->r_awcount > 2 * mi->mi_max_threads) ||
4572                     rp->r_gcount > 0)
4573                         cv_wait(&rp->r_cv, &rp->r_statelock);
4574         }
4575 
4576         /*
4577          * If we are getting called as a side effect of an nfs_write()
4578          * operation the local file size might not be extended yet.
4579          * In this case we want to be able to return pages of zeroes.
4580          */
4581         if (off + len > rp->r_size + PAGEOFFSET && seg != segkmap) {
4582                 mutex_exit(&rp->r_statelock);
4583                 return (EFAULT);                /* beyond EOF */
4584         }
4585 
4586         mutex_exit(&rp->r_statelock);
4587 
4588         if (len <= PAGESIZE) {
4589                 error = nfs3_getapage(vp, off, len, protp, pl, plsz,
4590                     seg, addr, rw, cr);
4591         } else {
4592                 error = pvn_getpages(nfs3_getapage, vp, off, len, protp,
4593                     pl, plsz, seg, addr, rw, cr);
4594         }
4595 
4596         switch (error) {
4597         case NFS_EOF:
4598                 nfs_purge_caches(vp, NFS_NOPURGE_DNLC, cr);
4599                 goto retry;
4600         case ESTALE:
4601                 PURGE_STALE_FH(error, vp, cr);
4602         }
4603 
4604         return (error);
4605 }
4606 
4607 /*
4608  * Called from pvn_getpages or nfs3_getpage to get a particular page.
4609  */
4610 /* ARGSUSED */
4611 static int
4612 nfs3_getapage(vnode_t *vp, u_offset_t off, size_t len, uint_t *protp,
4613         page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
4614         enum seg_rw rw, cred_t *cr)
4615 {
4616         rnode_t *rp;
4617         uint_t bsize;
4618         struct buf *bp;
4619         page_t *pp;
4620         u_offset_t lbn;
4621         u_offset_t io_off;
4622         u_offset_t blkoff;
4623         u_offset_t rablkoff;
4624         size_t io_len;
4625         uint_t blksize;
4626         int error;
4627         int readahead;
4628         int readahead_issued = 0;




  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  *      Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
  28  *      All rights reserved.
  29  */
  30 
  31 /*
  32  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  33  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  34  */
  35 
  36 #include <sys/param.h>
  37 #include <sys/types.h>
  38 #include <sys/systm.h>
  39 #include <sys/cred.h>
  40 #include <sys/time.h>
  41 #include <sys/vnode.h>
  42 #include <sys/vfs.h>
  43 #include <sys/vfs_opreg.h>
  44 #include <sys/file.h>
  45 #include <sys/filio.h>
  46 #include <sys/uio.h>
  47 #include <sys/buf.h>
  48 #include <sys/mman.h>
  49 #include <sys/pathname.h>
  50 #include <sys/dirent.h>
  51 #include <sys/debug.h>
  52 #include <sys/vmsystm.h>
  53 #include <sys/fcntl.h>


4569          */
4570         if (rw == S_CREATE) {
4571                 while ((mi->mi_max_threads != 0 &&
4572                     rp->r_awcount > 2 * mi->mi_max_threads) ||
4573                     rp->r_gcount > 0)
4574                         cv_wait(&rp->r_cv, &rp->r_statelock);
4575         }
4576 
4577         /*
4578          * If we are getting called as a side effect of an nfs_write()
4579          * operation the local file size might not be extended yet.
4580          * In this case we want to be able to return pages of zeroes.
4581          */
4582         if (off + len > rp->r_size + PAGEOFFSET && seg != segkmap) {
4583                 mutex_exit(&rp->r_statelock);
4584                 return (EFAULT);                /* beyond EOF */
4585         }
4586 
4587         mutex_exit(&rp->r_statelock);
4588 




4589         error = pvn_getpages(nfs3_getapage, vp, off, len, protp,
4590             pl, plsz, seg, addr, rw, cr);

4591 
4592         switch (error) {
4593         case NFS_EOF:
4594                 nfs_purge_caches(vp, NFS_NOPURGE_DNLC, cr);
4595                 goto retry;
4596         case ESTALE:
4597                 PURGE_STALE_FH(error, vp, cr);
4598         }
4599 
4600         return (error);
4601 }
4602 
4603 /*
4604  * Called from pvn_getpages to get a particular page.
4605  */
4606 /* ARGSUSED */
4607 static int
4608 nfs3_getapage(vnode_t *vp, u_offset_t off, size_t len, uint_t *protp,
4609         page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
4610         enum seg_rw rw, cred_t *cr)
4611 {
4612         rnode_t *rp;
4613         uint_t bsize;
4614         struct buf *bp;
4615         page_t *pp;
4616         u_offset_t lbn;
4617         u_offset_t io_off;
4618         u_offset_t blkoff;
4619         u_offset_t rablkoff;
4620         size_t io_len;
4621         uint_t blksize;
4622         int error;
4623         int readahead;
4624         int readahead_issued = 0;