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];
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];
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];
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;
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;
+}
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 */