diff options
author | kib <kib@FreeBSD.org> | 2013-03-19 14:36:28 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-03-19 14:36:28 +0000 |
commit | a43491886afc49c29869fa2c77138236b60a5a60 (patch) | |
tree | e16398d382f1c242dbeae34461c46e1b5b76d179 /sys/vm/vnode_pager.c | |
parent | 28b18148ad40106959ba13dacb31a3165419d8c6 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/vm/vnode_pager.c')
-rw-r--r-- | sys/vm/vnode_pager.c | 36 |
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 |