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


   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  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 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright (c) 2012, Joyent, Inc. All rights reserved.

  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/param.h>
  33 #include <sys/t_lock.h>
  34 #include <sys/systm.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/user.h>
  37 #include <sys/time.h>
  38 #include <sys/vfs.h>
  39 #include <sys/vfs_opreg.h>
  40 #include <sys/vnode.h>
  41 #include <sys/file.h>
  42 #include <sys/fcntl.h>
  43 #include <sys/flock.h>
  44 #include <sys/kmem.h>
  45 #include <sys/uio.h>
  46 #include <sys/errno.h>
  47 #include <sys/stat.h>
  48 #include <sys/cred.h>


1792                         rw_enter(&tp->tn_contents, RW_WRITER);
1793                         /* Size may have changed when lock was dropped */
1794                         if (off + len  > tp->tn_size + PAGEOFFSET) {
1795                                 err = EFAULT;
1796                                 goto out;
1797                         }
1798                 }
1799                 for (toff = (anoff_t)off; toff < (anoff_t)off + len;
1800                     toff += PAGESIZE) {
1801                         if (anon_get_ptr(tp->tn_anon, btop(toff)) == NULL) {
1802                                 /* XXX - may allocate mem w. write lock held */
1803                                 (void) anon_set_ptr(tp->tn_anon, btop(toff),
1804                                     anon_alloc(vp, toff), ANON_SLEEP);
1805                                 tp->tn_nblocks++;
1806                         }
1807                 }
1808                 rw_downgrade(&tp->tn_contents);
1809         }
1810 
1811 
1812         if (len <= PAGESIZE)
1813                 err = tmp_getapage(vp, (u_offset_t)off, len, protp, pl, plsz,
1814                     seg, addr, rw, cr);
1815         else
1816                 err = pvn_getpages(tmp_getapage, vp, (u_offset_t)off, len,
1817                     protp, pl, plsz, seg, addr, rw, cr);
1818 
1819         gethrestime(&now);
1820         tp->tn_atime = now;
1821         if (rw == S_WRITE)
1822                 tp->tn_mtime = now;
1823 
1824 out:
1825         rw_exit(&tp->tn_contents);
1826         return (err);
1827 }
1828 
1829 /*
1830  * Called from pvn_getpages or swap_getpage to get a particular page.
1831  */
1832 /*ARGSUSED*/
1833 static int
1834 tmp_getapage(
1835         struct vnode *vp,
1836         u_offset_t off,
1837         size_t len,
1838         uint_t *protp,
1839         page_t *pl[],
1840         size_t plsz,
1841         struct seg *seg,
1842         caddr_t addr,
1843         enum seg_rw rw,
1844         struct cred *cr)
1845 {
1846         struct page *pp;
1847         int flags;
1848         int err = 0;
1849         struct vnode *pvp;
1850         u_offset_t poff;




   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  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 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  29  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/param.h>
  34 #include <sys/t_lock.h>
  35 #include <sys/systm.h>
  36 #include <sys/sysmacros.h>
  37 #include <sys/user.h>
  38 #include <sys/time.h>
  39 #include <sys/vfs.h>
  40 #include <sys/vfs_opreg.h>
  41 #include <sys/vnode.h>
  42 #include <sys/file.h>
  43 #include <sys/fcntl.h>
  44 #include <sys/flock.h>
  45 #include <sys/kmem.h>
  46 #include <sys/uio.h>
  47 #include <sys/errno.h>
  48 #include <sys/stat.h>
  49 #include <sys/cred.h>


1793                         rw_enter(&tp->tn_contents, RW_WRITER);
1794                         /* Size may have changed when lock was dropped */
1795                         if (off + len  > tp->tn_size + PAGEOFFSET) {
1796                                 err = EFAULT;
1797                                 goto out;
1798                         }
1799                 }
1800                 for (toff = (anoff_t)off; toff < (anoff_t)off + len;
1801                     toff += PAGESIZE) {
1802                         if (anon_get_ptr(tp->tn_anon, btop(toff)) == NULL) {
1803                                 /* XXX - may allocate mem w. write lock held */
1804                                 (void) anon_set_ptr(tp->tn_anon, btop(toff),
1805                                     anon_alloc(vp, toff), ANON_SLEEP);
1806                                 tp->tn_nblocks++;
1807                         }
1808                 }
1809                 rw_downgrade(&tp->tn_contents);
1810         }
1811 
1812 
1813         err = pvn_getpages(tmp_getapage, vp, (u_offset_t)off, len, protp,
1814             pl, plsz, seg, addr, rw, cr);




1815 
1816         gethrestime(&now);
1817         tp->tn_atime = now;
1818         if (rw == S_WRITE)
1819                 tp->tn_mtime = now;
1820 
1821 out:
1822         rw_exit(&tp->tn_contents);
1823         return (err);
1824 }
1825 
1826 /*
1827  * Called from pvn_getpages to get a particular page.
1828  */
1829 /*ARGSUSED*/
1830 static int
1831 tmp_getapage(
1832         struct vnode *vp,
1833         u_offset_t off,
1834         size_t len,
1835         uint_t *protp,
1836         page_t *pl[],
1837         size_t plsz,
1838         struct seg *seg,
1839         caddr_t addr,
1840         enum seg_rw rw,
1841         struct cred *cr)
1842 {
1843         struct page *pp;
1844         int flags;
1845         int err = 0;
1846         struct vnode *pvp;
1847         u_offset_t poff;