Revision 018faafd block/qcow2-refcount.c

b/block/qcow2-refcount.c
105 105
    return 0;
106 106
}
107 107

  
108
/*
109
 * Returns the refcount of the cluster given by its index. Any non-negative
110
 * return value is the refcount of the cluster, negative values are -errno
111
 * and indicate an error.
112
 */
108 113
static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
109 114
{
110 115
    BDRVQcowState *s = bs->opaque;
111 116
    int refcount_table_index, block_index;
112 117
    int64_t refcount_block_offset;
118
    int ret;
113 119

  
114 120
    refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
115 121
    if (refcount_table_index >= s->refcount_table_size)
......
119 125
        return 0;
120 126
    if (refcount_block_offset != s->refcount_block_cache_offset) {
121 127
        /* better than nothing: return allocated if read error */
122
        if (load_refcount_block(bs, refcount_block_offset) < 0)
123
            return 1;
128
        ret = load_refcount_block(bs, refcount_block_offset);
129
        if (ret < 0) {
130
            return ret;
131
        }
124 132
    }
125 133
    block_index = cluster_index &
126 134
        ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
......
538 546
    return ret;
539 547
}
540 548

  
541
/* addend must be 1 or -1 */
549
/*
550
 * Increases or decreases the refcount of a given cluster by one.
551
 * addend must be 1 or -1.
552
 *
553
 * If the return value is non-negative, it is the new refcount of the cluster.
554
 * If it is negative, it is -errno and indicates an error.
555
 */
542 556
static int update_cluster_refcount(BlockDriverState *bs,
543 557
                                   int64_t cluster_index,
544 558
                                   int addend)
......
779 793
                        } else {
780 794
                            refcount = get_refcount(bs, offset >> s->cluster_bits);
781 795
                        }
796

  
797
                        if (refcount < 0) {
798
                            goto fail;
799
                        }
782 800
                    }
783 801

  
784 802
                    if (refcount == 1) {
......
801 819
            } else {
802 820
                refcount = get_refcount(bs, l2_offset >> s->cluster_bits);
803 821
            }
804
            if (refcount == 1) {
822
            if (refcount < 0) {
823
                goto fail;
824
            } else if (refcount == 1) {
805 825
                l2_offset |= QCOW_OFLAG_COPIED;
806 826
            }
807 827
            if (l2_offset != old_l2_offset) {
......
934 954
                    uint64_t entry = offset;
935 955
                    offset &= ~QCOW_OFLAG_COPIED;
936 956
                    refcount = get_refcount(bs, offset >> s->cluster_bits);
957
                    if (refcount < 0) {
958
                        fprintf(stderr, "Can't get refcount for offset %"
959
                            PRIx64 ": %s\n", entry, strerror(-refcount));
960
                    }
937 961
                    if ((refcount == 1) != ((entry & QCOW_OFLAG_COPIED) != 0)) {
938 962
                        fprintf(stderr, "ERROR OFLAG_COPIED: offset=%"
939 963
                            PRIx64 " refcount=%d\n", entry, refcount);
......
1011 1035
            if (check_copied) {
1012 1036
                refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED)
1013 1037
                    >> s->cluster_bits);
1038
                if (refcount < 0) {
1039
                    fprintf(stderr, "Can't get refcount for l2_offset %"
1040
                        PRIx64 ": %s\n", l2_offset, strerror(-refcount));
1041
                }
1014 1042
                if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) {
1015 1043
                    fprintf(stderr, "ERROR OFLAG_COPIED: l2_offset=%" PRIx64
1016 1044
                        " refcount=%d\n", l2_offset, refcount);
......
1118 1146
    /* compare ref counts */
1119 1147
    for(i = 0; i < nb_clusters; i++) {
1120 1148
        refcount1 = get_refcount(bs, i);
1149
        if (refcount1 < 0) {
1150
            fprintf(stderr, "Can't get refcount for cluster %d: %s\n",
1151
                i, strerror(-refcount1));
1152
        }
1153

  
1121 1154
        refcount2 = refcount_table[i];
1122 1155
        if (refcount1 != refcount2) {
1123 1156
            fprintf(stderr, "ERROR cluster %d refcount=%d reference=%d\n",

Also available in: Unified diff