diff options
author | Kevin Wolf <kwolf@redhat.com> | 2016-06-01 16:55:05 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2016-06-16 15:19:55 +0200 |
commit | d46a0bb24d6061c1eadcf1136fa73dc7c4ac267d (patch) | |
tree | c6bd837ba2b8b703a714c898838efa0c25340c4f | |
parent | 8556739355d2a5392334c237486e32bd0f24c227 (diff) | |
download | qemu-d46a0bb24d6061c1eadcf1136fa73dc7c4ac267d.zip qemu-d46a0bb24d6061c1eadcf1136fa73dc7c4ac267d.tar.gz qemu-d46a0bb24d6061c1eadcf1136fa73dc7c4ac267d.tar.bz2 |
qcow2: Implement .bdrv_co_pwritev()
This changes qcow2 to implement the byte-based .bdrv_co_pwritev
interface rather than the sector-based old one.
As preallocation uses the same allocation function as normal writes, and
the interface of that function needs to be changed, it is converted in
the same patch.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
-rw-r--r-- | block/qcow2-cluster.c | 13 | ||||
-rw-r--r-- | block/qcow2.c | 89 | ||||
-rw-r--r-- | block/qcow2.h | 3 | ||||
-rw-r--r-- | trace-events | 6 |
4 files changed, 52 insertions, 59 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index b24230b..893ddf6 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1265,7 +1265,8 @@ fail: * Return 0 on success and -errno in error cases */ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, - int *num, uint64_t *host_offset, QCowL2Meta **m) + unsigned int *bytes, uint64_t *host_offset, + QCowL2Meta **m) { BDRVQcow2State *s = bs->opaque; uint64_t start, remaining; @@ -1273,13 +1274,11 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, uint64_t cur_bytes; int ret; - trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, *num); - - assert((offset & ~BDRV_SECTOR_MASK) == 0); + trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, *bytes); again: start = offset; - remaining = (uint64_t)*num << BDRV_SECTOR_BITS; + remaining = *bytes; cluster_offset = 0; *host_offset = 0; cur_bytes = 0; @@ -1365,8 +1364,8 @@ again: } } - *num -= remaining >> BDRV_SECTOR_BITS; - assert(*num > 0); + *bytes -= remaining; + assert(*bytes > 0); assert(*host_offset != 0); return 0; diff --git a/block/qcow2.c b/block/qcow2.c index 545dea0..cb55e2d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1544,23 +1544,21 @@ fail: return ret; } -static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, - int64_t sector_num, - int remaining_sectors, - QEMUIOVector *qiov) +static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset, + uint64_t bytes, QEMUIOVector *qiov, + int flags) { BDRVQcow2State *s = bs->opaque; - int index_in_cluster; + int offset_in_cluster; int ret; - int cur_nr_sectors; /* number of sectors in current iteration */ + unsigned int cur_bytes; /* number of sectors in current iteration */ uint64_t cluster_offset; QEMUIOVector hd_qiov; uint64_t bytes_done = 0; uint8_t *cluster_data = NULL; QCowL2Meta *l2meta = NULL; - trace_qcow2_writev_start_req(qemu_coroutine_self(), sector_num, - remaining_sectors); + trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes); qemu_iovec_init(&hd_qiov, qiov->niov); @@ -1568,22 +1566,21 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, qemu_co_mutex_lock(&s->lock); - while (remaining_sectors != 0) { + while (bytes != 0) { l2meta = NULL; trace_qcow2_writev_start_part(qemu_coroutine_self()); - index_in_cluster = sector_num & (s->cluster_sectors - 1); - cur_nr_sectors = remaining_sectors; - if (bs->encrypted && - cur_nr_sectors > - QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors - index_in_cluster) { - cur_nr_sectors = - QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors - index_in_cluster; + offset_in_cluster = offset_into_cluster(s, offset); + cur_bytes = MIN(bytes, INT_MAX); + if (bs->encrypted) { + cur_bytes = MIN(cur_bytes, + QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size + - offset_in_cluster); } - ret = qcow2_alloc_cluster_offset(bs, sector_num << 9, - &cur_nr_sectors, &cluster_offset, &l2meta); + ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes, + &cluster_offset, &l2meta); if (ret < 0) { goto fail; } @@ -1591,8 +1588,7 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, assert((cluster_offset & 511) == 0); qemu_iovec_reset(&hd_qiov); - qemu_iovec_concat(&hd_qiov, qiov, bytes_done, - cur_nr_sectors * 512); + qemu_iovec_concat(&hd_qiov, qiov, bytes_done, cur_bytes); if (bs->encrypted) { Error *err = NULL; @@ -1611,8 +1607,9 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size); - if (qcow2_encrypt_sectors(s, sector_num, cluster_data, - cluster_data, cur_nr_sectors, + if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS, + cluster_data, cluster_data, + cur_bytes >>BDRV_SECTOR_BITS, true, &err) < 0) { error_free(err); ret = -EIO; @@ -1620,13 +1617,11 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, } qemu_iovec_reset(&hd_qiov); - qemu_iovec_add(&hd_qiov, cluster_data, - cur_nr_sectors * 512); + qemu_iovec_add(&hd_qiov, cluster_data, cur_bytes); } ret = qcow2_pre_write_overlap_check(bs, 0, - cluster_offset + index_in_cluster * BDRV_SECTOR_SIZE, - cur_nr_sectors * BDRV_SECTOR_SIZE); + cluster_offset + offset_in_cluster, cur_bytes); if (ret < 0) { goto fail; } @@ -1634,10 +1629,10 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, qemu_co_mutex_unlock(&s->lock); BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); trace_qcow2_writev_data(qemu_coroutine_self(), - (cluster_offset >> 9) + index_in_cluster); - ret = bdrv_co_writev(bs->file->bs, - (cluster_offset >> 9) + index_in_cluster, - cur_nr_sectors, &hd_qiov); + cluster_offset + offset_in_cluster); + ret = bdrv_co_pwritev(bs->file->bs, + cluster_offset + offset_in_cluster, + cur_bytes, &hd_qiov, 0); qemu_co_mutex_lock(&s->lock); if (ret < 0) { goto fail; @@ -1663,10 +1658,10 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, l2meta = next; } - remaining_sectors -= cur_nr_sectors; - sector_num += cur_nr_sectors; - bytes_done += cur_nr_sectors * 512; - trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_nr_sectors); + bytes -= cur_bytes; + offset += cur_bytes; + bytes_done += cur_bytes; + trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_bytes); } ret = 0; @@ -2008,19 +2003,19 @@ static int qcow2_change_backing_file(BlockDriverState *bs, static int preallocate(BlockDriverState *bs) { - uint64_t nb_sectors; + uint64_t bytes; uint64_t offset; uint64_t host_offset = 0; - int num; + unsigned int cur_bytes; int ret; QCowL2Meta *meta; - nb_sectors = bdrv_nb_sectors(bs); + bytes = bdrv_getlength(bs); offset = 0; - while (nb_sectors) { - num = MIN(nb_sectors, INT_MAX >> BDRV_SECTOR_BITS); - ret = qcow2_alloc_cluster_offset(bs, offset, &num, + while (bytes) { + cur_bytes = MIN(bytes, INT_MAX); + ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes, &host_offset, &meta); if (ret < 0) { return ret; @@ -2046,8 +2041,8 @@ static int preallocate(BlockDriverState *bs) /* TODO Preallocate data if requested */ - nb_sectors -= num; - offset += num << BDRV_SECTOR_BITS; + bytes -= cur_bytes; + offset += cur_bytes; } /* @@ -2056,11 +2051,9 @@ static int preallocate(BlockDriverState *bs) * EOF). Extend the image to the last allocated sector. */ if (host_offset != 0) { - uint8_t buf[BDRV_SECTOR_SIZE]; - memset(buf, 0, BDRV_SECTOR_SIZE); - ret = bdrv_write(bs->file->bs, - (host_offset >> BDRV_SECTOR_BITS) + num - 1, - buf, 1); + uint8_t data = 0; + ret = bdrv_pwrite(bs->file->bs, (host_offset + cur_bytes) - 1, + &data, 1); if (ret < 0) { return ret; } @@ -3379,7 +3372,7 @@ BlockDriver bdrv_qcow2 = { .bdrv_set_key = qcow2_set_key, .bdrv_co_preadv = qcow2_co_preadv, - .bdrv_co_writev = qcow2_co_writev, + .bdrv_co_pwritev = qcow2_co_pwritev, .bdrv_co_flush_to_os = qcow2_co_flush_to_os, .bdrv_co_pwrite_zeroes = qcow2_co_pwrite_zeroes, diff --git a/block/qcow2.h b/block/qcow2.h index 175b0c1..b36a7bf 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -539,7 +539,8 @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, unsigned int *bytes, uint64_t *cluster_offset); int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, - int *num, uint64_t *host_offset, QCowL2Meta **m); + unsigned int *bytes, uint64_t *host_offset, + QCowL2Meta **m); uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, uint64_t offset, int compressed_size); diff --git a/trace-events b/trace-events index 2f14205..720c644 100644 --- a/trace-events +++ b/trace-events @@ -606,16 +606,16 @@ qemu_system_shutdown_request(void) "" qemu_system_powerdown_request(void) "" # block/qcow2.c -qcow2_writev_start_req(void *co, int64_t sector, int nb_sectors) "co %p sector %" PRIx64 " nb_sectors %d" +qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset %" PRIx64 " bytes %d" qcow2_writev_done_req(void *co, int ret) "co %p ret %d" qcow2_writev_start_part(void *co) "co %p" -qcow2_writev_done_part(void *co, int cur_nr_sectors) "co %p cur_nr_sectors %d" +qcow2_writev_done_part(void *co, int cur_bytes) "co %p cur_bytes %d" qcow2_writev_data(void *co, uint64_t offset) "co %p offset %" PRIx64 qcow2_pwrite_zeroes_start_req(void *co, int64_t offset, int count) "co %p offset %" PRIx64 " count %d" qcow2_pwrite_zeroes(void *co, int64_t offset, int count) "co %p offset %" PRIx64 " count %d" # block/qcow2-cluster.c -qcow2_alloc_clusters_offset(void *co, uint64_t offset, int num) "co %p offset %" PRIx64 " num %d" +qcow2_alloc_clusters_offset(void *co, uint64_t offset, int bytes) "co %p offset %" PRIx64 " bytes %d" qcow2_handle_copied(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64 qcow2_handle_alloc(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64 qcow2_do_alloc_clusters_offset(void *co, uint64_t guest_offset, uint64_t host_offset, int nb_clusters) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " nb_clusters %d" |