Revision f141eafe block-qcow.c

b/block-qcow.c
525 525
typedef struct QCowAIOCB {
526 526
    BlockDriverAIOCB common;
527 527
    int64_t sector_num;
528
    QEMUIOVector *qiov;
528 529
    uint8_t *buf;
530
    void *orig_buf;
529 531
    int nb_sectors;
530 532
    int n;
531 533
    uint64_t cluster_offset;
......
543 545
    int index_in_cluster;
544 546

  
545 547
    acb->hd_aiocb = NULL;
546
    if (ret < 0) {
547
    fail:
548
        acb->common.cb(acb->common.opaque, ret);
549
        qemu_aio_release(acb);
550
        return;
551
    }
548
    if (ret < 0)
549
        goto done;
552 550

  
553 551
 redo:
554 552
    /* post process the read buffer */
......
570 568

  
571 569
    if (acb->nb_sectors == 0) {
572 570
        /* request completed */
573
        acb->common.cb(acb->common.opaque, 0);
574
        qemu_aio_release(acb);
575
        return;
571
        ret = 0;
572
        goto done;
576 573
    }
577 574

  
578 575
    /* prepare next AIO request */
......
592 589
            acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num,
593 590
                &acb->hd_qiov, acb->n, qcow_aio_read_cb, acb);
594 591
            if (acb->hd_aiocb == NULL)
595
                goto fail;
592
                goto done;
596 593
        } else {
597 594
            /* Note: in this case, no need to wait */
598 595
            memset(acb->buf, 0, 512 * acb->n);
......
601 598
    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
602 599
        /* add AIO support for compressed blocks ? */
603 600
        if (decompress_cluster(s, acb->cluster_offset) < 0)
604
            goto fail;
601
            goto done;
605 602
        memcpy(acb->buf,
606 603
               s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
607 604
        goto redo;
608 605
    } else {
609 606
        if ((acb->cluster_offset & 511) != 0) {
610 607
            ret = -EIO;
611
            goto fail;
608
            goto done;
612 609
        }
613 610
        acb->hd_iov.iov_base = acb->buf;
614 611
        acb->hd_iov.iov_len = acb->n * 512;
......
617 614
                            (acb->cluster_offset >> 9) + index_in_cluster,
618 615
                            &acb->hd_qiov, acb->n, qcow_aio_read_cb, acb);
619 616
        if (acb->hd_aiocb == NULL)
620
            goto fail;
617
            goto done;
618
    }
619

  
620
    return;
621

  
622
done:
623
    if (acb->qiov->niov > 1) {
624
        qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
625
        qemu_vfree(acb->orig_buf);
621 626
    }
627
    acb->common.cb(acb->common.opaque, ret);
628
    qemu_aio_release(acb);
622 629
}
623 630

  
624
static BlockDriverAIOCB *qcow_aio_read(BlockDriverState *bs,
625
        int64_t sector_num, uint8_t *buf, int nb_sectors,
631
static BlockDriverAIOCB *qcow_aio_readv(BlockDriverState *bs,
632
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
626 633
        BlockDriverCompletionFunc *cb, void *opaque)
627 634
{
628 635
    QCowAIOCB *acb;
......
632 639
        return NULL;
633 640
    acb->hd_aiocb = NULL;
634 641
    acb->sector_num = sector_num;
635
    acb->buf = buf;
642
    acb->qiov = qiov;
643
    if (qiov->niov > 1)
644
        acb->buf = acb->orig_buf = qemu_memalign(512, qiov->size);
645
    else
646
        acb->buf = qiov->iov->iov_base;
636 647
    acb->nb_sectors = nb_sectors;
637 648
    acb->n = 0;
638 649
    acb->cluster_offset = 0;
......
652 663

  
653 664
    acb->hd_aiocb = NULL;
654 665

  
655
    if (ret < 0) {
656
    fail:
657
        acb->common.cb(acb->common.opaque, ret);
658
        qemu_aio_release(acb);
659
        return;
660
    }
666
    if (ret < 0)
667
        goto done;
661 668

  
662 669
    acb->nb_sectors -= acb->n;
663 670
    acb->sector_num += acb->n;
......
665 672

  
666 673
    if (acb->nb_sectors == 0) {
667 674
        /* request completed */
668
        acb->common.cb(acb->common.opaque, 0);
669
        qemu_aio_release(acb);
670
        return;
675
        ret = 0;
676
        goto done;
671 677
    }
672 678

  
673 679
    index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
......
679 685
                                        index_in_cluster + acb->n);
680 686
    if (!cluster_offset || (cluster_offset & 511) != 0) {
681 687
        ret = -EIO;
682
        goto fail;
688
        goto done;
683 689
    }
684 690
    if (s->crypt_method) {
685 691
        if (!acb->cluster_data) {
686 692
            acb->cluster_data = qemu_mallocz(s->cluster_size);
687 693
            if (!acb->cluster_data) {
688 694
                ret = -ENOMEM;
689
                goto fail;
695
                goto done;
690 696
            }
691 697
        }
692 698
        encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
......
704 710
                                    &acb->hd_qiov, acb->n,
705 711
                                    qcow_aio_write_cb, acb);
706 712
    if (acb->hd_aiocb == NULL)
707
        goto fail;
713
        goto done;
714
    return;
715

  
716
done:
717
    if (acb->qiov->niov > 1)
718
        qemu_vfree(acb->orig_buf);
719
    acb->common.cb(acb->common.opaque, ret);
720
    qemu_aio_release(acb);
708 721
}
709 722

  
710
static BlockDriverAIOCB *qcow_aio_write(BlockDriverState *bs,
711
        int64_t sector_num, const uint8_t *buf, int nb_sectors,
723
static BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs,
724
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
712 725
        BlockDriverCompletionFunc *cb, void *opaque)
713 726
{
714 727
    BDRVQcowState *s = bs->opaque;
......
721 734
        return NULL;
722 735
    acb->hd_aiocb = NULL;
723 736
    acb->sector_num = sector_num;
724
    acb->buf = (uint8_t *)buf;
737
    acb->qiov = qiov;
738
    if (qiov->niov > 1) {
739
        acb->buf = acb->orig_buf = qemu_memalign(512, qiov->size);
740
        qemu_iovec_to_buffer(qiov, acb->buf);
741
    } else
742
        acb->buf = qiov->iov->iov_base;
725 743
    acb->nb_sectors = nb_sectors;
726 744
    acb->n = 0;
727 745

  
......
909 927
    .bdrv_is_allocated	= qcow_is_allocated,
910 928
    .bdrv_set_key	= qcow_set_key,
911 929
    .bdrv_make_empty	= qcow_make_empty,
912
    .bdrv_aio_read	= qcow_aio_read,
913
    .bdrv_aio_write	= qcow_aio_write,
930
    .bdrv_aio_readv	= qcow_aio_readv,
931
    .bdrv_aio_writev	= qcow_aio_writev,
914 932
    .bdrv_aio_cancel	= qcow_aio_cancel,
915 933
    .aiocb_size		= sizeof(QCowAIOCB),
916 934
    .bdrv_write_compressed = qcow_write_compressed,

Also available in: Unified diff