Commit d28a1b6ec6e6d7d03ed72852ea04190feb2a7638

Authored by aliguori
1 parent 522584a5

virtio-blk: use generic vectored I/O APIs (Christoph Hellwig)


Use the generic bdrv_aio_readv/bdrv_aio_writev APIs instead of linearizing
buffers directly.  This enables using the future native preadv/pwritev
support.


Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6903 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 17 additions and 71 deletions
hw/virtio-blk.c
@@ -35,8 +35,7 @@ typedef struct VirtIOBlockReq @@ -35,8 +35,7 @@ typedef struct VirtIOBlockReq
35 VirtQueueElement elem; 35 VirtQueueElement elem;
36 struct virtio_blk_inhdr *in; 36 struct virtio_blk_inhdr *in;
37 struct virtio_blk_outhdr *out; 37 struct virtio_blk_outhdr *out;
38 - size_t size;  
39 - uint8_t *buffer; 38 + QEMUIOVector qiov;
40 struct VirtIOBlockReq *next; 39 struct VirtIOBlockReq *next;
41 } VirtIOBlockReq; 40 } VirtIOBlockReq;
42 41
@@ -45,10 +44,9 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) @@ -45,10 +44,9 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
45 VirtIOBlock *s = req->dev; 44 VirtIOBlock *s = req->dev;
46 45
47 req->in->status = status; 46 req->in->status = status;
48 - virtqueue_push(s->vq, &req->elem, req->size + sizeof(*req->in)); 47 + virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
49 virtio_notify(&s->vdev, s->vq); 48 virtio_notify(&s->vdev, s->vq);
50 49
51 - qemu_free(req->buffer);  
52 qemu_free(req); 50 qemu_free(req);
53 } 51 }
54 52
@@ -76,24 +74,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret) @@ -76,24 +74,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
76 { 74 {
77 VirtIOBlockReq *req = opaque; 75 VirtIOBlockReq *req = opaque;
78 76
79 - /* Copy read data to the guest */  
80 - if (!ret && !(req->out->type & VIRTIO_BLK_T_OUT)) {  
81 - size_t offset = 0;  
82 - int i;  
83 -  
84 - for (i = 0; i < req->elem.in_num - 1; i++) {  
85 - size_t len;  
86 -  
87 - /* Be pretty defensive wrt malicious guests */  
88 - len = MIN(req->elem.in_sg[i].iov_len,  
89 - req->size - offset);  
90 -  
91 - memcpy(req->elem.in_sg[i].iov_base,  
92 - req->buffer + offset,  
93 - len);  
94 - offset += len;  
95 - }  
96 - } else if (ret && (req->out->type & VIRTIO_BLK_T_OUT)) { 77 + if (ret && (req->out->type & VIRTIO_BLK_T_OUT)) {
97 if (virtio_blk_handle_write_error(req, -ret)) 78 if (virtio_blk_handle_write_error(req, -ret))
98 return; 79 return;
99 } 80 }
@@ -122,39 +103,16 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s) @@ -122,39 +103,16 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
122 return req; 103 return req;
123 } 104 }
124 105
125 -static int virtio_blk_handle_write(VirtIOBlockReq *req) 106 +static void virtio_blk_handle_write(VirtIOBlockReq *req)
126 { 107 {
127 - if (!req->buffer) {  
128 - size_t offset = 0;  
129 - int i;  
130 -  
131 - for (i = 1; i < req->elem.out_num; i++)  
132 - req->size += req->elem.out_sg[i].iov_len;  
133 -  
134 - req->buffer = qemu_memalign(512, req->size);  
135 - if (req->buffer == NULL) {  
136 - qemu_free(req);  
137 - return -1;  
138 - }  
139 -  
140 - /* We copy the data from the SG list to avoid splitting up the request.  
141 - This helps performance a lot until we can pass full sg lists as AIO  
142 - operations */  
143 - for (i = 1; i < req->elem.out_num; i++) {  
144 - size_t len;  
145 -  
146 - len = MIN(req->elem.out_sg[i].iov_len,  
147 - req->size - offset);  
148 - memcpy(req->buffer + offset,  
149 - req->elem.out_sg[i].iov_base,  
150 - len);  
151 - offset += len;  
152 - }  
153 - } 108 + bdrv_aio_writev(req->dev->bs, req->out->sector, &req->qiov,
  109 + req->qiov.size / 512, virtio_blk_rw_complete, req);
  110 +}
154 111
155 - bdrv_aio_write(req->dev->bs, req->out->sector, req->buffer, req->size / 512,  
156 - virtio_blk_rw_complete, req);  
157 - return 0; 112 +static void virtio_blk_handle_read(VirtIOBlockReq *req)
  113 +{
  114 + bdrv_aio_readv(req->dev->bs, req->out->sector, &req->qiov,
  115 + req->qiov.size / 512, virtio_blk_rw_complete, req);
158 } 116 }
159 117
160 static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) 118 static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
@@ -163,8 +121,6 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) @@ -163,8 +121,6 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
163 VirtIOBlockReq *req; 121 VirtIOBlockReq *req;
164 122
165 while ((req = virtio_blk_get_request(s))) { 123 while ((req = virtio_blk_get_request(s))) {
166 - int i;  
167 -  
168 if (req->elem.out_num < 1 || req->elem.in_num < 1) { 124 if (req->elem.out_num < 1 || req->elem.in_num < 1) {
169 fprintf(stderr, "virtio-blk missing headers\n"); 125 fprintf(stderr, "virtio-blk missing headers\n");
170 exit(1); 126 exit(1);
@@ -187,23 +143,13 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) @@ -187,23 +143,13 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
187 virtio_notify(vdev, vq); 143 virtio_notify(vdev, vq);
188 qemu_free(req); 144 qemu_free(req);
189 } else if (req->out->type & VIRTIO_BLK_T_OUT) { 145 } else if (req->out->type & VIRTIO_BLK_T_OUT) {
190 - if (virtio_blk_handle_write(req) < 0)  
191 - break; 146 + qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
  147 + req->elem.out_num - 1);
  148 + virtio_blk_handle_write(req);
192 } else { 149 } else {
193 - for (i = 0; i < req->elem.in_num - 1; i++)  
194 - req->size += req->elem.in_sg[i].iov_len;  
195 -  
196 - req->buffer = qemu_memalign(512, req->size);  
197 - if (req->buffer == NULL) {  
198 - qemu_free(req);  
199 - break;  
200 - }  
201 -  
202 - bdrv_aio_read(s->bs, req->out->sector,  
203 - req->buffer,  
204 - req->size / 512,  
205 - virtio_blk_rw_complete,  
206 - req); 150 + qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0],
  151 + req->elem.in_num - 1);
  152 + virtio_blk_handle_read(req);
207 } 153 }
208 } 154 }
209 /* 155 /*