summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>1999-09-17 05:17:59 +0000
committerdillon <dillon@FreeBSD.org>1999-09-17 05:17:59 +0000
commit124cdf53462edef3fd859a8d3c9d6bf6be840e98 (patch)
treea918b30bd92a3bd11cf65a89d2beb954d8720724
parent7a0052d268ee8736620e4c44ba2fd3149196391d (diff)
downloadFreeBSD-src-124cdf53462edef3fd859a8d3c9d6bf6be840e98.zip
FreeBSD-src-124cdf53462edef3fd859a8d3c9d6bf6be840e98.tar.gz
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>
-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 367d3a3..cc7cd4b 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;
OpenPOWER on IntegriCloud