Revision 72ecf02d block/qcow2.c
b/block/qcow2.c | ||
---|---|---|
934 | 934 |
return 0; |
935 | 935 |
} |
936 | 936 |
|
937 |
static int qcow2_write(BlockDriverState *bs, int64_t sector_num, |
|
938 |
const uint8_t *buf, int nb_sectors) |
|
939 |
{ |
|
940 |
BDRVQcowState *s = bs->opaque; |
|
941 |
int ret, index_in_cluster, n; |
|
942 |
uint64_t cluster_offset; |
|
943 |
int n_end; |
|
944 |
QCowL2Meta l2meta; |
|
945 |
|
|
946 |
while (nb_sectors > 0) { |
|
947 |
memset(&l2meta, 0, sizeof(l2meta)); |
|
948 |
|
|
949 |
index_in_cluster = sector_num & (s->cluster_sectors - 1); |
|
950 |
n_end = index_in_cluster + nb_sectors; |
|
951 |
if (s->crypt_method && |
|
952 |
n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) |
|
953 |
n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; |
|
954 |
cluster_offset = qcow2_alloc_cluster_offset(bs, sector_num << 9, |
|
955 |
index_in_cluster, |
|
956 |
n_end, &n, &l2meta); |
|
957 |
if (!cluster_offset) |
|
958 |
return -1; |
|
959 |
if (s->crypt_method) { |
|
960 |
qcow2_encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1, |
|
961 |
&s->aes_encrypt_key); |
|
962 |
ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, |
|
963 |
s->cluster_data, n * 512); |
|
964 |
} else { |
|
965 |
ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512); |
|
966 |
} |
|
967 |
if (ret != n * 512 || qcow2_alloc_cluster_link_l2(bs, cluster_offset, &l2meta) < 0) { |
|
968 |
qcow2_free_any_clusters(bs, cluster_offset, l2meta.nb_clusters); |
|
969 |
return -1; |
|
970 |
} |
|
971 |
nb_sectors -= n; |
|
972 |
sector_num += n; |
|
973 |
buf += n * 512; |
|
974 |
if (l2meta.nb_clusters != 0) { |
|
975 |
QLIST_REMOVE(&l2meta, next_in_flight); |
|
976 |
} |
|
977 |
} |
|
978 |
s->cluster_cache_offset = -1; /* disable compressed cache */ |
|
979 |
return 0; |
|
980 |
} |
|
981 |
|
|
982 | 937 |
/* XXX: put compressed sectors first, then all the cluster aligned |
983 | 938 |
tables to avoid losing bytes in alignment */ |
984 | 939 |
static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num, |
... | ... | |
1166 | 1121 |
.bdrv_set_key = qcow_set_key, |
1167 | 1122 |
.bdrv_make_empty = qcow_make_empty, |
1168 | 1123 |
|
1169 |
.bdrv_read = qcow2_read, |
|
1170 |
.bdrv_write = qcow2_write, |
|
1171 |
.bdrv_aio_readv = qcow_aio_readv, |
|
1172 |
.bdrv_aio_writev = qcow_aio_writev, |
|
1124 |
.bdrv_aio_readv = qcow_aio_readv, |
|
1125 |
.bdrv_aio_writev = qcow_aio_writev, |
|
1173 | 1126 |
.bdrv_write_compressed = qcow_write_compressed, |
1174 | 1127 |
|
1175 | 1128 |
.bdrv_snapshot_create = qcow2_snapshot_create, |
Also available in: Unified diff