From 3591bbc6b6cd7b17c8e9173a262ef5695e8a59ec Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 30 Apr 2006 20:23:26 +0000 Subject: [PATCH] Remove buf->b_saveaddr, assert that vmapbuf() is only called on pbuf's. Pass the user pointer and length to vmapbuf() rather then having it try to pull the information out of the buffer. vmapbuf() is now responsible for setting b_data, b_bufsize, and b_bcount. Also fix a bug in cam_periph_mapmem(). The procedure was failing to unmap earlier vmapped bufs if later vmapbuf() calls in the loop failed. --- sys/bus/cam/cam_periph.c | 22 +++----- sys/bus/cam/cam_periph.h | 3 +- sys/dev/raid/vinum/.gdbinit.kernel | 4 +- sys/dev/raid/vinum/vinumio.c | 7 ++- sys/i386/i386/vm_machdep.c | 4 +- sys/kern/kern_physio.c | 30 +++++----- sys/kern/vfs_aio.c | 8 +-- sys/kern/vfs_bio.c | 85 +++++++++++++++++------------ sys/platform/pc32/i386/vm_machdep.c | 4 +- sys/sys/buf.h | 5 +- sys/vfs/ufs/ffs_rawread.c | 65 +++++++++------------- 11 files changed, 112 insertions(+), 125 deletions(-) diff --git a/sys/bus/cam/cam_periph.c b/sys/bus/cam/cam_periph.c index 7e4c7c3465..3a4d93731f 100644 --- a/sys/bus/cam/cam_periph.c +++ b/sys/bus/cam/cam_periph.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/cam/cam_periph.c,v 1.24.2.3 2003/01/25 19:04:40 dillon Exp $ - * $DragonFly: src/sys/bus/cam/cam_periph.c,v 1.14 2006/04/30 17:22:14 dillon Exp $ + * $DragonFly: src/sys/bus/cam/cam_periph.c,v 1.15 2006/04/30 20:23:19 dillon Exp $ */ #include @@ -587,29 +587,25 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo) */ mapinfo->bp[i] = getpbuf(NULL); - /* save the buffer's data address */ - mapinfo->bp[i]->b_saveaddr = mapinfo->bp[i]->b_data; - - /* put our pointer in the data slot */ - mapinfo->bp[i]->b_data = *data_ptrs[i]; - - /* set the transfer length, we know it's < DFLTPHYS */ - mapinfo->bp[i]->b_bufsize = lengths[i]; + /* save the original user pointer */ + mapinfo->saved_ptrs[i] = *data_ptrs[i]; /* set the flags */ mapinfo->bp[i]->b_cmd = cmd[i]; - /* map the buffer into kernel memory */ - if (vmapbuf(mapinfo->bp[i]) < 0) { + /* map the user buffer into kernel memory */ + if (vmapbuf(mapinfo->bp[i], *data_ptrs[i], lengths[i]) < 0) { printf("cam_periph_mapmem: error, " "address %p, length %lu isn't " "user accessible any more\n", (void *)*data_ptrs[i], (u_long)lengths[i]); for (j = 0; j < i; ++j) { - *data_ptrs[j] = mapinfo->bp[j]->b_saveaddr; + *data_ptrs[j] = mapinfo->saved_ptrs[j]; + vunmapbuf(mapinfo->bp[j]); relpbuf(mapinfo->bp[j], NULL); } + mapinfo->num_bufs_used -= i; return(EACCES); } @@ -661,7 +657,7 @@ cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo) for (i = 0; i < numbufs; i++) { /* Set the user's pointer back to the original value */ - *data_ptrs[i] = mapinfo->bp[i]->b_saveaddr; + *data_ptrs[i] = mapinfo->saved_ptrs[i]; /* unmap the buffer */ vunmapbuf(mapinfo->bp[i]); diff --git a/sys/bus/cam/cam_periph.h b/sys/bus/cam/cam_periph.h index adae22bd35..35c2ec6be8 100644 --- a/sys/bus/cam/cam_periph.h +++ b/sys/bus/cam/cam_periph.h @@ -26,7 +26,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/cam/cam_periph.h,v 1.6.2.1 2000/05/07 18:16:49 n_hibma Exp $ - * $DragonFly: src/sys/bus/cam/cam_periph.h,v 1.5 2003/12/29 23:09:30 dillon Exp $ + * $DragonFly: src/sys/bus/cam/cam_periph.h,v 1.6 2006/04/30 20:23:19 dillon Exp $ */ #ifndef _CAM_CAM_PERIPH_H @@ -107,6 +107,7 @@ struct devstat; struct cam_periph_map_info { int num_bufs_used; struct buf *bp[CAM_PERIPH_MAXMAPS]; + caddr_t saved_ptrs[CAM_PERIPH_MAXMAPS]; }; cam_status cam_periph_alloc(periph_ctor_t *periph_ctor, diff --git a/sys/dev/raid/vinum/.gdbinit.kernel b/sys/dev/raid/vinum/.gdbinit.kernel index 7364a01dee..36513649a7 100644 --- a/sys/dev/raid/vinum/.gdbinit.kernel +++ b/sys/dev/raid/vinum/.gdbinit.kernel @@ -1,4 +1,4 @@ -# $DragonFly: src/sys/dev/raid/vinum/.gdbinit.kernel,v 1.4 2006/03/24 18:35:32 dillon Exp $ +# $DragonFly: src/sys/dev/raid/vinum/.gdbinit.kernel,v 1.5 2006/04/30 20:23:21 dillon Exp $ set remotebaud 38400 set remotetimeout 1 set complaints 1 @@ -309,8 +309,6 @@ printf "\nb_validend: " output $bp->b_validend printf "\nb_poffset: " output $bp->b_bio_array[2].bio_offset -printf "\nb_saveaddr: " -output $bp->b_saveaddr printf "\nb_savekva: " output $bp->b_savekva printf "\nb_driver1: " diff --git a/sys/dev/raid/vinum/vinumio.c b/sys/dev/raid/vinum/vinumio.c index c179e4b328..f919ee0a76 100644 --- a/sys/dev/raid/vinum/vinumio.c +++ b/sys/dev/raid/vinum/vinumio.c @@ -35,7 +35,7 @@ * * $Id: vinumio.c,v 1.30 2000/05/10 23:23:30 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumio.c,v 1.52.2.6 2002/05/02 08:43:44 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumio.c,v 1.13 2006/04/30 17:22:17 dillon Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumio.c,v 1.14 2006/04/30 20:23:21 dillon Exp $ */ #include "vinumhdr.h" @@ -317,6 +317,7 @@ driveio(struct drive *drive, char *buf, size_t length, off_t offset, buf_cmd_t c { int error; struct buf *bp; + caddr_t saveaddr; error = 0; /* to keep the compiler happy */ while (length) { /* divide into small enough blocks */ @@ -325,12 +326,12 @@ driveio(struct drive *drive, char *buf, size_t length, off_t offset, buf_cmd_t c bp = geteblk(len); /* get a buffer header */ bp->b_cmd = cmd; bp->b_bio1.bio_offset = offset; /* disk offset */ - bp->b_saveaddr = bp->b_data; + saveaddr = bp->b_data; bp->b_data = buf; bp->b_bcount = len; dev_dstrategy(drive->dev, &bp->b_bio1); error = biowait(bp); - bp->b_data = bp->b_saveaddr; + bp->b_data = saveaddr; bp->b_flags |= B_INVAL | B_AGE; bp->b_flags &= ~B_ERROR; brelse(bp); diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index 1d7d385247..c2766b5040 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -39,7 +39,7 @@ * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ * $FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.132.2.9 2003/01/25 19:02:23 dillon Exp $ - * $DragonFly: src/sys/i386/i386/Attic/vm_machdep.c,v 1.40 2006/02/28 18:30:22 dillon Exp $ + * $DragonFly: src/sys/i386/i386/Attic/vm_machdep.c,v 1.41 2006/04/30 20:23:22 dillon Exp $ */ #include "use_npx.h" @@ -263,7 +263,7 @@ cpu_proc_exit(void) pcb->pcb_ext = NULL; td->td_switch(td); crit_exit(); - kmem_free(kernel_map, (caddr_t)ext, ctob(IOPAGES + 1)); + kmem_free(kernel_map, (vm_offset_t)ext, ctob(IOPAGES + 1)); } user_ldt_free(pcb); if (pcb->pcb_flags & PCB_DBREGS) { diff --git a/sys/kern/kern_physio.c b/sys/kern/kern_physio.c index ce342c9def..abc4619174 100644 --- a/sys/kern/kern_physio.c +++ b/sys/kern/kern_physio.c @@ -17,7 +17,7 @@ * are met. * * $FreeBSD: src/sys/kern/kern_physio.c,v 1.46.2.4 2003/11/14 09:51:47 simokawa Exp $ - * $DragonFly: src/sys/kern/kern_physio.c,v 1.18 2006/04/30 17:22:17 dillon Exp $ + * $DragonFly: src/sys/kern/kern_physio.c,v 1.19 2006/04/30 20:23:23 dillon Exp $ */ #include @@ -46,12 +46,11 @@ physio(dev_t dev, struct uio *uio, int ioflag) int error; int chk_blockno; int saflags; - caddr_t sa; - u_int iolen; + int iolen; + int bcount; struct buf *bp; bp = getpbuf(NULL); - sa = bp->b_data; saflags = bp->b_flags; error = 0; @@ -75,17 +74,15 @@ physio(dev_t dev, struct uio *uio, int ioflag) else bp->b_cmd = BUF_CMD_WRITE; bp->b_flags = saflags; - bp->b_data = uio->uio_iov[i].iov_base; - bp->b_bcount = uio->uio_iov[i].iov_len; - bp->b_saveaddr = sa; + bcount = uio->uio_iov[i].iov_len; reinitbufbio(bp); /* clear translation cache */ bp->b_bio1.bio_offset = uio->uio_offset; bp->b_bio1.bio_done = physwakeup; /* Don't exceed drivers iosize limit */ - if (bp->b_bcount > dev->si_iosize_max) - bp->b_bcount = dev->si_iosize_max; + if (bcount > dev->si_iosize_max) + bcount = dev->si_iosize_max; /* * Make sure the pbuf can map the request @@ -94,18 +91,20 @@ physio(dev_t dev, struct uio *uio, int ioflag) * XXX: page aligned or it will be fragmented. */ iolen = ((vm_offset_t) bp->b_data) & PAGE_MASK; - if ((bp->b_bcount + iolen) > bp->b_kvasize) { - bp->b_bcount = bp->b_kvasize; + if ((bcount + iolen) > bp->b_kvasize) { + bcount = bp->b_kvasize; if (iolen != 0) - bp->b_bcount -= PAGE_SIZE; + bcount -= PAGE_SIZE; } - bp->b_bufsize = bp->b_bcount; - if (uio->uio_segflg == UIO_USERSPACE) { - if (vmapbuf(bp) < 0) { + if (vmapbuf(bp, uio->uio_iov[i].iov_base, bcount) < 0) { error = EFAULT; goto doerror; } + } else { + bp->b_data = uio->uio_iov[i].iov_base; + bp->b_bcount = bcount; + bp->b_bufsize = bcount; } dev_dstrategy(dev, &bp->b_bio1); crit_enter(); @@ -129,7 +128,6 @@ physio(dev_t dev, struct uio *uio, int ioflag) } } doerror: - bp->b_data = sa; relpbuf(bp, NULL); return (error); } diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index bc8b2d5216..59e88dd5b6 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -14,7 +14,7 @@ * of the author. This software is distributed AS-IS. * * $FreeBSD: src/sys/kern/vfs_aio.c,v 1.70.2.28 2003/05/29 06:15:35 alc Exp $ - * $DragonFly: src/sys/kern/vfs_aio.c,v 1.24 2006/04/30 17:22:17 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_aio.c,v 1.25 2006/04/30 20:23:24 dillon Exp $ */ /* @@ -959,17 +959,13 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) bp->b_bio1.bio_caller_info1.ptr = p; error = 0; - bp->b_bcount = cb->aio_nbytes; - bp->b_bufsize = cb->aio_nbytes; bp->b_cmd = (cb->aio_lio_opcode == LIO_WRITE) ? BUF_CMD_WRITE : BUF_CMD_READ; bp->b_bio1.bio_done = aio_physwakeup; - bp->b_saveaddr = bp->b_data; - bp->b_data = (void *)(uintptr_t)cb->aio_buf; bp->b_bio1.bio_offset = cb->aio_offset; /* Bring buffer into kernel space. */ - if (vmapbuf(bp) < 0) { + if (vmapbuf(bp, __DEVOLATILE(char *, cb->aio_buf), cb->aio_nbytes) < 0) { error = EFAULT; goto doerror; } diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 3ac6febdf0..27e91bca4b 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -12,7 +12,7 @@ * John S. Dyson. * * $FreeBSD: src/sys/kern/vfs_bio.c,v 1.242.2.20 2003/05/28 18:38:10 alc Exp $ - * $DragonFly: src/sys/kern/vfs_bio.c,v 1.69 2006/04/30 18:52:36 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_bio.c,v 1.70 2006/04/30 20:23:24 dillon Exp $ */ /* @@ -3374,40 +3374,49 @@ vm_hold_free_pages(struct buf *bp, vm_offset_t from, vm_offset_t to) /* * vmapbuf: * - * Map an IO request into kernel virtual address space. - * - * All requests are (re)mapped into kernel VA space. - * Notice that we use b_bufsize for the size of the buffer - * to be mapped. b_bcount might be modified by the driver. + * Map a user buffer into KVM via a pbuf. On return the buffer's + * b_data, b_bufsize, and b_bcount will be set, and its XIO page array + * initialized. */ int -vmapbuf(struct buf *bp) +vmapbuf(struct buf *bp, caddr_t udata, int bytes) { - caddr_t addr, v, kva; + caddr_t addr; vm_paddr_t pa; int pidx; int i; + int vmprot; struct vm_page *m; /* - * bp had better have a command + * bp had better have a command and it better be a pbuf. */ KKASSERT(bp->b_cmd != BUF_CMD_DONE); + KKASSERT(bp->b_flags & B_PAGING); - if (bp->b_bufsize < 0) + if (bytes < 0) return (-1); - for (v = bp->b_saveaddr, - addr = (caddr_t)trunc_page((vm_offset_t)bp->b_data), - pidx = 0; - addr < bp->b_data + bp->b_bufsize; - addr += PAGE_SIZE, v += PAGE_SIZE, pidx++) { + + /* + * Map the user data into KVM. Mappings have to be page-aligned. + */ + addr = (caddr_t)trunc_page((vm_offset_t)udata); + pidx = 0; + + vmprot = VM_PROT_READ; + if (bp->b_cmd == BUF_CMD_READ) + vmprot |= VM_PROT_WRITE; + + while (addr < udata + bytes) { /* * Do the vm_fault if needed; do the copy-on-write thing * when reading stuff off device into memory. */ retry: - i = vm_fault_quick((addr >= bp->b_data) ? addr : bp->b_data, - (bp->b_cmd == BUF_CMD_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ); + if (addr >= udata) + i = vm_fault_quick(addr, vmprot); + else + i = vm_fault_quick(udata, vmprot); if (i < 0) { for (i = 0; i < pidx; ++i) { vm_page_unhold(bp->b_xio.xio_pages[i]); @@ -3417,13 +3426,9 @@ retry: } /* - * WARNING! If sparc support is MFCd in the future this will - * have to be changed from pmap_kextract() to pmap_extract() - * ala -current. + * Extract from current process's address map. Since the + * fault succeeded, an empty page indicates a race. */ -#ifdef __sparc64__ -#error "If MFCing sparc support use pmap_extract" -#endif pa = pmap_kextract((vm_offset_t)addr); if (pa == 0) { printf("vmapbuf: warning, race against user address during I/O"); @@ -3432,15 +3437,22 @@ retry: m = PHYS_TO_VM_PAGE(pa); vm_page_hold(m); bp->b_xio.xio_pages[pidx] = m; + addr += PAGE_SIZE; + ++pidx; } + + /* + * Map the page array and set the buffer fields to point to + * the mapped data buffer. + */ if (pidx > btoc(MAXPHYS)) panic("vmapbuf: mapped more than MAXPHYS"); - pmap_qenter((vm_offset_t)bp->b_saveaddr, bp->b_xio.xio_pages, pidx); - - kva = bp->b_saveaddr; + pmap_qenter((vm_offset_t)bp->b_kvabase, bp->b_xio.xio_pages, pidx); + bp->b_xio.xio_npages = pidx; - bp->b_saveaddr = bp->b_data; - bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK); + bp->b_data = bp->b_kvabase + ((int)(intptr_t)udata & PAGE_MASK); + bp->b_bcount = bytes; + bp->b_bufsize = bytes; return(0); } @@ -3455,16 +3467,17 @@ vunmapbuf(struct buf *bp) { int pidx; int npages; - vm_page_t *m; - npages = bp->b_xio.xio_npages; - pmap_qremove(trunc_page((vm_offset_t)bp->b_data), - npages); - m = bp->b_xio.xio_pages; - for (pidx = 0; pidx < npages; pidx++) - vm_page_unhold(*m++); + KKASSERT(bp->b_flags & B_PAGING); - bp->b_data = bp->b_saveaddr; + npages = bp->b_xio.xio_npages; + pmap_qremove(trunc_page((vm_offset_t)bp->b_data), npages); + for (pidx = 0; pidx < npages; ++pidx) { + vm_page_unhold(bp->b_xio.xio_pages[pidx]); + bp->b_xio.xio_pages[pidx] = NULL; + } + bp->b_xio.xio_npages = 0; + bp->b_data = bp->b_kvabase; } /* diff --git a/sys/platform/pc32/i386/vm_machdep.c b/sys/platform/pc32/i386/vm_machdep.c index 1d20068eb8..571845fde5 100644 --- a/sys/platform/pc32/i386/vm_machdep.c +++ b/sys/platform/pc32/i386/vm_machdep.c @@ -39,7 +39,7 @@ * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ * $FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.132.2.9 2003/01/25 19:02:23 dillon Exp $ - * $DragonFly: src/sys/platform/pc32/i386/vm_machdep.c,v 1.40 2006/02/28 18:30:22 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/i386/vm_machdep.c,v 1.41 2006/04/30 20:23:22 dillon Exp $ */ #include "use_npx.h" @@ -263,7 +263,7 @@ cpu_proc_exit(void) pcb->pcb_ext = NULL; td->td_switch(td); crit_exit(); - kmem_free(kernel_map, (caddr_t)ext, ctob(IOPAGES + 1)); + kmem_free(kernel_map, (vm_offset_t)ext, ctob(IOPAGES + 1)); } user_ldt_free(pcb); if (pcb->pcb_flags & PCB_DBREGS) { diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 224f0b709f..ea7534435b 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -37,7 +37,7 @@ * * @(#)buf.h 8.9 (Berkeley) 3/30/95 * $FreeBSD: src/sys/sys/buf.h,v 1.88.2.10 2003/01/25 19:02:23 dillon Exp $ - * $DragonFly: src/sys/sys/buf.h,v 1.32 2006/04/30 18:25:36 dillon Exp $ + * $DragonFly: src/sys/sys/buf.h,v 1.33 2006/04/30 20:23:25 dillon Exp $ */ #ifndef _SYS_BUF_H_ @@ -169,7 +169,6 @@ struct buf { int b_kvasize; /* size of kva for buffer */ int b_dirtyoff; /* Offset in buffer of dirty region. */ int b_dirtyend; /* Offset of end of dirty region. */ - void *b_saveaddr; /* Original b_addr for physio. */ struct xio b_xio; /* data buffer page list management */ struct workhead b_dep; /* List of filesystem dependencies. */ }; @@ -374,7 +373,7 @@ void vfs_bio_set_validclean (struct buf *, int base, int size); void vfs_bio_clrbuf (struct buf *); void vfs_busy_pages (struct vnode *, struct buf *); void vfs_unbusy_pages (struct buf *); -int vmapbuf (struct buf *); +int vmapbuf (struct buf *, caddr_t, int); void vunmapbuf (struct buf *); void relpbuf (struct buf *, int *); void brelvp (struct buf *); diff --git a/sys/vfs/ufs/ffs_rawread.c b/sys/vfs/ufs/ffs_rawread.c index ecc785f00b..8722e86907 100644 --- a/sys/vfs/ufs/ffs_rawread.c +++ b/sys/vfs/ufs/ffs_rawread.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/ufs/ffs/ffs_rawread.c,v 1.3.2.2 2003/05/29 06:15:35 alc Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_rawread.c,v 1.21 2006/04/30 17:22:18 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_rawread.c,v 1.22 2006/04/30 20:23:26 dillon Exp $ */ #include @@ -53,7 +53,7 @@ static int ffs_rawread_readahead(struct vnode *vp, caddr_t udata, off_t offset, size_t len, struct thread *td, struct buf *bp, - caddr_t sa, int *baseticks); + int *baseticks); static int ffs_rawread_main(struct vnode *vp, struct uio *uio); @@ -153,27 +153,27 @@ ffs_rawread_sync(struct vnode *vp, struct thread *td) static int ffs_rawread_readahead(struct vnode *vp, caddr_t udata, off_t loffset, size_t len, struct thread *td, struct buf *bp, - caddr_t sa, int *baseticks) + int *baseticks) { int error; - uint iolen; + int iolen; int blockoff; int bsize; struct vnode *dp; int bforwards; bsize = vp->v_mount->mnt_stat.f_iosize; - - iolen = ((vm_offset_t) udata) & PAGE_MASK; - bp->b_bcount = len; - if (bp->b_bcount + iolen > bp->b_kvasize) { - bp->b_bcount = bp->b_kvasize; + + /* + * Make sure it fits into the pbuf + */ + iolen = (int)(intptr_t)udata & PAGE_MASK; + if (len + iolen > bp->b_kvasize) { + len = bp->b_kvasize; if (iolen != 0) - bp->b_bcount -= PAGE_SIZE; + len -= PAGE_SIZE; } bp->b_flags &= ~B_ERROR; - bp->b_data = udata; - bp->b_saveaddr = sa; bp->b_loffset = loffset; bp->b_bio2.bio_offset = NOOFFSET; bp->b_bio2.bio_done = ffs_rawreadwakeup; @@ -189,18 +189,17 @@ ffs_rawread_readahead(struct vnode *vp, caddr_t udata, off_t loffset, /* * Fill holes with NULs to preserve semantics */ - if (bp->b_bcount + blockoff * DEV_BSIZE > bsize) - bp->b_bcount = bsize - blockoff * DEV_BSIZE; - bp->b_bufsize = bp->b_bcount; + if (len + blockoff * DEV_BSIZE > bsize) + len = bsize - blockoff * DEV_BSIZE; - if (vmapbuf(bp) < 0) + if (vmapbuf(bp, udata, len) < 0) return EFAULT; if (ticks - *baseticks >= hogticks) { *baseticks = ticks; uio_yield(); } - bzero(bp->b_data, bp->b_bufsize); + bzero(bp->b_data, bp->b_bcount); /* Mark operation completed (similar to bufdone()) */ @@ -208,12 +207,11 @@ ffs_rawread_readahead(struct vnode *vp, caddr_t udata, off_t loffset, return 0; } - if (bp->b_bcount + blockoff * DEV_BSIZE > bforwards) - bp->b_bcount = bforwards - blockoff * DEV_BSIZE; - bp->b_bufsize = bp->b_bcount; + if (len + blockoff * DEV_BSIZE > bforwards) + len = bforwards - blockoff * DEV_BSIZE; bp->b_bio2.bio_offset += blockoff * DEV_BSIZE; - if (vmapbuf(bp) < 0) + if (vmapbuf(bp, udata, len) < 0) return EFAULT; /* @@ -231,14 +229,12 @@ ffs_rawread_readahead(struct vnode *vp, caddr_t udata, off_t loffset, return 0; } - static int ffs_rawread_main(struct vnode *vp, struct uio *uio) { int error, nerror; struct buf *bp, *nbp, *tbp; - caddr_t sa, nsa, tsa; - uint iolen; + int iolen; int baseticks = ticks; caddr_t udata; int resid; @@ -255,17 +251,14 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) bp = NULL; nbp = NULL; - sa = NULL; - nsa = NULL; while (resid > 0) { if (bp == NULL) { /* Setup first read */ /* XXX: Leave some bufs for swap */ bp = getpbuf(&ffsrawbufcnt); - sa = bp->b_data; error = ffs_rawread_readahead(vp, udata, offset, resid, - td, bp, sa, &baseticks); + td, bp, &baseticks); if (error != 0) break; @@ -276,15 +269,12 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) else nbp = NULL; if (nbp != NULL) { - nsa = nbp->b_data; - nerror = ffs_rawread_readahead( vp, udata + bp->b_bufsize, offset + bp->b_bufsize, resid - bp->b_bufsize, - td, nbp, nsa, - &baseticks); + td, nbp, &baseticks); if (nerror) { relpbuf(nbp, &ffsrawbufcnt); nbp = NULL; @@ -318,8 +308,7 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) /* Incomplete read. Try to read remaining part */ error = ffs_rawread_readahead( vp, udata, offset, - bp->b_bufsize - iolen, td, bp, - sa, &baseticks); + bp->b_bufsize - iolen, td, bp, &baseticks); if (error != 0) break; } else if (nbp != NULL) { /* Complete read with readahead */ @@ -328,10 +317,6 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) bp = nbp; nbp = tbp; - tsa = sa; - sa = nsa; - nsa = tsa; - clearbiocache(&nbp->b_bio2); if (resid <= bp->b_bufsize) { /* No more readaheads */ @@ -342,7 +327,7 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) vp, udata + bp->b_bufsize, offset + bp->b_bufsize, resid - bp->b_bufsize, - td, nbp, nsa, &baseticks); + td, nbp, &baseticks); if (nerror != 0) { relpbuf(nbp, &ffsrawbufcnt); nbp = NULL; @@ -352,7 +337,7 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) break; } else if (resid > 0) { /* More to read, no readahead */ error = ffs_rawread_readahead(vp, udata, offset, - resid, td, bp, sa, + resid, td, bp, &baseticks); if (error != 0) break; -- 2.41.0