Revision 91553dcc hw/virtio-blk.c

b/hw/virtio-blk.c
252 252
}
253 253
#endif /* __linux__ */
254 254

  
255
static void virtio_blk_handle_write(VirtIOBlockReq *req)
255
static void do_multiwrite(BlockDriverState *bs, BlockRequest *blkreq,
256
    int num_writes)
256 257
{
257
    BlockDriverAIOCB *acb;
258
    int i, ret;
259
    ret = bdrv_aio_multiwrite(bs, blkreq, num_writes);
260

  
261
    if (ret != 0) {
262
        for (i = 0; i < num_writes; i++) {
263
            if (blkreq[i].error) {
264
                virtio_blk_req_complete(blkreq[i].opaque, VIRTIO_BLK_S_IOERR);
265
            }
266
        }
267
    }
268
}
258 269

  
259
    acb = bdrv_aio_writev(req->dev->bs, req->out->sector, &req->qiov,
260
                          req->qiov.size / 512, virtio_blk_rw_complete, req);
261
    if (!acb) {
262
        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
270
static void virtio_blk_handle_write(BlockRequest *blkreq, int *num_writes,
271
    VirtIOBlockReq *req, BlockDriverState **old_bs)
272
{
273
    if (req->dev->bs != *old_bs || *num_writes == 32) {
274
        if (*old_bs != NULL) {
275
            do_multiwrite(*old_bs, blkreq, *num_writes);
276
        }
277
        *num_writes = 0;
278
        *old_bs = req->dev->bs;
263 279
    }
280

  
281
    blkreq[*num_writes].sector = req->out->sector;
282
    blkreq[*num_writes].nb_sectors = req->qiov.size / 512;
283
    blkreq[*num_writes].qiov = &req->qiov;
284
    blkreq[*num_writes].cb = virtio_blk_rw_complete;
285
    blkreq[*num_writes].opaque = req;
286
    blkreq[*num_writes].error = 0;
287

  
288
    (*num_writes)++;
264 289
}
265 290

  
266 291
static void virtio_blk_handle_read(VirtIOBlockReq *req)
......
278 303
{
279 304
    VirtIOBlock *s = to_virtio_blk(vdev);
280 305
    VirtIOBlockReq *req;
306
    BlockRequest blkreq[32];
307
    int num_writes = 0;
308
    BlockDriverState *old_bs = NULL;
281 309

  
282 310
    while ((req = virtio_blk_get_request(s))) {
283 311
        if (req->elem.out_num < 1 || req->elem.in_num < 1) {
......
299 327
        } else if (req->out->type & VIRTIO_BLK_T_OUT) {
300 328
            qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
301 329
                                     req->elem.out_num - 1);
302
            virtio_blk_handle_write(req);
330
            virtio_blk_handle_write(blkreq, &num_writes, req, &old_bs);
303 331
        } else {
304 332
            qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0],
305 333
                                     req->elem.in_num - 1);
306 334
            virtio_blk_handle_read(req);
307 335
        }
308 336
    }
337

  
338
    if (num_writes > 0) {
339
        do_multiwrite(old_bs, blkreq, num_writes);
340
    }
341

  
309 342
    /*
310 343
     * FIXME: Want to check for completions before returning to guest mode,
311 344
     * so cached reads and writes are reported as quickly as possible. But
......
324 357
    s->rq = NULL;
325 358

  
326 359
    while (req) {
327
        virtio_blk_handle_write(req);
360
        bdrv_aio_writev(req->dev->bs, req->out->sector, &req->qiov,
361
            req->qiov.size / 512, virtio_blk_rw_complete, req);
328 362
        req = req->next;
329 363
    }
330 364
}

Also available in: Unified diff