Message ID | 1478706218-8935-4-git-send-email-thuth@redhat.com |
---|---|
State | Changes Requested |
Headers | show |
Thomas Huth <thuth@redhat.com> writes: > Rework the virtio-block code a little bit to provide > block write access, too. > > Signed-off-by: Thomas Huth <thuth@redhat.com> > --- > board-qemu/slof/virtio-block.fs | 8 ++++++++ > lib/libvirtio/virtio-blk.c | 24 +++++++++++++----------- > lib/libvirtio/virtio-blk.h | 3 ++- > lib/libvirtio/virtio.code | 11 ++++++++++- > lib/libvirtio/virtio.in | 1 + > 5 files changed, 34 insertions(+), 13 deletions(-) > > diff --git a/board-qemu/slof/virtio-block.fs b/board-qemu/slof/virtio-block.fs > index bc9013e..e2e3def 100644 > --- a/board-qemu/slof/virtio-block.fs > +++ b/board-qemu/slof/virtio-block.fs > @@ -49,6 +49,10 @@ virtio-setup-vd VALUE virtiodev > virtiodev virtio-blk-read > ; > > +: write-blocks ( addr block# #blocks -- #written ) > + virtiodev virtio-blk-write > +; > + > \ Standard node "open" function > : open ( -- okay? ) > open 0= IF false EXIT THEN > @@ -79,6 +83,10 @@ virtio-setup-vd VALUE virtiodev > s" read" deblocker @ $call-method > ; > > +: write ( addr len -- actual ) > + s" write" deblocker @ $call-method > +; > + > \ Set disk alias if none is set yet > : (set-alias) > s" disk" get-next-alias ?dup IF > diff --git a/lib/libvirtio/virtio-blk.c b/lib/libvirtio/virtio-blk.c > index 07ec104..bc554f3 100644 > --- a/lib/libvirtio/virtio-blk.c > +++ b/lib/libvirtio/virtio-blk.c > @@ -112,15 +112,17 @@ static void fill_blk_hdr(struct virtio_blk_req *blkhdr, bool is_modern, > } > > /** > - * Read blocks > + * Read / write blocks > * @param reg pointer to "reg" property > * @param buf pointer to destination buffer > - * @param blocknum block number of the first block that should be read > - * @param cnt amount of blocks that should be read > - * @return number of blocks that have been read successfully > + * @param blocknum block number of the first block that should be transfered > + * @param cnt amount of blocks that should be transfered > + * @param type VIRTIO_BLK_T_OUT for write, VIRTIO_BLK_T_IN for read transfers > + * @return number of blocks that have been transfered successfully > */ > int > -virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt) > +virtioblk_transfer(struct virtio_device *dev, char *buf, uint64_t blocknum, > + long cnt, unsigned int type) > { > struct vring_desc *desc; > int id; > @@ -136,7 +138,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt > uint16_t last_used_idx, avail_idx; > int blk_size = DEFAULT_SECTOR_SIZE; > > - //printf("virtioblk_read: dev=%p buf=%p blocknum=%li count=%li\n", > + //printf("virtioblk_transfer: dev=%p buf=%p blocknum=%lli count=%li\n", > // dev, buf, blocknum, cnt); > > /* Check whether request is within disk capacity */ > @@ -144,7 +146,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt > offset_of(struct virtio_blk_cfg, capacity), > sizeof(capacity)); > if (blocknum + cnt - 1 > capacity) { > - puts("virtioblk_read: Access beyond end of device!"); > + puts("virtioblk_transfer: Access beyond end of device!"); > return 0; > } > > @@ -152,7 +154,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt > offset_of(struct virtio_blk_cfg, blk_size), > sizeof(blk_size)); > if (blk_size % DEFAULT_SECTOR_SIZE) { > - fprintf(stderr, "virtio-blk: Unaligned sector read %d\n", blk_size); > + fprintf(stderr, "virtio-blk: Unaligned sector size %d\n", blk_size); > return 0; > } > > @@ -167,7 +169,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt > current_used_idx = &vq_used->idx; > > /* Set up header */ > - fill_blk_hdr(&blkhdr, dev->is_modern, VIRTIO_BLK_T_IN | VIRTIO_BLK_T_BARRIER, > + fill_blk_hdr(&blkhdr, dev->is_modern, type | VIRTIO_BLK_T_BARRIER, > 1, blocknum * blk_size / DEFAULT_SECTOR_SIZE); > > /* Determine descriptor index */ > @@ -182,7 +184,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt > /* Set up virtqueue descriptor for data */ > desc = &vq_desc[(id + 1) % vq_size]; > virtio_fill_desc(desc, dev->is_modern, (uint64_t)buf, cnt * blk_size, > - VRING_DESC_F_NEXT | VRING_DESC_F_WRITE, > + VRING_DESC_F_NEXT | ((type & 1) ? 0 : VRING_DESC_F_WRITE), > (id + 2) % vq_size); > > /* Set up virtqueue descriptor for status */ > @@ -209,7 +211,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt > if (status == 0) > return cnt; > > - printf("virtioblk_read failed! status = %i\n", status); > + printf("virtioblk_transfer failed! status = %i\n", status); Including type (In/Out) in the above error prints will help in debugging. Regards Nikunj
diff --git a/board-qemu/slof/virtio-block.fs b/board-qemu/slof/virtio-block.fs index bc9013e..e2e3def 100644 --- a/board-qemu/slof/virtio-block.fs +++ b/board-qemu/slof/virtio-block.fs @@ -49,6 +49,10 @@ virtio-setup-vd VALUE virtiodev virtiodev virtio-blk-read ; +: write-blocks ( addr block# #blocks -- #written ) + virtiodev virtio-blk-write +; + \ Standard node "open" function : open ( -- okay? ) open 0= IF false EXIT THEN @@ -79,6 +83,10 @@ virtio-setup-vd VALUE virtiodev s" read" deblocker @ $call-method ; +: write ( addr len -- actual ) + s" write" deblocker @ $call-method +; + \ Set disk alias if none is set yet : (set-alias) s" disk" get-next-alias ?dup IF diff --git a/lib/libvirtio/virtio-blk.c b/lib/libvirtio/virtio-blk.c index 07ec104..bc554f3 100644 --- a/lib/libvirtio/virtio-blk.c +++ b/lib/libvirtio/virtio-blk.c @@ -112,15 +112,17 @@ static void fill_blk_hdr(struct virtio_blk_req *blkhdr, bool is_modern, } /** - * Read blocks + * Read / write blocks * @param reg pointer to "reg" property * @param buf pointer to destination buffer - * @param blocknum block number of the first block that should be read - * @param cnt amount of blocks that should be read - * @return number of blocks that have been read successfully + * @param blocknum block number of the first block that should be transfered + * @param cnt amount of blocks that should be transfered + * @param type VIRTIO_BLK_T_OUT for write, VIRTIO_BLK_T_IN for read transfers + * @return number of blocks that have been transfered successfully */ int -virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt) +virtioblk_transfer(struct virtio_device *dev, char *buf, uint64_t blocknum, + long cnt, unsigned int type) { struct vring_desc *desc; int id; @@ -136,7 +138,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt uint16_t last_used_idx, avail_idx; int blk_size = DEFAULT_SECTOR_SIZE; - //printf("virtioblk_read: dev=%p buf=%p blocknum=%li count=%li\n", + //printf("virtioblk_transfer: dev=%p buf=%p blocknum=%lli count=%li\n", // dev, buf, blocknum, cnt); /* Check whether request is within disk capacity */ @@ -144,7 +146,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt offset_of(struct virtio_blk_cfg, capacity), sizeof(capacity)); if (blocknum + cnt - 1 > capacity) { - puts("virtioblk_read: Access beyond end of device!"); + puts("virtioblk_transfer: Access beyond end of device!"); return 0; } @@ -152,7 +154,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt offset_of(struct virtio_blk_cfg, blk_size), sizeof(blk_size)); if (blk_size % DEFAULT_SECTOR_SIZE) { - fprintf(stderr, "virtio-blk: Unaligned sector read %d\n", blk_size); + fprintf(stderr, "virtio-blk: Unaligned sector size %d\n", blk_size); return 0; } @@ -167,7 +169,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt current_used_idx = &vq_used->idx; /* Set up header */ - fill_blk_hdr(&blkhdr, dev->is_modern, VIRTIO_BLK_T_IN | VIRTIO_BLK_T_BARRIER, + fill_blk_hdr(&blkhdr, dev->is_modern, type | VIRTIO_BLK_T_BARRIER, 1, blocknum * blk_size / DEFAULT_SECTOR_SIZE); /* Determine descriptor index */ @@ -182,7 +184,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt /* Set up virtqueue descriptor for data */ desc = &vq_desc[(id + 1) % vq_size]; virtio_fill_desc(desc, dev->is_modern, (uint64_t)buf, cnt * blk_size, - VRING_DESC_F_NEXT | VRING_DESC_F_WRITE, + VRING_DESC_F_NEXT | ((type & 1) ? 0 : VRING_DESC_F_WRITE), (id + 2) % vq_size); /* Set up virtqueue descriptor for status */ @@ -209,7 +211,7 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt if (status == 0) return cnt; - printf("virtioblk_read failed! status = %i\n", status); + printf("virtioblk_transfer failed! status = %i\n", status); return 0; } diff --git a/lib/libvirtio/virtio-blk.h b/lib/libvirtio/virtio-blk.h index 2e7b592..21f0adc 100644 --- a/lib/libvirtio/virtio-blk.h +++ b/lib/libvirtio/virtio-blk.h @@ -55,6 +55,7 @@ struct virtio_blk_req { extern int virtioblk_init(struct virtio_device *dev); extern void virtioblk_shutdown(struct virtio_device *dev); -extern int virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt); +extern int virtioblk_transfer(struct virtio_device *dev, char *buf, + uint64_t blocknum, long cnt, unsigned int type); #endif /* _VIRTIO_BLK_H */ diff --git a/lib/libvirtio/virtio.code b/lib/libvirtio/virtio.code index 971a3cf..b8262ad 100644 --- a/lib/libvirtio/virtio.code +++ b/lib/libvirtio/virtio.code @@ -70,7 +70,16 @@ PRIM(virtio_X2d_blk_X2d_read) long cnt = TOS.n; POP; long blkno = TOS.n; POP; void *buf = TOS.a; - TOS.n = virtioblk_read(dev, buf, blkno, cnt); + TOS.n = virtioblk_transfer(dev, buf, blkno, cnt, VIRTIO_BLK_T_IN); +MIRP + +// : virtio-blk-write ( buf blkno cnt dev -- #written ) +PRIM(virtio_X2d_blk_X2d_write) + void *dev = TOS.a; POP; + long cnt = TOS.n; POP; + long blkno = TOS.n; POP; + void *buf = TOS.a; + TOS.n = virtioblk_transfer(dev, buf, blkno, cnt, VIRTIO_BLK_T_OUT); MIRP /******** virtio-fs ********/ diff --git a/lib/libvirtio/virtio.in b/lib/libvirtio/virtio.in index d2b1641..41a9cd0 100644 --- a/lib/libvirtio/virtio.in +++ b/lib/libvirtio/virtio.in @@ -20,6 +20,7 @@ cod(virtio-set-qaddr) cod(virtio-blk-init) cod(virtio-blk-shutdown) cod(virtio-blk-read) +cod(virtio-blk-write) cod(virtio-scsi-init) cod(virtio-scsi-shutdown)
Rework the virtio-block code a little bit to provide block write access, too. Signed-off-by: Thomas Huth <thuth@redhat.com> --- board-qemu/slof/virtio-block.fs | 8 ++++++++ lib/libvirtio/virtio-blk.c | 24 +++++++++++++----------- lib/libvirtio/virtio-blk.h | 3 ++- lib/libvirtio/virtio.code | 11 ++++++++++- lib/libvirtio/virtio.in | 1 + 5 files changed, 34 insertions(+), 13 deletions(-)