Revision f214978a block/qcow2-cluster.c

b/block/qcow2-cluster.c
684 684
    int l2_index, ret;
685 685
    uint64_t l2_offset, *l2_table, cluster_offset;
686 686
    int nb_clusters, i = 0;
687
    QCowL2Meta *old_alloc;
687 688

  
688 689
    ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
689 690
    if (ret == 0)
......
732 733
    }
733 734
    nb_clusters = i;
734 735

  
736
    /*
737
     * Check if there already is an AIO write request in flight which allocates
738
     * the same cluster. In this case we need to wait until the previous
739
     * request has completed and updated the L2 table accordingly.
740
     */
741
    LIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) {
742

  
743
        uint64_t end_offset = offset + nb_clusters * s->cluster_size;
744
        uint64_t old_offset = old_alloc->offset;
745
        uint64_t old_end_offset = old_alloc->offset +
746
            old_alloc->nb_clusters * s->cluster_size;
747

  
748
        if (end_offset < old_offset || offset > old_end_offset) {
749
            /* No intersection */
750
        } else {
751
            if (offset < old_offset) {
752
                /* Stop at the start of a running allocation */
753
                nb_clusters = (old_offset - offset) >> s->cluster_bits;
754
            } else {
755
                nb_clusters = 0;
756
            }
757

  
758
            if (nb_clusters == 0) {
759
                /* Set dependency and wait for a callback */
760
                m->depends_on = old_alloc;
761
                m->nb_clusters = 0;
762
                *num = 0;
763
                return 0;
764
            }
765
        }
766
    }
767

  
768
    if (!nb_clusters) {
769
        abort();
770
    }
771

  
772
    LIST_INSERT_HEAD(&s->cluster_allocs, m, next_in_flight);
773

  
735 774
    /* allocate a new cluster */
736 775

  
737 776
    cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size);

Also available in: Unified diff