From 6cbc3031c8408e4cb3e55a01f25536e81d3ae90d Mon Sep 17 00:00:00 2001 From: Philipp Hahn Date: Thu, 4 Aug 2011 19:22:10 +0200 Subject: qcow2: Fix DEBUG_* compilation By introducing BlockDriverState compiling qcow2 with DEBUG_ALLOC and DEBUG_EXT defined got broken. Define a BdrvCheckResult structure locally which is now needed as the second argument. Also fix qcow2_read_extensions() needing BDRVQcowState. Signed-off-by: Philipp Hahn Signed-off-by: Kevin Wolf --- block/qcow2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index bfff6cd963..01ea2658b0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -87,6 +87,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, while (offset < end_offset) { #ifdef DEBUG_EXT + BDRVQcowState *s = bs->opaque; /* Sanity check */ if (offset > s->cluster_size) printf("qcow2_read_extension: suspicious offset %lu\n", offset); @@ -280,7 +281,10 @@ static int qcow2_open(BlockDriverState *bs, int flags) qemu_co_mutex_init(&s->lock); #ifdef DEBUG_ALLOC - qcow2_check_refcounts(bs); + { + BdrvCheckResult result = {0}; + qcow2_check_refcounts(bs, &result); + } #endif return ret; -- cgit v1.2.3 From f5cd8173e77c334c278b4684e3806ad01bba1047 Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 23 Aug 2011 15:21:08 +0200 Subject: qcow/qcow2: Allocate QCowAIOCB structure using stack instead of calling qemi_aio_get use stack Signed-off-by: Frediano Ziglio Signed-off-by: Kevin Wolf --- block/qcow2.c | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index 01ea2658b0..f4e3c06ad8 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -392,17 +392,6 @@ typedef struct QCowAIOCB { QLIST_ENTRY(QCowAIOCB) next_depend; } QCowAIOCB; -static void qcow2_aio_cancel(BlockDriverAIOCB *blockacb) -{ - QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common); - qemu_aio_release(acb); -} - -static AIOPool qcow2_aio_pool = { - .aiocb_size = sizeof(QCowAIOCB), - .cancel = qcow2_aio_cancel, -}; - /* * Returns 0 when the request is completed successfully, 1 when there is still * a part left to do and -errno in error cases. @@ -532,13 +521,10 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, - void *opaque, int is_write) + void *opaque, int is_write, QCowAIOCB *acb) { - QCowAIOCB *acb; - - acb = qemu_aio_get(&qcow2_aio_pool, bs, cb, opaque); - if (!acb) - return NULL; + memset(acb, 0, sizeof(*acb)); + acb->common.bs = bs; acb->sector_num = sector_num; acb->qiov = qiov; acb->is_write = is_write; @@ -558,19 +544,18 @@ static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { BDRVQcowState *s = bs->opaque; - QCowAIOCB *acb; + QCowAIOCB acb; int ret; - acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 0); + qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 0, &acb); qemu_co_mutex_lock(&s->lock); do { - ret = qcow2_aio_read_cb(acb); + ret = qcow2_aio_read_cb(&acb); } while (ret > 0); qemu_co_mutex_unlock(&s->lock); - qemu_iovec_destroy(&acb->hd_qiov); - qemu_aio_release(acb); + qemu_iovec_destroy(&acb.hd_qiov); return ret; } @@ -674,20 +659,19 @@ static int qcow2_co_writev(BlockDriverState *bs, QEMUIOVector *qiov) { BDRVQcowState *s = bs->opaque; - QCowAIOCB *acb; + QCowAIOCB acb; int ret; - acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 1); + qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 1, &acb); s->cluster_cache_offset = -1; /* disable compressed cache */ qemu_co_mutex_lock(&s->lock); do { - ret = qcow2_aio_write_cb(acb); + ret = qcow2_aio_write_cb(&acb); } while (ret > 0); qemu_co_mutex_unlock(&s->lock); - qemu_iovec_destroy(&acb->hd_qiov); - qemu_aio_release(acb); + qemu_iovec_destroy(&acb.hd_qiov); return ret; } -- cgit v1.2.3 From 4617310c33990609f05a6ce7eebc2f4d51b7ddfc Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 23 Aug 2011 15:21:13 +0200 Subject: qcow2: Removed unused AIOCB fields Signed-off-by: Frediano Ziglio Signed-off-by: Kevin Wolf --- block/qcow2.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index f4e3c06ad8..9f7566f288 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -385,11 +385,8 @@ typedef struct QCowAIOCB { uint64_t bytes_done; uint64_t cluster_offset; uint8_t *cluster_data; - bool is_write; QEMUIOVector hd_qiov; - QEMUBH *bh; QCowL2Meta l2meta; - QLIST_ENTRY(QCowAIOCB) next_depend; } QCowAIOCB; /* @@ -521,13 +518,12 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, - void *opaque, int is_write, QCowAIOCB *acb) + void *opaque, QCowAIOCB *acb) { memset(acb, 0, sizeof(*acb)); acb->common.bs = bs; acb->sector_num = sector_num; acb->qiov = qiov; - acb->is_write = is_write; qemu_iovec_init(&acb->hd_qiov, qiov->niov); @@ -547,7 +543,7 @@ static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num, QCowAIOCB acb; int ret; - qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 0, &acb); + qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, &acb); qemu_co_mutex_lock(&s->lock); do { @@ -662,7 +658,7 @@ static int qcow2_co_writev(BlockDriverState *bs, QCowAIOCB acb; int ret; - qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 1, &acb); + qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, &acb); s->cluster_cache_offset = -1; /* disable compressed cache */ qemu_co_mutex_lock(&s->lock); -- cgit v1.2.3 From faf575c136cfeed785016179aa7560ad41202e51 Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 23 Aug 2011 15:21:14 +0200 Subject: qcow2: removed cur_nr_sectors field in QCowAIOCB Signed-off-by: Frediano Ziglio Signed-off-by: Kevin Wolf --- block/qcow2.c | 98 ++++++++++++++++++++++++++--------------------------------- 1 file changed, 43 insertions(+), 55 deletions(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index 9f7566f288..cc5f409367 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -381,7 +381,6 @@ typedef struct QCowAIOCB { int64_t sector_num; QEMUIOVector *qiov; int remaining_sectors; - int cur_nr_sectors; /* number of sectors in current iteration */ uint64_t bytes_done; uint64_t cluster_offset; uint8_t *cluster_data; @@ -399,42 +398,22 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) BDRVQcowState *s = bs->opaque; int index_in_cluster, n1; int ret; - - /* post process the read buffer */ - if (!acb->cluster_offset) { - /* nothing to do */ - } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) { - /* nothing to do */ - } else { - if (s->crypt_method) { - qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, - acb->cluster_data, acb->cur_nr_sectors, 0, &s->aes_decrypt_key); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, - acb->cur_nr_sectors * 512); - qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data, - 512 * acb->cur_nr_sectors); - } - } - - acb->remaining_sectors -= acb->cur_nr_sectors; - acb->sector_num += acb->cur_nr_sectors; - acb->bytes_done += acb->cur_nr_sectors * 512; + int cur_nr_sectors; /* number of sectors in current iteration */ if (acb->remaining_sectors == 0) { /* request completed */ return 0; } - /* prepare next AIO request */ - acb->cur_nr_sectors = acb->remaining_sectors; + /* prepare next request */ + cur_nr_sectors = acb->remaining_sectors; if (s->crypt_method) { - acb->cur_nr_sectors = MIN(acb->cur_nr_sectors, + cur_nr_sectors = MIN(cur_nr_sectors, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); } ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9, - &acb->cur_nr_sectors, &acb->cluster_offset); + &cur_nr_sectors, &acb->cluster_offset); if (ret < 0) { return ret; } @@ -443,14 +422,14 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) qemu_iovec_reset(&acb->hd_qiov); qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, - acb->cur_nr_sectors * 512); + cur_nr_sectors * 512); if (!acb->cluster_offset) { if (bs->backing_hd) { /* read from the base image */ n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov, - acb->sector_num, acb->cur_nr_sectors); + acb->sector_num, cur_nr_sectors); if (n1 > 0) { BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); qemu_co_mutex_unlock(&s->lock); @@ -461,11 +440,9 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) return ret; } } - return 1; } else { /* Note: in this case, no need to wait */ - qemu_iovec_memset(&acb->hd_qiov, 0, 512 * acb->cur_nr_sectors); - return 1; + qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors); } } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) { /* add AIO support for compressed blocks ? */ @@ -476,9 +453,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) qemu_iovec_from_buffer(&acb->hd_qiov, s->cluster_cache + index_in_cluster * 512, - 512 * acb->cur_nr_sectors); - - return 1; + 512 * cur_nr_sectors); } else { if ((acb->cluster_offset & 511) != 0) { return -EIO; @@ -494,24 +469,37 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); } - assert(acb->cur_nr_sectors <= + assert(cur_nr_sectors <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); qemu_iovec_reset(&acb->hd_qiov); qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, - 512 * acb->cur_nr_sectors); + 512 * cur_nr_sectors); } BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); qemu_co_mutex_unlock(&s->lock); ret = bdrv_co_readv(bs->file, (acb->cluster_offset >> 9) + index_in_cluster, - acb->cur_nr_sectors, &acb->hd_qiov); + cur_nr_sectors, &acb->hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { return ret; } + if (s->crypt_method) { + qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, + acb->cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key); + qemu_iovec_reset(&acb->hd_qiov); + qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, + cur_nr_sectors * 512); + qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data, + 512 * cur_nr_sectors); + } } + acb->remaining_sectors -= cur_nr_sectors; + acb->sector_num += cur_nr_sectors; + acb->bytes_done += cur_nr_sectors * 512; + return 1; } @@ -529,7 +517,6 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, acb->bytes_done = 0; acb->remaining_sectors = nb_sectors; - acb->cur_nr_sectors = 0; acb->cluster_offset = 0; acb->l2meta.nb_clusters = 0; qemu_co_queue_init(&acb->l2meta.dependent_requests); @@ -582,18 +569,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) int index_in_cluster; int n_end; int ret; - - ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta); - - run_dependent_requests(s, &acb->l2meta); - - if (ret < 0) { - return ret; - } - - acb->remaining_sectors -= acb->cur_nr_sectors; - acb->sector_num += acb->cur_nr_sectors; - acb->bytes_done += acb->cur_nr_sectors * 512; + int cur_nr_sectors; /* number of sectors in current iteration */ if (acb->remaining_sectors == 0) { /* request completed */ @@ -607,7 +583,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9, - index_in_cluster, n_end, &acb->cur_nr_sectors, &acb->l2meta); + index_in_cluster, n_end, &cur_nr_sectors, &acb->l2meta); if (ret < 0) { return ret; } @@ -617,7 +593,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) qemu_iovec_reset(&acb->hd_qiov); qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, - acb->cur_nr_sectors * 512); + cur_nr_sectors * 512); if (s->crypt_method) { if (!acb->cluster_data) { @@ -629,23 +605,35 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data); qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, - acb->cluster_data, acb->cur_nr_sectors, 1, &s->aes_encrypt_key); + acb->cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key); qemu_iovec_reset(&acb->hd_qiov); qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, - acb->cur_nr_sectors * 512); + cur_nr_sectors * 512); } BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); qemu_co_mutex_unlock(&s->lock); ret = bdrv_co_writev(bs->file, (acb->cluster_offset >> 9) + index_in_cluster, - acb->cur_nr_sectors, &acb->hd_qiov); + cur_nr_sectors, &acb->hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { return ret; } + ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta); + + run_dependent_requests(s, &acb->l2meta); + + if (ret < 0) { + return ret; + } + + acb->remaining_sectors -= cur_nr_sectors; + acb->sector_num += cur_nr_sectors; + acb->bytes_done += cur_nr_sectors * 512; + return 1; } -- cgit v1.2.3 From c227140397c7167479862632498b78a3d680ec57 Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 23 Aug 2011 15:21:15 +0200 Subject: qcow2: remove l2meta from QCowAIOCB Signed-off-by: Frediano Ziglio Signed-off-by: Kevin Wolf --- block/qcow2.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index cc5f409367..3068a58a7d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -385,7 +385,6 @@ typedef struct QCowAIOCB { uint64_t cluster_offset; uint8_t *cluster_data; QEMUIOVector hd_qiov; - QCowL2Meta l2meta; } QCowAIOCB; /* @@ -518,8 +517,6 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, acb->bytes_done = 0; acb->remaining_sectors = nb_sectors; acb->cluster_offset = 0; - acb->l2meta.nb_clusters = 0; - qemu_co_queue_init(&acb->l2meta.dependent_requests); return acb; } @@ -570,6 +567,10 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) int n_end; int ret; int cur_nr_sectors; /* number of sectors in current iteration */ + QCowL2Meta l2meta; + + l2meta.nb_clusters = 0; + qemu_co_queue_init(&l2meta.dependent_requests); if (acb->remaining_sectors == 0) { /* request completed */ @@ -583,12 +584,12 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9, - index_in_cluster, n_end, &cur_nr_sectors, &acb->l2meta); + index_in_cluster, n_end, &cur_nr_sectors, &l2meta); if (ret < 0) { return ret; } - acb->cluster_offset = acb->l2meta.cluster_offset; + acb->cluster_offset = l2meta.cluster_offset; assert((acb->cluster_offset & 511) == 0); qemu_iovec_reset(&acb->hd_qiov); @@ -622,9 +623,9 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) return ret; } - ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta); + ret = qcow2_alloc_cluster_link_l2(bs, &l2meta); - run_dependent_requests(s, &acb->l2meta); + run_dependent_requests(s, &l2meta); if (ret < 0) { return ret; -- cgit v1.2.3 From c2bdd9904b4c77389a7bffa5e6517cf1c1e2b420 Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 23 Aug 2011 15:21:16 +0200 Subject: qcow2: remove cluster_offset from QCowAIOCB Signed-off-by: Frediano Ziglio Signed-off-by: Kevin Wolf --- block/qcow2.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index 3068a58a7d..22da050dc8 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -382,7 +382,6 @@ typedef struct QCowAIOCB { QEMUIOVector *qiov; int remaining_sectors; uint64_t bytes_done; - uint64_t cluster_offset; uint8_t *cluster_data; QEMUIOVector hd_qiov; } QCowAIOCB; @@ -398,6 +397,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) int index_in_cluster, n1; int ret; int cur_nr_sectors; /* number of sectors in current iteration */ + uint64_t cluster_offset = 0; if (acb->remaining_sectors == 0) { /* request completed */ @@ -412,7 +412,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) } ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9, - &cur_nr_sectors, &acb->cluster_offset); + &cur_nr_sectors, &cluster_offset); if (ret < 0) { return ret; } @@ -423,7 +423,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, cur_nr_sectors * 512); - if (!acb->cluster_offset) { + if (!cluster_offset) { if (bs->backing_hd) { /* read from the base image */ @@ -443,9 +443,9 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) /* Note: in this case, no need to wait */ qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors); } - } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) { + } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { /* add AIO support for compressed blocks ? */ - ret = qcow2_decompress_cluster(bs, acb->cluster_offset); + ret = qcow2_decompress_cluster(bs, cluster_offset); if (ret < 0) { return ret; } @@ -454,7 +454,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) s->cluster_cache + index_in_cluster * 512, 512 * cur_nr_sectors); } else { - if ((acb->cluster_offset & 511) != 0) { + if ((cluster_offset & 511) != 0) { return -EIO; } @@ -478,7 +478,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); qemu_co_mutex_unlock(&s->lock); ret = bdrv_co_readv(bs->file, - (acb->cluster_offset >> 9) + index_in_cluster, + (cluster_offset >> 9) + index_in_cluster, cur_nr_sectors, &acb->hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { @@ -516,7 +516,6 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, acb->bytes_done = 0; acb->remaining_sectors = nb_sectors; - acb->cluster_offset = 0; return acb; } @@ -568,6 +567,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) int ret; int cur_nr_sectors; /* number of sectors in current iteration */ QCowL2Meta l2meta; + uint64_t cluster_offset; l2meta.nb_clusters = 0; qemu_co_queue_init(&l2meta.dependent_requests); @@ -589,8 +589,8 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) return ret; } - acb->cluster_offset = l2meta.cluster_offset; - assert((acb->cluster_offset & 511) == 0); + cluster_offset = l2meta.cluster_offset; + assert((cluster_offset & 511) == 0); qemu_iovec_reset(&acb->hd_qiov); qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, @@ -616,7 +616,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); qemu_co_mutex_unlock(&s->lock); ret = bdrv_co_writev(bs->file, - (acb->cluster_offset >> 9) + index_in_cluster, + (cluster_offset >> 9) + index_in_cluster, cur_nr_sectors, &acb->hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { -- cgit v1.2.3 From e78c69b89c3c40f938e41b2917e86eeaebc4adc2 Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 23 Aug 2011 15:21:17 +0200 Subject: qcow2: remove common from QCowAIOCB Signed-off-by: Frediano Ziglio Signed-off-by: Kevin Wolf --- block/qcow2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index 22da050dc8..fdb4140bcc 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -377,7 +377,7 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, } typedef struct QCowAIOCB { - BlockDriverAIOCB common; + BlockDriverState *bs; int64_t sector_num; QEMUIOVector *qiov; int remaining_sectors; @@ -392,7 +392,7 @@ typedef struct QCowAIOCB { */ static int qcow2_aio_read_cb(QCowAIOCB *acb) { - BlockDriverState *bs = acb->common.bs; + BlockDriverState *bs = acb->bs; BDRVQcowState *s = bs->opaque; int index_in_cluster, n1; int ret; @@ -508,7 +508,7 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, void *opaque, QCowAIOCB *acb) { memset(acb, 0, sizeof(*acb)); - acb->common.bs = bs; + acb->bs = bs; acb->sector_num = sector_num; acb->qiov = qiov; @@ -560,7 +560,7 @@ static void run_dependent_requests(BDRVQcowState *s, QCowL2Meta *m) */ static int qcow2_aio_write_cb(QCowAIOCB *acb) { - BlockDriverState *bs = acb->common.bs; + BlockDriverState *bs = acb->bs; BDRVQcowState *s = bs->opaque; int index_in_cluster; int n_end; -- cgit v1.2.3 From 5ebaa27e9ad01fa01df7bcb269f3b67e2726ecfa Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 23 Aug 2011 15:21:18 +0200 Subject: qcow2: reindent and use while before the big jump prepare to remove read/write callbacks Signed-off-by: Frediano Ziglio Signed-off-by: Kevin Wolf --- block/qcow2.c | 272 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 135 insertions(+), 137 deletions(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index fdb4140bcc..52a7769752 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -399,107 +399,105 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) int cur_nr_sectors; /* number of sectors in current iteration */ uint64_t cluster_offset = 0; - if (acb->remaining_sectors == 0) { - /* request completed */ - return 0; - } - - /* prepare next request */ - cur_nr_sectors = acb->remaining_sectors; - if (s->crypt_method) { - cur_nr_sectors = MIN(cur_nr_sectors, - QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); - } + while (acb->remaining_sectors != 0) { - ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9, - &cur_nr_sectors, &cluster_offset); - if (ret < 0) { - return ret; - } - - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, - cur_nr_sectors * 512); - - if (!cluster_offset) { - - if (bs->backing_hd) { - /* read from the base image */ - n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov, - acb->sector_num, cur_nr_sectors); - if (n1 > 0) { - BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); - qemu_co_mutex_unlock(&s->lock); - ret = bdrv_co_readv(bs->backing_hd, acb->sector_num, - n1, &acb->hd_qiov); - qemu_co_mutex_lock(&s->lock); - if (ret < 0) { - return ret; - } - } - } else { - /* Note: in this case, no need to wait */ - qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors); + /* prepare next request */ + cur_nr_sectors = acb->remaining_sectors; + if (s->crypt_method) { + cur_nr_sectors = MIN(cur_nr_sectors, + QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); } - } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { - /* add AIO support for compressed blocks ? */ - ret = qcow2_decompress_cluster(bs, cluster_offset); + + ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9, + &cur_nr_sectors, &cluster_offset); if (ret < 0) { return ret; } - qemu_iovec_from_buffer(&acb->hd_qiov, - s->cluster_cache + index_in_cluster * 512, - 512 * cur_nr_sectors); - } else { - if ((cluster_offset & 511) != 0) { - return -EIO; - } + index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - if (s->crypt_method) { - /* - * For encrypted images, read everything into a temporary - * contiguous buffer on which the AES functions can work. - */ - if (!acb->cluster_data) { - acb->cluster_data = - g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); + qemu_iovec_reset(&acb->hd_qiov); + qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, + cur_nr_sectors * 512); + + if (!cluster_offset) { + + if (bs->backing_hd) { + /* read from the base image */ + n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov, + acb->sector_num, cur_nr_sectors); + if (n1 > 0) { + BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_readv(bs->backing_hd, acb->sector_num, + n1, &acb->hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + return ret; + } + } + } else { + /* Note: in this case, no need to wait */ + qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors); + } + } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { + /* add AIO support for compressed blocks ? */ + ret = qcow2_decompress_cluster(bs, cluster_offset); + if (ret < 0) { + return ret; } - assert(cur_nr_sectors <= - QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, + qemu_iovec_from_buffer(&acb->hd_qiov, + s->cluster_cache + index_in_cluster * 512, 512 * cur_nr_sectors); - } + } else { + if ((cluster_offset & 511) != 0) { + return -EIO; + } - BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); - qemu_co_mutex_unlock(&s->lock); - ret = bdrv_co_readv(bs->file, - (cluster_offset >> 9) + index_in_cluster, - cur_nr_sectors, &acb->hd_qiov); - qemu_co_mutex_lock(&s->lock); - if (ret < 0) { - return ret; - } - if (s->crypt_method) { - qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, - acb->cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, - cur_nr_sectors * 512); - qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data, - 512 * cur_nr_sectors); + if (s->crypt_method) { + /* + * For encrypted images, read everything into a temporary + * contiguous buffer on which the AES functions can work. + */ + if (!acb->cluster_data) { + acb->cluster_data = + g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); + } + + assert(cur_nr_sectors <= + QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); + qemu_iovec_reset(&acb->hd_qiov); + qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, + 512 * cur_nr_sectors); + } + + BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_readv(bs->file, + (cluster_offset >> 9) + index_in_cluster, + cur_nr_sectors, &acb->hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + return ret; + } + if (s->crypt_method) { + qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, + acb->cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key); + qemu_iovec_reset(&acb->hd_qiov); + qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, + cur_nr_sectors * 512); + qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data, + 512 * cur_nr_sectors); + } } - } - acb->remaining_sectors -= cur_nr_sectors; - acb->sector_num += cur_nr_sectors; - acb->bytes_done += cur_nr_sectors * 512; + acb->remaining_sectors -= cur_nr_sectors; + acb->sector_num += cur_nr_sectors; + acb->bytes_done += cur_nr_sectors * 512; + } - return 1; + return 0; } static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, @@ -572,70 +570,70 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) l2meta.nb_clusters = 0; qemu_co_queue_init(&l2meta.dependent_requests); - if (acb->remaining_sectors == 0) { - /* request completed */ - return 0; - } + while (acb->remaining_sectors != 0) { - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - n_end = index_in_cluster + acb->remaining_sectors; - if (s->crypt_method && - n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) - n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; + index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); + n_end = index_in_cluster + acb->remaining_sectors; + if (s->crypt_method && + n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) { + n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; + } - ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9, - index_in_cluster, n_end, &cur_nr_sectors, &l2meta); - if (ret < 0) { - return ret; - } + ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9, + index_in_cluster, n_end, &cur_nr_sectors, &l2meta); + if (ret < 0) { + return ret; + } - cluster_offset = l2meta.cluster_offset; - assert((cluster_offset & 511) == 0); + cluster_offset = l2meta.cluster_offset; + assert((cluster_offset & 511) == 0); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, - cur_nr_sectors * 512); + qemu_iovec_reset(&acb->hd_qiov); + qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, + cur_nr_sectors * 512); - if (s->crypt_method) { - if (!acb->cluster_data) { - acb->cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * - s->cluster_size); - } + if (s->crypt_method) { + if (!acb->cluster_data) { + acb->cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * + s->cluster_size); + } - assert(acb->hd_qiov.size <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); - qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data); + assert(acb->hd_qiov.size <= + QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); + qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data); - qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, - acb->cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key); + qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, + acb->cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, - cur_nr_sectors * 512); - } + qemu_iovec_reset(&acb->hd_qiov); + qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, + cur_nr_sectors * 512); + } - BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); - qemu_co_mutex_unlock(&s->lock); - ret = bdrv_co_writev(bs->file, - (cluster_offset >> 9) + index_in_cluster, - cur_nr_sectors, &acb->hd_qiov); - qemu_co_mutex_lock(&s->lock); - if (ret < 0) { - return ret; - } + BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_writev(bs->file, + (cluster_offset >> 9) + index_in_cluster, + cur_nr_sectors, &acb->hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + return ret; + } - ret = qcow2_alloc_cluster_link_l2(bs, &l2meta); + ret = qcow2_alloc_cluster_link_l2(bs, &l2meta); - run_dependent_requests(s, &l2meta); + run_dependent_requests(s, &l2meta); - if (ret < 0) { - return ret; - } + if (ret < 0) { + return ret; + } - acb->remaining_sectors -= cur_nr_sectors; - acb->sector_num += cur_nr_sectors; - acb->bytes_done += cur_nr_sectors * 512; + acb->remaining_sectors -= cur_nr_sectors; + acb->sector_num += cur_nr_sectors; + acb->bytes_done += cur_nr_sectors * 512; + } - return 1; + return 0; } static int qcow2_co_writev(BlockDriverState *bs, -- cgit v1.2.3 From 3fc48d0983a989d2227668bbcaae1681ea37fddd Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 23 Aug 2011 15:21:19 +0200 Subject: qcow2: Removed QCowAIOCB entirely Signed-off-by: Frediano Ziglio Signed-off-by: Kevin Wolf --- block/qcow2.c | 207 +++++++++++++++++++++++----------------------------------- 1 file changed, 80 insertions(+), 127 deletions(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index 52a7769752..37dab656ab 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -376,83 +376,77 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, return n1; } -typedef struct QCowAIOCB { - BlockDriverState *bs; - int64_t sector_num; - QEMUIOVector *qiov; - int remaining_sectors; - uint64_t bytes_done; - uint8_t *cluster_data; - QEMUIOVector hd_qiov; -} QCowAIOCB; - -/* - * Returns 0 when the request is completed successfully, 1 when there is still - * a part left to do and -errno in error cases. - */ -static int qcow2_aio_read_cb(QCowAIOCB *acb) +static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num, + int remaining_sectors, QEMUIOVector *qiov) { - BlockDriverState *bs = acb->bs; BDRVQcowState *s = bs->opaque; int index_in_cluster, n1; int ret; int cur_nr_sectors; /* number of sectors in current iteration */ uint64_t cluster_offset = 0; + uint64_t bytes_done = 0; + QEMUIOVector hd_qiov; + uint8_t *cluster_data = NULL; - while (acb->remaining_sectors != 0) { + qemu_iovec_init(&hd_qiov, qiov->niov); + + qemu_co_mutex_lock(&s->lock); + + while (remaining_sectors != 0) { /* prepare next request */ - cur_nr_sectors = acb->remaining_sectors; + cur_nr_sectors = remaining_sectors; if (s->crypt_method) { cur_nr_sectors = MIN(cur_nr_sectors, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); } - ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9, + ret = qcow2_get_cluster_offset(bs, sector_num << 9, &cur_nr_sectors, &cluster_offset); if (ret < 0) { - return ret; + goto fail; } - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); + index_in_cluster = sector_num & (s->cluster_sectors - 1); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, + qemu_iovec_reset(&hd_qiov); + qemu_iovec_copy(&hd_qiov, qiov, bytes_done, cur_nr_sectors * 512); if (!cluster_offset) { if (bs->backing_hd) { /* read from the base image */ - n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov, - acb->sector_num, cur_nr_sectors); + n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov, + sector_num, cur_nr_sectors); if (n1 > 0) { BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); qemu_co_mutex_unlock(&s->lock); - ret = bdrv_co_readv(bs->backing_hd, acb->sector_num, - n1, &acb->hd_qiov); + ret = bdrv_co_readv(bs->backing_hd, sector_num, + n1, &hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { - return ret; + goto fail; } } } else { /* Note: in this case, no need to wait */ - qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors); + qemu_iovec_memset(&hd_qiov, 0, 512 * cur_nr_sectors); } } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { /* add AIO support for compressed blocks ? */ ret = qcow2_decompress_cluster(bs, cluster_offset); if (ret < 0) { - return ret; + goto fail; } - qemu_iovec_from_buffer(&acb->hd_qiov, + qemu_iovec_from_buffer(&hd_qiov, s->cluster_cache + index_in_cluster * 512, 512 * cur_nr_sectors); } else { if ((cluster_offset & 511) != 0) { - return -EIO; + ret = -EIO; + goto fail; } if (s->crypt_method) { @@ -460,15 +454,15 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) * For encrypted images, read everything into a temporary * contiguous buffer on which the AES functions can work. */ - if (!acb->cluster_data) { - acb->cluster_data = + if (!cluster_data) { + cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); } assert(cur_nr_sectors <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, + qemu_iovec_reset(&hd_qiov); + qemu_iovec_add(&hd_qiov, cluster_data, 512 * cur_nr_sectors); } @@ -476,63 +470,32 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb) qemu_co_mutex_unlock(&s->lock); ret = bdrv_co_readv(bs->file, (cluster_offset >> 9) + index_in_cluster, - cur_nr_sectors, &acb->hd_qiov); + cur_nr_sectors, &hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { - return ret; + goto fail; } if (s->crypt_method) { - qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, - acb->cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, + qcow2_encrypt_sectors(s, sector_num, cluster_data, + cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key); + qemu_iovec_reset(&hd_qiov); + qemu_iovec_copy(&hd_qiov, qiov, bytes_done, cur_nr_sectors * 512); - qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data, + qemu_iovec_from_buffer(&hd_qiov, cluster_data, 512 * cur_nr_sectors); } } - acb->remaining_sectors -= cur_nr_sectors; - acb->sector_num += cur_nr_sectors; - acb->bytes_done += cur_nr_sectors * 512; + remaining_sectors -= cur_nr_sectors; + sector_num += cur_nr_sectors; + bytes_done += cur_nr_sectors * 512; } + ret = 0; - return 0; -} - -static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, - QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, - void *opaque, QCowAIOCB *acb) -{ - memset(acb, 0, sizeof(*acb)); - acb->bs = bs; - acb->sector_num = sector_num; - acb->qiov = qiov; - - qemu_iovec_init(&acb->hd_qiov, qiov->niov); - - acb->bytes_done = 0; - acb->remaining_sectors = nb_sectors; - return acb; -} - -static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) -{ - BDRVQcowState *s = bs->opaque; - QCowAIOCB acb; - int ret; - - qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, &acb); - - qemu_co_mutex_lock(&s->lock); - do { - ret = qcow2_aio_read_cb(&acb); - } while (ret > 0); +fail: qemu_co_mutex_unlock(&s->lock); - qemu_iovec_destroy(&acb.hd_qiov); + qemu_iovec_destroy(&hd_qiov); return ret; } @@ -552,13 +515,11 @@ static void run_dependent_requests(BDRVQcowState *s, QCowL2Meta *m) } } -/* - * Returns 0 when the request is completed successfully, 1 when there is still - * a part left to do and -errno in error cases. - */ -static int qcow2_aio_write_cb(QCowAIOCB *acb) +static int qcow2_co_writev(BlockDriverState *bs, + int64_t sector_num, + int remaining_sectors, + QEMUIOVector *qiov) { - BlockDriverState *bs = acb->bs; BDRVQcowState *s = bs->opaque; int index_in_cluster; int n_end; @@ -566,47 +527,56 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) int cur_nr_sectors; /* number of sectors in current iteration */ QCowL2Meta l2meta; uint64_t cluster_offset; + QEMUIOVector hd_qiov; + uint64_t bytes_done = 0; + uint8_t *cluster_data = NULL; l2meta.nb_clusters = 0; qemu_co_queue_init(&l2meta.dependent_requests); - while (acb->remaining_sectors != 0) { + qemu_iovec_init(&hd_qiov, qiov->niov); + + s->cluster_cache_offset = -1; /* disable compressed cache */ + + qemu_co_mutex_lock(&s->lock); - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - n_end = index_in_cluster + acb->remaining_sectors; + while (remaining_sectors != 0) { + + index_in_cluster = sector_num & (s->cluster_sectors - 1); + n_end = index_in_cluster + remaining_sectors; if (s->crypt_method && n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) { n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; } - ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9, + ret = qcow2_alloc_cluster_offset(bs, sector_num << 9, index_in_cluster, n_end, &cur_nr_sectors, &l2meta); if (ret < 0) { - return ret; + goto fail; } cluster_offset = l2meta.cluster_offset; assert((cluster_offset & 511) == 0); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, + qemu_iovec_reset(&hd_qiov); + qemu_iovec_copy(&hd_qiov, qiov, bytes_done, cur_nr_sectors * 512); if (s->crypt_method) { - if (!acb->cluster_data) { - acb->cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * + if (!cluster_data) { + cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); } - assert(acb->hd_qiov.size <= + assert(hd_qiov.size <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); - qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data); + qemu_iovec_to_buffer(&hd_qiov, cluster_data); - qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, - acb->cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key); + qcow2_encrypt_sectors(s, sector_num, cluster_data, + cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, + qemu_iovec_reset(&hd_qiov); + qemu_iovec_add(&hd_qiov, cluster_data, cur_nr_sectors * 512); } @@ -614,10 +584,10 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) qemu_co_mutex_unlock(&s->lock); ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + index_in_cluster, - cur_nr_sectors, &acb->hd_qiov); + cur_nr_sectors, &hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { - return ret; + goto fail; } ret = qcow2_alloc_cluster_link_l2(bs, &l2meta); @@ -625,36 +595,19 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb) run_dependent_requests(s, &l2meta); if (ret < 0) { - return ret; + goto fail; } - acb->remaining_sectors -= cur_nr_sectors; - acb->sector_num += cur_nr_sectors; - acb->bytes_done += cur_nr_sectors * 512; + remaining_sectors -= cur_nr_sectors; + sector_num += cur_nr_sectors; + bytes_done += cur_nr_sectors * 512; } + ret = 0; - return 0; -} - -static int qcow2_co_writev(BlockDriverState *bs, - int64_t sector_num, - int nb_sectors, - QEMUIOVector *qiov) -{ - BDRVQcowState *s = bs->opaque; - QCowAIOCB acb; - int ret; - - qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, &acb); - s->cluster_cache_offset = -1; /* disable compressed cache */ - - qemu_co_mutex_lock(&s->lock); - do { - ret = qcow2_aio_write_cb(&acb); - } while (ret > 0); +fail: qemu_co_mutex_unlock(&s->lock); - qemu_iovec_destroy(&acb.hd_qiov); + qemu_iovec_destroy(&hd_qiov); return ret; } -- cgit v1.2.3 From ab0997e0afdcb272fd04784a280b2df46b0c759f Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 23 Aug 2011 15:21:20 +0200 Subject: qcow2: remove memory leak Signed-off-by: Frediano Ziglio Signed-off-by: Kevin Wolf --- block/qcow2.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index 37dab656ab..b725d68b1d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -496,6 +496,7 @@ fail: qemu_co_mutex_unlock(&s->lock); qemu_iovec_destroy(&hd_qiov); + g_free(cluster_data); return ret; } @@ -608,6 +609,7 @@ fail: qemu_co_mutex_unlock(&s->lock); qemu_iovec_destroy(&hd_qiov); + g_free(cluster_data); return ret; } -- cgit v1.2.3