mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-08-24 23:16:45 +00:00
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:
committed by
Will Deacon
parent
ba021bc9d6
commit
258dd093dc
+22
-8
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user