diff options
author | dyson <dyson@FreeBSD.org> | 1996-06-26 05:52:15 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1996-06-26 05:52:15 +0000 |
commit | e2f426dc1b0fb18a48ef0de15a04f0588e32f27e (patch) | |
tree | 58040758fb53585e2e6cb0cd317176c89b632e36 /sys | |
parent | f345bebc3296865457028897f6766ea365ce23d9 (diff) | |
download | FreeBSD-src-e2f426dc1b0fb18a48ef0de15a04f0588e32f27e.zip FreeBSD-src-e2f426dc1b0fb18a48ef0de15a04f0588e32f27e.tar.gz |
Fix a problem that caused system crashes after physio. This problem
was due to non-aligned 64K transfers taking 17 pages. We currently
do not support >16 page transfers. The transfer is unfortunately truncated,
but since buffers are usually malloced, this is a problem only once in
a while. Savecore is a culprit, but tar/cpio usually aren't. This
is NOT the final fix (which is likely a bouncing scheme), but will at
least keep the system from crashing.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_physio.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/sys/kern/kern_physio.c b/sys/kern/kern_physio.c index 7f8324b..ed4920c 100644 --- a/sys/kern/kern_physio.c +++ b/sys/kern/kern_physio.c @@ -16,7 +16,7 @@ * 4. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: kern_physio.c,v 1.15 1995/12/07 12:46:46 davidg Exp $ + * $Id: kern_physio.c,v 1.16 1995/12/13 15:12:59 julian Exp $ */ #include <sys/param.h> @@ -78,13 +78,13 @@ physio(strategy, bp, dev, rw, minp, uio) while( uio->uio_iov[i].iov_len) { bp->b_bcount = uio->uio_iov[i].iov_len; + bp->b_flags = B_BUSY | B_PHYS | B_CALL | bufflags; + bp->b_iodone = physwakeup; + bp->b_data = uio->uio_iov[i].iov_base; bp->b_bcount = minp( bp); if( minp != minphys) bp->b_bcount = minphys( bp); bp->b_bufsize = bp->b_bcount; - bp->b_flags = B_BUSY | B_PHYS | B_CALL | bufflags; - bp->b_iodone = physwakeup; - bp->b_data = uio->uio_iov[i].iov_base; /* * pass in the kva from the physical buffer * for the temporary kernel mapping. @@ -164,9 +164,14 @@ doerror: u_int minphys(struct buf *bp) { + u_int maxphys = MAXPHYS; + + if( ((vm_offset_t) bp->b_data) & PAGE_MASK) { + maxphys = MAXPHYS - PAGE_SIZE; + } - if( bp->b_bcount > MAXPHYS) { - bp->b_bcount = MAXPHYS; + if( bp->b_bcount > maxphys) { + bp->b_bcount = maxphys; } return bp->b_bcount; } |