[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 22/61] qcow2: Pass a QEMUIOVector to do_perform_cow_{
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 22/61] qcow2: Pass a QEMUIOVector to do_perform_cow_{read, write}() |
Date: |
Fri, 23 Jun 2017 18:21:20 +0200 |
From: Alberto Garcia <address@hidden>
Instead of passing a single buffer pointer to do_perform_cow_write(),
pass a QEMUIOVector. This will allow us to merge the write requests
for the COW regions and the actual data into a single one.
Although do_perform_cow_read() does not strictly need to change its
API, we're doing it here as well for consistency.
Signed-off-by: Alberto Garcia <address@hidden>
Reviewed-by: Kevin Wolf <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block/qcow2-cluster.c | 51 ++++++++++++++++++++++++---------------------------
1 file changed, 24 insertions(+), 27 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 20fb531..3ac26d6 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -406,19 +406,14 @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t
sector_num,
static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
uint64_t src_cluster_offset,
unsigned offset_in_cluster,
- uint8_t *buffer,
- unsigned bytes)
+ QEMUIOVector *qiov)
{
- QEMUIOVector qiov;
- struct iovec iov = { .iov_base = buffer, .iov_len = bytes };
int ret;
- if (bytes == 0) {
+ if (qiov->size == 0) {
return 0;
}
- qemu_iovec_init_external(&qiov, &iov, 1);
-
BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);
if (!bs->drv) {
@@ -430,7 +425,7 @@ static int coroutine_fn
do_perform_cow_read(BlockDriverState *bs,
* which can lead to deadlock when block layer copy-on-read is enabled.
*/
ret = bs->drv->bdrv_co_preadv(bs, src_cluster_offset + offset_in_cluster,
- bytes, &qiov, 0);
+ qiov->size, qiov, 0);
if (ret < 0) {
return ret;
}
@@ -462,28 +457,23 @@ static bool coroutine_fn
do_perform_cow_encrypt(BlockDriverState *bs,
static int coroutine_fn do_perform_cow_write(BlockDriverState *bs,
uint64_t cluster_offset,
unsigned offset_in_cluster,
- uint8_t *buffer,
- unsigned bytes)
+ QEMUIOVector *qiov)
{
- QEMUIOVector qiov;
- struct iovec iov = { .iov_base = buffer, .iov_len = bytes };
int ret;
- if (bytes == 0) {
+ if (qiov->size == 0) {
return 0;
}
- qemu_iovec_init_external(&qiov, &iov, 1);
-
ret = qcow2_pre_write_overlap_check(bs, 0,
- cluster_offset + offset_in_cluster, bytes);
+ cluster_offset + offset_in_cluster, qiov->size);
if (ret < 0) {
return ret;
}
BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
- bytes, &qiov, 0);
+ qiov->size, qiov, 0);
if (ret < 0) {
return ret;
}
@@ -780,6 +770,7 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
unsigned data_bytes = end->offset - (start->offset + start->nb_bytes);
bool merge_reads;
uint8_t *start_buffer, *end_buffer;
+ QEMUIOVector qiov;
int ret;
assert(start->nb_bytes <= UINT_MAX - end->nb_bytes);
@@ -816,22 +807,25 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta
*m)
/* The part of the buffer where the end region is located */
end_buffer = start_buffer + buffer_size - end->nb_bytes;
+ qemu_iovec_init(&qiov, 1);
+
qemu_co_mutex_unlock(&s->lock);
/* First we read the existing data from both COW regions. We
* either read the whole region in one go, or the start and end
* regions separately. */
if (merge_reads) {
- ret = do_perform_cow_read(bs, m->offset, start->offset,
- start_buffer, buffer_size);
+ qemu_iovec_add(&qiov, start_buffer, buffer_size);
+ ret = do_perform_cow_read(bs, m->offset, start->offset, &qiov);
} else {
- ret = do_perform_cow_read(bs, m->offset, start->offset,
- start_buffer, start->nb_bytes);
+ qemu_iovec_add(&qiov, start_buffer, start->nb_bytes);
+ ret = do_perform_cow_read(bs, m->offset, start->offset, &qiov);
if (ret < 0) {
goto fail;
}
- ret = do_perform_cow_read(bs, m->offset, end->offset,
- end_buffer, end->nb_bytes);
+ qemu_iovec_reset(&qiov);
+ qemu_iovec_add(&qiov, end_buffer, end->nb_bytes);
+ ret = do_perform_cow_read(bs, m->offset, end->offset, &qiov);
}
if (ret < 0) {
goto fail;
@@ -849,14 +843,16 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta
*m)
}
/* And now we can write everything */
- ret = do_perform_cow_write(bs, m->alloc_offset, start->offset,
- start_buffer, start->nb_bytes);
+ qemu_iovec_reset(&qiov);
+ qemu_iovec_add(&qiov, start_buffer, start->nb_bytes);
+ ret = do_perform_cow_write(bs, m->alloc_offset, start->offset, &qiov);
if (ret < 0) {
goto fail;
}
- ret = do_perform_cow_write(bs, m->alloc_offset, end->offset,
- end_buffer, end->nb_bytes);
+ qemu_iovec_reset(&qiov);
+ qemu_iovec_add(&qiov, end_buffer, end->nb_bytes);
+ ret = do_perform_cow_write(bs, m->alloc_offset, end->offset, &qiov);
fail:
qemu_co_mutex_lock(&s->lock);
@@ -870,6 +866,7 @@ fail:
}
qemu_vfree(start_buffer);
+ qemu_iovec_destroy(&qiov);
return ret;
}
--
1.8.3.1
- Re: [Qemu-block] [PULL 11/61] virtio-pci: use ioeventfd even when KVM is disabled, (continued)
[Qemu-block] [PULL 15/61] qemu-iotests: 068: test iothread mode, Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 17/61] qcow2: Remove unused Error variable in do_perform_cow(), Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 18/61] qcow2: Use unsigned int for both members of Qcow2COWRegion, Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 20/61] qcow2: Split do_perform_cow() into _read(), _encrypt() and _write(), Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 16/61] nvme: Add support for Read Data and Write Data in CMBs., Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 19/61] qcow2: Make perform_cow() call do_perform_cow() twice, Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 21/61] qcow2: Allow reading both COW regions with only one request, Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 22/61] qcow2: Pass a QEMUIOVector to do_perform_cow_{read, write}(),
Kevin Wolf <=
[Qemu-block] [PULL 26/61] qed: Make qed_read_table() synchronous, Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 24/61] qcow2: Use offset_into_cluster() and offset_to_l2_index(), Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 25/61] qed: Use bottom half to resume waiting requests, Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 27/61] qed: Remove callback from qed_read_table(), Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 23/61] qcow2: Merge the writing of the COW regions with the guest data, Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 28/61] qed: Remove callback from qed_read_l2_table(), Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 29/61] qed: Remove callback from qed_find_cluster(), Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 30/61] qed: Make qed_read_backing_file() synchronous, Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 31/61] qed: Make qed_copy_from_backing_file() synchronous, Kevin Wolf, 2017/06/23
[Qemu-block] [PULL 33/61] qed: Make qed_write_header() synchronous, Kevin Wolf, 2017/06/23