ok
On 02/04/2011, at 11:58 PM, 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?
>
>
> 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. */