Revision 93913dfd block/qcow2-refcount.c
b/block/qcow2-refcount.c | ||
---|---|---|
705 | 705 |
BDRVQcowState *s = bs->opaque; |
706 | 706 |
uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated; |
707 | 707 |
int64_t old_offset, old_l2_offset; |
708 |
int i, j, l1_modified, nb_csectors, refcount; |
|
708 |
int i, j, l1_modified = 0, nb_csectors, refcount;
|
|
709 | 709 |
int ret; |
710 |
bool old_l2_writethrough, old_refcount_writethrough; |
|
711 |
|
|
712 |
/* Switch caches to writeback mode during update */ |
|
713 |
old_l2_writethrough = |
|
714 |
qcow2_cache_set_writethrough(bs, s->l2_table_cache, false); |
|
715 |
old_refcount_writethrough = |
|
716 |
qcow2_cache_set_writethrough(bs, s->refcount_block_cache, false); |
|
710 | 717 |
|
711 | 718 |
l2_table = NULL; |
712 | 719 |
l1_table = NULL; |
... | ... | |
720 | 727 |
l1_allocated = 1; |
721 | 728 |
if (bdrv_pread(bs->file, l1_table_offset, |
722 | 729 |
l1_table, l1_size2) != l1_size2) |
730 |
{ |
|
731 |
ret = -EIO; |
|
723 | 732 |
goto fail; |
733 |
} |
|
734 |
|
|
724 | 735 |
for(i = 0;i < l1_size; i++) |
725 | 736 |
be64_to_cpus(&l1_table[i]); |
726 | 737 |
} else { |
... | ... | |
729 | 740 |
l1_allocated = 0; |
730 | 741 |
} |
731 | 742 |
|
732 |
l1_modified = 0; |
|
733 | 743 |
for(i = 0; i < l1_size; i++) { |
734 | 744 |
l2_offset = l1_table[i]; |
735 | 745 |
if (l2_offset) { |
... | ... | |
773 | 783 |
} |
774 | 784 |
|
775 | 785 |
if (refcount < 0) { |
786 |
ret = -EIO; |
|
776 | 787 |
goto fail; |
777 | 788 |
} |
778 | 789 |
} |
... | ... | |
803 | 814 |
refcount = get_refcount(bs, l2_offset >> s->cluster_bits); |
804 | 815 |
} |
805 | 816 |
if (refcount < 0) { |
817 |
ret = -EIO; |
|
806 | 818 |
goto fail; |
807 | 819 |
} else if (refcount == 1) { |
808 | 820 |
l2_offset |= QCOW_OFLAG_COPIED; |
... | ... | |
813 | 825 |
} |
814 | 826 |
} |
815 | 827 |
} |
828 |
|
|
829 |
ret = 0; |
|
830 |
fail: |
|
831 |
if (l2_table) { |
|
832 |
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); |
|
833 |
} |
|
834 |
|
|
835 |
/* Enable writethrough cache mode again */ |
|
836 |
qcow2_cache_set_writethrough(bs, s->l2_table_cache, old_l2_writethrough); |
|
837 |
qcow2_cache_set_writethrough(bs, s->refcount_block_cache, |
|
838 |
old_refcount_writethrough); |
|
839 |
|
|
816 | 840 |
if (l1_modified) { |
817 | 841 |
for(i = 0; i < l1_size; i++) |
818 | 842 |
cpu_to_be64s(&l1_table[i]); |
... | ... | |
824 | 848 |
} |
825 | 849 |
if (l1_allocated) |
826 | 850 |
qemu_free(l1_table); |
827 |
return 0; |
|
828 |
fail: |
|
829 |
if (l2_table) { |
|
830 |
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); |
|
831 |
} |
|
832 |
|
|
833 |
if (l1_allocated) |
|
834 |
qemu_free(l1_table); |
|
835 |
return -EIO; |
|
851 |
return ret; |
|
836 | 852 |
} |
837 | 853 |
|
838 | 854 |
|
Also available in: Unified diff