From: Pekka Enberg Date: Sat, 8 Jan 2011 12:28:59 +0000 (+0200) Subject: kvm: Implement virtio block device write support X-Git-Tag: next-20110824~3^2~528^2~18 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=ed7acee4a9de8ad144581de5916e8e6911bf9505;p=karo-tx-linux.git kvm: Implement virtio block device write support This patch implement virtio block device write support. The writes are not persistent because we map the disk image with MAP_PRIVATE. Signed-off-by: Pekka Enberg --- diff --git a/tools/kvm/blk-virtio.c b/tools/kvm/blk-virtio.c index 1e26ca5d85bb..13e6d90a66bf 100644 --- a/tools/kvm/blk-virtio.c +++ b/tools/kvm/blk-virtio.c @@ -119,10 +119,9 @@ static bool blk_virtio_read(struct kvm *self, struct virt_queue *queue) struct virtio_blk_outhdr *req; struct vring_desc *desc; uint16_t desc_ndx; - uint32_t dst_len; + uint32_t block_len; uint8_t *status; - void *dst; - int err; + void *block; desc_ndx = queue->vring.avail->ring[queue->last_avail_idx++ % queue->vring.num]; @@ -141,8 +140,8 @@ static bool blk_virtio_read(struct kvm *self, struct virt_queue *queue) desc = &queue->vring.desc[desc->next]; assert(!(desc->flags & VRING_DESC_F_INDIRECT)); - dst = guest_flat_to_host(self, desc->addr); - dst_len = desc->len; + block = guest_flat_to_host(self, desc->addr); + block_len = desc->len; /* status */ desc = &queue->vring.desc[desc->next]; @@ -150,16 +149,31 @@ static bool blk_virtio_read(struct kvm *self, struct virt_queue *queue) status = guest_flat_to_host(self, desc->addr); - if (req->type == VIRTIO_BLK_T_IN) { - err = disk_image__read_sector(self->disk_image, req->sector, dst, dst_len); + switch (req->type) { + case VIRTIO_BLK_T_IN: { + int err; + err = disk_image__read_sector(self->disk_image, req->sector, block, block_len); if (err) *status = VIRTIO_BLK_S_IOERR; else *status = VIRTIO_BLK_S_OK; - } else { + break; + } + case VIRTIO_BLK_T_OUT: { + int err; + + err = disk_image__write_sector(self->disk_image, req->sector, block, block_len); + if (err) + *status = VIRTIO_BLK_S_IOERR; + else + *status = VIRTIO_BLK_S_OK; + break; + } + default: warning("request type %d", req->type); *status = VIRTIO_BLK_S_IOERR; + break; } used_elem = &queue->vring.used->ring[queue->vring.used->idx++ % queue->vring.num]; diff --git a/tools/kvm/disk-image.c b/tools/kvm/disk-image.c index a6d1e964810a..fd2d96898b82 100644 --- a/tools/kvm/disk-image.c +++ b/tools/kvm/disk-image.c @@ -46,7 +46,7 @@ struct disk_image *disk_image__open(const char *filename) self->size = st.st_size; - self->mmap = mmap(NULL, self->size, PROT_READ, MAP_PRIVATE, self->fd, 0); + self->mmap = mmap(NULL, self->size, PROT_READ|PROT_WRITE, MAP_PRIVATE, self->fd, 0); if (self->mmap == MAP_FAILED) goto failed_close_fd; @@ -85,3 +85,15 @@ int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, return 0; } + +int disk_image__write_sector(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len) +{ + uint64_t offset = sector << SECTOR_SHIFT; + + if (offset + src_len > self->size) + return -1; + + memcpy(self->mmap + offset, src, src_len); + + return 0; +} diff --git a/tools/kvm/include/kvm/disk-image.h b/tools/kvm/include/kvm/disk-image.h index 6cba338d4fba..c6413ca51ffa 100644 --- a/tools/kvm/include/kvm/disk-image.h +++ b/tools/kvm/include/kvm/disk-image.h @@ -12,5 +12,6 @@ struct disk_image { struct disk_image *disk_image__open(const char *filename); void disk_image__close(struct disk_image *self); int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len); +int disk_image__write_sector(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len); #endif /* KVM__DISK_IMAGE_H */