virtio-blk: Convert VirtIOBlockReq.elem to pointer
This will make converging with dataplane code easier. Add virtio_blk_free_request to handle the freeing of request internal fields. Signed-off-by: Fam Zheng <famz@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		| @@ -27,6 +27,22 @@ | ||||
| #endif | ||||
| #include "hw/virtio/virtio-bus.h" | ||||
|  | ||||
| static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s) | ||||
| { | ||||
|     VirtIOBlockReq *req = g_slice_new0(VirtIOBlockReq); | ||||
|     req->dev = s; | ||||
|     req->elem = g_slice_new0(VirtQueueElement); | ||||
|     return req; | ||||
| } | ||||
|  | ||||
| static void virtio_blk_free_request(VirtIOBlockReq *req) | ||||
| { | ||||
|     if (req) { | ||||
|         g_slice_free(VirtQueueElement, req->elem); | ||||
|         g_slice_free(VirtIOBlockReq, req); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) | ||||
| { | ||||
|     VirtIOBlock *s = req->dev; | ||||
| @@ -35,7 +51,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) | ||||
|     trace_virtio_blk_req_complete(req, status); | ||||
|  | ||||
|     stb_p(&req->in->status, status); | ||||
|     virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in)); | ||||
|     virtqueue_push(s->vq, req->elem, req->qiov.size + sizeof(*req->in)); | ||||
|     virtio_notify(vdev, s->vq); | ||||
| } | ||||
|  | ||||
| @@ -51,7 +67,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, | ||||
|     } else if (action == BLOCK_ERROR_ACTION_REPORT) { | ||||
|         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); | ||||
|         bdrv_acct_done(s->bs, &req->acct); | ||||
|         g_free(req); | ||||
|         virtio_blk_free_request(req); | ||||
|     } | ||||
|  | ||||
|     bdrv_error_action(s->bs, action, is_read, error); | ||||
| @@ -72,7 +88,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret) | ||||
|  | ||||
|     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); | ||||
|     bdrv_acct_done(req->dev->bs, &req->acct); | ||||
|     g_free(req); | ||||
|     virtio_blk_free_request(req); | ||||
| } | ||||
|  | ||||
| static void virtio_blk_flush_complete(void *opaque, int ret) | ||||
| @@ -87,27 +103,16 @@ static void virtio_blk_flush_complete(void *opaque, int ret) | ||||
|  | ||||
|     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); | ||||
|     bdrv_acct_done(req->dev->bs, &req->acct); | ||||
|     g_free(req); | ||||
| } | ||||
|  | ||||
| static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s) | ||||
| { | ||||
|     VirtIOBlockReq *req = g_malloc(sizeof(*req)); | ||||
|     req->dev = s; | ||||
|     req->qiov.size = 0; | ||||
|     req->next = NULL; | ||||
|     return req; | ||||
|     virtio_blk_free_request(req); | ||||
| } | ||||
|  | ||||
| static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s) | ||||
| { | ||||
|     VirtIOBlockReq *req = virtio_blk_alloc_request(s); | ||||
|  | ||||
|     if (req != NULL) { | ||||
|         if (!virtqueue_pop(s->vq, &req->elem)) { | ||||
|             g_free(req); | ||||
|             return NULL; | ||||
|         } | ||||
|     if (!virtqueue_pop(s->vq, req->elem)) { | ||||
|         virtio_blk_free_request(req); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     return req; | ||||
| @@ -236,9 +241,9 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) | ||||
| { | ||||
|     int status; | ||||
|  | ||||
|     status = virtio_blk_handle_scsi_req(req->dev, &req->elem); | ||||
|     status = virtio_blk_handle_scsi_req(req->dev, req->elem); | ||||
|     virtio_blk_req_complete(req, status); | ||||
|     g_free(req); | ||||
|     virtio_blk_free_request(req); | ||||
| } | ||||
|  | ||||
| typedef struct MultiReqBuffer { | ||||
| @@ -340,19 +345,19 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req, | ||||
| { | ||||
|     uint32_t type; | ||||
|  | ||||
|     if (req->elem.out_num < 1 || req->elem.in_num < 1) { | ||||
|     if (req->elem->out_num < 1 || req->elem->in_num < 1) { | ||||
|         error_report("virtio-blk missing headers"); | ||||
|         exit(1); | ||||
|     } | ||||
|  | ||||
|     if (req->elem.out_sg[0].iov_len < sizeof(*req->out) || | ||||
|         req->elem.in_sg[req->elem.in_num - 1].iov_len < sizeof(*req->in)) { | ||||
|     if (req->elem->out_sg[0].iov_len < sizeof(*req->out) || | ||||
|         req->elem->in_sg[req->elem->in_num - 1].iov_len < sizeof(*req->in)) { | ||||
|         error_report("virtio-blk header not in correct element"); | ||||
|         exit(1); | ||||
|     } | ||||
|  | ||||
|     req->out = (void *)req->elem.out_sg[0].iov_base; | ||||
|     req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base; | ||||
|     req->out = (void *)req->elem->out_sg[0].iov_base; | ||||
|     req->in = (void *)req->elem->in_sg[req->elem->in_num - 1].iov_base; | ||||
|  | ||||
|     type = ldl_p(&req->out->type); | ||||
|  | ||||
| @@ -367,23 +372,23 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req, | ||||
|          * NB: per existing s/n string convention the string is | ||||
|          * terminated by '\0' only when shorter than buffer. | ||||
|          */ | ||||
|         strncpy(req->elem.in_sg[0].iov_base, | ||||
|         strncpy(req->elem->in_sg[0].iov_base, | ||||
|                 s->blk.serial ? s->blk.serial : "", | ||||
|                 MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES)); | ||||
|                 MIN(req->elem->in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES)); | ||||
|         virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); | ||||
|         g_free(req); | ||||
|         virtio_blk_free_request(req); | ||||
|     } else if (type & VIRTIO_BLK_T_OUT) { | ||||
|         qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1], | ||||
|                                  req->elem.out_num - 1); | ||||
|         qemu_iovec_init_external(&req->qiov, &req->elem->out_sg[1], | ||||
|                                  req->elem->out_num - 1); | ||||
|         virtio_blk_handle_write(req, mrb); | ||||
|     } else if (type == VIRTIO_BLK_T_IN || type == VIRTIO_BLK_T_BARRIER) { | ||||
|         /* VIRTIO_BLK_T_IN is 0, so we can't just & it. */ | ||||
|         qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0], | ||||
|                                  req->elem.in_num - 1); | ||||
|         qemu_iovec_init_external(&req->qiov, &req->elem->in_sg[0], | ||||
|                                  req->elem->in_num - 1); | ||||
|         virtio_blk_handle_read(req); | ||||
|     } else { | ||||
|         virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP); | ||||
|         g_free(req); | ||||
|         virtio_blk_free_request(req); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -598,7 +603,8 @@ static void virtio_blk_save(QEMUFile *f, void *opaque) | ||||
|      | ||||
|     while (req) { | ||||
|         qemu_put_sbyte(f, 1); | ||||
|         qemu_put_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem)); | ||||
|         qemu_put_buffer(f, (unsigned char *)req->elem, | ||||
|                         sizeof(VirtQueueElement)); | ||||
|         req = req->next; | ||||
|     } | ||||
|     qemu_put_sbyte(f, 0); | ||||
| @@ -620,14 +626,15 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id) | ||||
|  | ||||
|     while (qemu_get_sbyte(f)) { | ||||
|         VirtIOBlockReq *req = virtio_blk_alloc_request(s); | ||||
|         qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem)); | ||||
|         qemu_get_buffer(f, (unsigned char *)req->elem, | ||||
|                         sizeof(VirtQueueElement)); | ||||
|         req->next = s->rq; | ||||
|         s->rq = req; | ||||
|  | ||||
|         virtqueue_map_sg(req->elem.in_sg, req->elem.in_addr, | ||||
|             req->elem.in_num, 1); | ||||
|         virtqueue_map_sg(req->elem.out_sg, req->elem.out_addr, | ||||
|             req->elem.out_num, 0); | ||||
|         virtqueue_map_sg(req->elem->in_sg, req->elem->in_addr, | ||||
|             req->elem->in_num, 1); | ||||
|         virtqueue_map_sg(req->elem->out_sg, req->elem->out_addr, | ||||
|             req->elem->out_num, 0); | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
|   | ||||
| @@ -136,7 +136,7 @@ typedef struct VirtIOBlock { | ||||
|  | ||||
| typedef struct VirtIOBlockReq { | ||||
|     VirtIOBlock *dev; | ||||
|     VirtQueueElement elem; | ||||
|     VirtQueueElement *elem; | ||||
|     struct virtio_blk_inhdr *in; | ||||
|     struct virtio_blk_outhdr *out; | ||||
|     QEMUIOVector qiov; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user