svn commit: r248512 - head/sys/vm

Konstantin Belousov kib at FreeBSD.org
Tue Mar 19 14:36:29 UTC 2013


Author: kib
Date: Tue Mar 19 14:36:28 2013
New Revision: 248512
URL: http://svnweb.freebsd.org/changeset/base/248512

Log:
  Pass unmapped buffers for page in requests if the filesystem indicated support
  for the unmapped i/o.
  
  Sponsored by:	The FreeBSD Foundation
  Tested by:	pho

Modified:
  head/sys/vm/vnode_pager.c

Modified: head/sys/vm/vnode_pager.c
==============================================================================
--- head/sys/vm/vnode_pager.c	Tue Mar 19 14:33:01 2013	(r248511)
+++ head/sys/vm/vnode_pager.c	Tue Mar 19 14:36:28 2013	(r248512)
@@ -698,6 +698,7 @@ vnode_pager_generic_getpages(vp, m, byte
 	int runpg;
 	int runend;
 	struct buf *bp;
+	struct mount *mp;
 	int count;
 	int error;
 
@@ -903,9 +904,21 @@ vnode_pager_generic_getpages(vp, m, byte
 	kva = (vm_offset_t)bp->b_data;
 
 	/*
-	 * and map the pages to be read into the kva
+	 * and map the pages to be read into the kva, if the filesystem
+	 * requires mapped buffers.
 	 */
-	pmap_qenter(kva, m, count);
+	mp = vp->v_mount;
+	if (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMAPPED_BUFS) != 0 &&
+	    unmapped_buf_allowed) {
+		bp->b_data = unmapped_buf;
+		bp->b_kvabase = unmapped_buf;
+		bp->b_offset = 0;
+		bp->b_flags |= B_UNMAPPED;
+		bp->b_npages = count;
+		for (i = 0; i < count; i++)
+			bp->b_pages[i] = m[i];
+	} else
+		pmap_qenter(kva, m, count);
 
 	/* build a minimal buffer header */
 	bp->b_iocmd = BIO_READ;
@@ -934,11 +947,22 @@ vnode_pager_generic_getpages(vp, m, byte
 	if ((bp->b_ioflags & BIO_ERROR) != 0)
 		error = EIO;
 
-	if (!error) {
-		if (size != count * PAGE_SIZE)
-			bzero((caddr_t) kva + size, PAGE_SIZE * count - size);
+	if (error != 0 && size != count * PAGE_SIZE) {
+		if ((bp->b_flags & B_UNMAPPED) != 0) {
+			bp->b_flags &= ~B_UNMAPPED;
+			pmap_qenter(kva, m, count);
+		}
+		bzero((caddr_t)kva + size, PAGE_SIZE * count - size);
+	}
+	if ((bp->b_flags & B_UNMAPPED) == 0)
+		pmap_qremove(kva, count);
+	if (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMAPPED_BUFS) != 0) {
+		bp->b_data = (caddr_t)kva;
+		bp->b_kvabase = (caddr_t)kva;
+		bp->b_flags &= ~B_UNMAPPED;
+		for (i = 0; i < count; i++)
+			bp->b_pages[i] = NULL;
 	}
-	pmap_qremove(kva, count);
 
 	/*
 	 * free the buffer header back to the swap buffer pool


More information about the svn-src-all mailing list