summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-03-19 14:36:28 +0000
committerkib <kib@FreeBSD.org>2013-03-19 14:36:28 +0000
commita43491886afc49c29869fa2c77138236b60a5a60 (patch)
treee16398d382f1c242dbeae34461c46e1b5b76d179
parent28b18148ad40106959ba13dacb31a3165419d8c6 (diff)
downloadFreeBSD-src-a43491886afc49c29869fa2c77138236b60a5a60.zip
FreeBSD-src-a43491886afc49c29869fa2c77138236b60a5a60.tar.gz
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
-rw-r--r--sys/vm/vnode_pager.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index a0340af..f136d75 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -698,6 +698,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
int runpg;
int runend;
struct buf *bp;
+ struct mount *mp;
int count;
int error;
@@ -903,9 +904,21 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
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, bytecount, reqpage)
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
OpenPOWER on IntegriCloud