diff options
author | Fam Zheng <famz@redhat.com> | 2014-06-11 12:11:50 +0800 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2014-06-27 18:18:31 +0200 |
commit | ee17e84830e2e7030d57db5b415719e9022573cd (patch) | |
tree | f24f67489f917b1376d0b13f548c7fc3fd40b949 /hw/block | |
parent | ab2e3cd2dc97ad87fcdfb814a13b2ef386a5f13a (diff) | |
download | qemu-ee17e84830e2e7030d57db5b415719e9022573cd.zip qemu-ee17e84830e2e7030d57db5b415719e9022573cd.tar.gz qemu-ee17e84830e2e7030d57db5b415719e9022573cd.tar.bz2 |
virtio-blk: Fix and clean up the in_sg and out_sg check
out_sg is checked by iov_to_buf below, so it can be dropped.
Add assert and iov_discard_back around in_sg, as the in_sg is handled in
dataplane code.
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/block')
-rw-r--r-- | hw/block/virtio-blk.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 0561095..4b1aeab 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -345,7 +345,9 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) { uint32_t type; + struct iovec *in_iov = req->elem->in_sg; struct iovec *iov = req->elem->out_sg; + unsigned in_num = req->elem->in_num; unsigned out_num = req->elem->out_num; if (req->elem->out_num < 1 || req->elem->in_num < 1) { @@ -353,19 +355,24 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req, 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)) { - error_report("virtio-blk header not in correct element"); - exit(1); - } - if (unlikely(iov_to_buf(iov, out_num, 0, &req->out, sizeof(req->out)) != sizeof(req->out))) { error_report("virtio-blk request outhdr too short"); exit(1); } + iov_discard_front(&iov, &out_num, sizeof(req->out)); - req->in = (void *)req->elem->in_sg[req->elem->in_num - 1].iov_base; + + if (in_num < 1 || + in_iov[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) { + error_report("virtio-blk request inhdr too short"); + exit(1); + } + + req->in = (void *)in_iov[in_num - 1].iov_base + + in_iov[in_num - 1].iov_len + - sizeof(struct virtio_blk_inhdr); + iov_discard_back(in_iov, &in_num, sizeof(struct virtio_blk_inhdr)); type = ldl_p(&req->out.type); |