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 <penberg@kernel.org>
This commit is contained in:
Pekka Enberg
2011-01-08 14:28:59 +02:00
committed by Will Deacon
parent ba021bc9d6
commit 258dd093dc
3 changed files with 36 additions and 9 deletions
+22 -8
View File
@@ -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];
+13 -1
View File
@@ -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;
}
+1
View File
@@ -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 */