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>
This commit is contained in:
Matthew Dillon 1999-09-17 05:17:59 +00:00
parent 4dcc5c2d1d
commit 24579ca1d7

View File

@ -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;