On Sat, Apr 02, 2011 at 01:58:22PM +0000, Thordur Bjornsson wrote: > Hi, > > So, it doesn't make sense to have a bufq for vnds. > > The disk that stores the image backing the vnd has it's own bufq > ofcourse and what happens is that vnd puts a buf on it's bufq, > which is promptly removed when we call vndstart, followed by a call > to strategy so the buf ends up almost immediately on the bufq > on the underlaying disk. > > Tested on vnd/svnd (and with the image on NFS. vnd is broken on nfs!). > > OK? >
Makes sense to me. ok krw@. .... Ken > > Index: vnd.c > =================================================================== > RCS file: /home/thib/cvs/src/sys/dev/vnd.c,v > retrieving revision 1.107 > diff -u -p -r1.107 vnd.c > --- vnd.c 15 Feb 2011 20:02:11 -0000 1.107 > +++ vnd.c 2 Apr 2011 11:34:38 -0000 > @@ -127,8 +127,6 @@ struct vnd_softc { > struct disk sc_dk; > char sc_dk_name[16]; > > - struct bufq sc_bufq; > - > char sc_file[VNDNLEN]; /* file we're covering */ > int sc_flags; /* flags */ > size_t sc_size; /* size of vnd in sectors */ > @@ -159,7 +157,7 @@ int numvnd = 0; > void vndattach(int); > > void vndclear(struct vnd_softc *); > -void vndstart(struct vnd_softc *); > +void vndstart(struct vnd_softc *, struct buf *); > int vndsetcred(struct vnd_softc *, struct ucred *); > void vndiodone(struct buf *); > void vndshutdown(void); > @@ -445,64 +443,50 @@ vndstrategy(struct buf *bp) > > /* No bypassing of buffer cache? */ > if (vndsimple(bp->b_dev)) { > - /* Loop until all queued requests are handled. */ > - for (;;) { > - int part = DISKPART(bp->b_dev); > - daddr64_t off = DL_SECTOBLK(vnd->sc_dk.dk_label, > - > DL_GETPOFFSET(&vnd->sc_dk.dk_label->d_partitions[part])); > - aiov.iov_base = bp->b_data; > - auio.uio_resid = aiov.iov_len = bp->b_bcount; > - auio.uio_iov = &aiov; > - auio.uio_iovcnt = 1; > - auio.uio_offset = dbtob((off_t)(bp->b_blkno + off)); > - auio.uio_segflg = UIO_SYSSPACE; > - auio.uio_procp = p; > - > - vn_lock(vnd->sc_vp, LK_EXCLUSIVE | LK_RETRY, p); > - if (bp->b_flags & B_READ) { > - auio.uio_rw = UIO_READ; > - bp->b_error = VOP_READ(vnd->sc_vp, &auio, 0, > - vnd->sc_cred); > - if (vnd->sc_keyctx) > - vndencrypt(vnd, bp->b_data, > - bp->b_bcount, bp->b_blkno, 0); > - } else { > - if (vnd->sc_keyctx) > - vndencrypt(vnd, bp->b_data, > - bp->b_bcount, bp->b_blkno, 1); > - auio.uio_rw = UIO_WRITE; > - /* > - * Upper layer has already checked I/O for > - * limits, so there is no need to do it again. > - */ > - bp->b_error = VOP_WRITE(vnd->sc_vp, &auio, > - IO_NOLIMIT, vnd->sc_cred); > - /* Data in buffer cache needs to be in clear */ > - if (vnd->sc_keyctx) > - vndencrypt(vnd, bp->b_data, > - bp->b_bcount, bp->b_blkno, 0); > - } > - VOP_UNLOCK(vnd->sc_vp, 0, p); > - if (bp->b_error) > - bp->b_flags |= B_ERROR; > - bp->b_resid = auio.uio_resid; > - s = splbio(); > - biodone(bp); > - splx(s); > - > - /* If nothing more is queued, we are done. */ > - if (!bufq_peek(&vnd->sc_bufq)) > - return; > - > + int part = DISKPART(bp->b_dev); > + daddr64_t off = DL_SECTOBLK(vnd->sc_dk.dk_label, > + DL_GETPOFFSET(&vnd->sc_dk.dk_label->d_partitions[part])); > + aiov.iov_base = bp->b_data; > + auio.uio_resid = aiov.iov_len = bp->b_bcount; > + auio.uio_iov = &aiov; > + auio.uio_iovcnt = 1; > + auio.uio_offset = dbtob((off_t)(bp->b_blkno + off)); > + auio.uio_segflg = UIO_SYSSPACE; > + auio.uio_procp = p; > + > + vn_lock(vnd->sc_vp, LK_EXCLUSIVE | LK_RETRY, p); > + if (bp->b_flags & B_READ) { > + auio.uio_rw = UIO_READ; > + bp->b_error = VOP_READ(vnd->sc_vp, &auio, 0, > + vnd->sc_cred); > + if (vnd->sc_keyctx) > + vndencrypt(vnd, bp->b_data, > + bp->b_bcount, bp->b_blkno, 0); > + } else { > + if (vnd->sc_keyctx) > + vndencrypt(vnd, bp->b_data, > + bp->b_bcount, bp->b_blkno, 1); > + auio.uio_rw = UIO_WRITE; > /* > - * Dequeue now since lower level strategy > - * routine might queue using same links. > + * Upper layer has already checked I/O for > + * limits, so there is no need to do it again. > */ > - s = splbio(); > - bp = bufq_dequeue(&vnd->sc_bufq); > - KASSERT(bp != NULL); > - splx(s); > + bp->b_error = VOP_WRITE(vnd->sc_vp, &auio, > + IO_NOLIMIT, vnd->sc_cred); > + /* Data in buffer cache needs to be in clear */ > + if (vnd->sc_keyctx) > + vndencrypt(vnd, bp->b_data, > + bp->b_bcount, bp->b_blkno, 0); > } > + VOP_UNLOCK(vnd->sc_vp, 0, p); > + if (bp->b_error) > + bp->b_flags |= B_ERROR; > + bp->b_resid = auio.uio_resid; > + s = splbio(); > + biodone(bp); > + splx(s); > + > + return; > } > > if (vnd->sc_vp->v_type != VREG || vnd->sc_keyctx != NULL) { > @@ -597,34 +581,15 @@ vndstrategy(struct buf *bp) > return; > } > > - bufq_queue(&vnd->sc_bufq, &nbp->vb_buf); > - s = splbio(); > - vndstart(vnd); > - splx(s); > + vndstart(vnd, &nbp->vb_buf); > bn += sz; > addr += sz; > } > } > > -/* > - * Feed requests sequentially. > - * We do it this way to keep from flooding NFS servers if we are connected > - * to an NFS file. This places the burden on the client rather than the > - * server. > - */ > void > -vndstart(struct vnd_softc *vnd) > +vndstart(struct vnd_softc *vnd, struct buf *bp) > { > - struct buf *bp; > - > - /* > - * Dequeue now since lower level strategy routine might > - * queue using same links > - */ > - bp = bufq_dequeue(&vnd->sc_bufq); > - if (bp == NULL) > - return; > - > DNPRINTF(VDB_IO, > "vndstart(%d): bp %p vp %p blkno %lld addr %p cnt %lx\n", > vnd-vnd_softc, bp, bp->b_vp, bp->b_blkno, bp->b_data, > @@ -671,12 +636,6 @@ vndiodone(struct buf *bp) > } > > out: > - /* > - * A bufq_done call is actually done on this buf in the context > - * of the bufq for the device on which the vnd image resides on. > - * Meaning we have to do one ourselves too. > - */ > - bufq_done(&vnd->sc_bufq, bp); > putvndbuf(vbp); > disk_unbusy(&vnd->sc_dk, (pbp->b_bcount - pbp->b_resid), > (pbp->b_flags & B_READ)); > @@ -877,7 +836,6 @@ vndioctl(dev_t dev, u_long cmd, caddr_t > /* Attach the disk. */ > vnd->sc_dk.dk_name = vnd->sc_dk_name; > disk_attach(&vnd->sc_dev, &vnd->sc_dk); > - bufq_init(&vnd->sc_bufq, BUFQ_DEFAULT); > > vndunlock(vnd); > > @@ -914,7 +872,6 @@ vndioctl(dev_t dev, u_long cmd, caddr_t > } > > /* Detach the disk. */ > - bufq_destroy(&vnd->sc_bufq); > disk_detach(&vnd->sc_dk); > > /* This must be atomic. */