aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMatthew Dillon <dillon@FreeBSD.org>1999-09-17 05:17:59 +0000
committerMatthew Dillon <dillon@FreeBSD.org>1999-09-17 05:17:59 +0000
commit24579ca1d7a4ffaa220af5bd7593aa759e1d9c38 (patch)
tree04e96ec9a43de92c3bcf105738e09ef09accc346 /sys
parent4dcc5c2d1d86e7fc50d32458979049a3def253e4 (diff)
downloadsrc-24579ca1d7a4ffaa220af5bd7593aa759e1d9c38.tar.gz
src-24579ca1d7a4ffaa220af5bd7593aa759e1d9c38.zip
The vnode pager (used when you do file-backed mmaps) must use the
underlying physical sector size when aligning I/O transfer sizes. It cannot assume 512 bytes. We assume the underlying sector size is a power of 2. If it isn't, mmap() will break badly anyway (in the same way mmap broke with NFS when NFS tried to cache piecemeal write ranges in buffers, before we enforced read-buffer-before-write-piecemeal for NFS). Reviewed by: Alan Cox <alc@cs.rice.edu>, David Greenman <dg@root.com>
Notes
Notes: svn path=/head/; revision=51340
Diffstat (limited to 'sys')
-rw-r--r--sys/vm/vnode_pager.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index 367d3a39f398..cc7cd4bec794 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -58,6 +58,7 @@
#include <sys/mount.h>
#include <sys/buf.h>
#include <sys/vmmeter.h>
+#include <sys/conf.h>
#include <vm/vm.h>
#include <vm/vm_prot.h>
@@ -196,6 +197,10 @@ vnode_pager_haspage(object, pindex, before, after)
int bsize;
int pagesperblock, blocksperpage;
+ /*
+ * If no vp or vp is doomed or marked transparent to VM, we do not
+ * have the page.
+ */
if ((vp == NULL) || (vp->v_flag & VDOOMED))
return FALSE;
@@ -708,10 +713,13 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
size = object->un_pager.vnp.vnp_size - foff;
/*
- * round up physical size for real devices
+ * round up physical size for real devices.
*/
- if (dp->v_type == VBLK || dp->v_type == VCHR)
- size = (size + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
+ if (dp->v_type == VBLK || dp->v_type == VCHR) {
+ int secmask = dp->v_rdev->si_bsize_phys - 1;
+ KASSERT(secmask < PAGE_SIZE, ("vnode_pager_generic_getpages: sector size %d too large\n", secmask + 1));
+ size = (size + secmask) & ~secmask;
+ }
bp = getpbuf(&vnode_pbuf_freecnt);
kva = (vm_offset_t) bp->b_data;