Revision 363c3c85

b/block/curl.c
47 47

  
48 48
typedef struct CURLAIOCB {
49 49
    BlockDriverAIOCB common;
50
    QEMUBH *bh;
50 51
    QEMUIOVector *qiov;
52

  
53
    int64_t sector_num;
54
    int nb_sectors;
55

  
51 56
    size_t start;
52 57
    size_t end;
53 58
} CURLAIOCB;
......
440 445
    .cancel             = curl_aio_cancel,
441 446
};
442 447

  
443
static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
444
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
445
        BlockDriverCompletionFunc *cb, void *opaque)
448

  
449
static void curl_readv_bh_cb(void *p)
446 450
{
447
    BDRVCURLState *s = bs->opaque;
448
    CURLAIOCB *acb;
449
    size_t start = sector_num * SECTOR_SIZE;
450
    size_t end;
451 451
    CURLState *state;
452 452

  
453
    acb = qemu_aio_get(&curl_aio_pool, bs, cb, opaque);
454
    if (!acb)
455
        return NULL;
453
    CURLAIOCB *acb = p;
454
    BDRVCURLState *s = acb->common.bs->opaque;
456 455

  
457
    acb->qiov = qiov;
456
    qemu_bh_delete(acb->bh);
457
    acb->bh = NULL;
458

  
459
    size_t start = acb->sector_num * SECTOR_SIZE;
460
    size_t end;
458 461

  
459 462
    // In case we have the requested data already (e.g. read-ahead),
460 463
    // we can just call the callback and be done.
461

  
462
    switch (curl_find_buf(s, start, nb_sectors * SECTOR_SIZE, acb)) {
464
    switch (curl_find_buf(s, start, acb->nb_sectors * SECTOR_SIZE, acb)) {
463 465
        case FIND_RET_OK:
464 466
            qemu_aio_release(acb);
465 467
            // fall through
466 468
        case FIND_RET_WAIT:
467
            return &acb->common;
469
            return;
468 470
        default:
469 471
            break;
470 472
    }
471 473

  
472 474
    // No cache found, so let's start a new request
473

  
474 475
    state = curl_init_state(s);
475
    if (!state)
476
        return NULL;
476
    if (!state) {
477
        acb->common.cb(acb->common.opaque, -EIO);
478
        qemu_aio_release(acb);
479
        return;
480
    }
477 481

  
478 482
    acb->start = 0;
479
    acb->end = (nb_sectors * SECTOR_SIZE);
483
    acb->end = (acb->nb_sectors * SECTOR_SIZE);
480 484

  
481 485
    state->buf_off = 0;
482 486
    if (state->orig_buf)
......
489 493

  
490 494
    snprintf(state->range, 127, "%zd-%zd", start, end);
491 495
    DPRINTF("CURL (AIO): Reading %d at %zd (%s)\n",
492
            (nb_sectors * SECTOR_SIZE), start, state->range);
496
            (acb->nb_sectors * SECTOR_SIZE), start, state->range);
493 497
    curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
494 498

  
495 499
    curl_multi_add_handle(s->multi, state->curl);
496 500
    curl_multi_do(s);
497 501

  
502
}
503

  
504
static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
505
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
506
        BlockDriverCompletionFunc *cb, void *opaque)
507
{
508
    CURLAIOCB *acb;
509

  
510
    acb = qemu_aio_get(&curl_aio_pool, bs, cb, opaque);
511

  
512
    if (!acb) {
513
        return NULL;
514
    }
515

  
516
    acb->qiov = qiov;
517
    acb->sector_num = sector_num;
518
    acb->nb_sectors = nb_sectors;
519

  
520
    acb->bh = qemu_bh_new(curl_readv_bh_cb, acb);
521

  
522
    if (!acb->bh) {
523
        DPRINTF("CURL: qemu_bh_new failed\n");
524
        return NULL;
525
    }
526

  
527
    qemu_bh_schedule(acb->bh);
498 528
    return &acb->common;
499 529
}
500 530

  

Also available in: Unified diff