From f50f88b9fea09fef12cc293126cf45dcf0ef600b Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 7 Dec 2012 18:08:46 +0100 Subject: qcow2: Allocate l2meta only for cluster allocations Even for writes to already allocated clusters, an l2meta is allocated, though it stays effectively unused. After this patch, only allocating requests still have one. Each l2meta now describes an in-flight request that writes to clusters that are not yet hooked up in the L2 table. Signed-off-by: Kevin Wolf --- block/qcow2.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'block/qcow2.c') diff --git a/block/qcow2.c b/block/qcow2.c index 66ca12f94e..08d92cc6e3 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -787,8 +787,7 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, while (remaining_sectors != 0) { - l2meta = g_malloc0(sizeof(*l2meta)); - qemu_co_queue_init(&l2meta->dependent_requests); + l2meta = NULL; trace_qcow2_writev_start_part(qemu_coroutine_self()); index_in_cluster = sector_num & (s->cluster_sectors - 1); @@ -799,7 +798,7 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, } ret = qcow2_alloc_cluster_offset(bs, sector_num << 9, - index_in_cluster, n_end, &cur_nr_sectors, &cluster_offset, l2meta); + index_in_cluster, n_end, &cur_nr_sectors, &cluster_offset, &l2meta); if (ret < 0) { goto fail; } @@ -845,14 +844,16 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, goto fail; } - ret = qcow2_alloc_cluster_link_l2(bs, l2meta); - if (ret < 0) { - goto fail; - } + if (l2meta != NULL) { + ret = qcow2_alloc_cluster_link_l2(bs, l2meta); + if (ret < 0) { + goto fail; + } - run_dependent_requests(s, l2meta); - g_free(l2meta); - l2meta = NULL; + run_dependent_requests(s, l2meta); + g_free(l2meta); + l2meta = NULL; + } remaining_sectors -= cur_nr_sectors; sector_num += cur_nr_sectors; @@ -1134,11 +1135,10 @@ static int preallocate(BlockDriverState *bs) uint64_t host_offset = 0; int num; int ret; - QCowL2Meta meta; + QCowL2Meta *meta; nb_sectors = bdrv_getlength(bs) >> 9; offset = 0; - qemu_co_queue_init(&meta.dependent_requests); while (nb_sectors) { num = MIN(nb_sectors, INT_MAX >> 9); @@ -1148,15 +1148,17 @@ static int preallocate(BlockDriverState *bs) return ret; } - ret = qcow2_alloc_cluster_link_l2(bs, &meta); + ret = qcow2_alloc_cluster_link_l2(bs, meta); if (ret < 0) { - qcow2_free_any_clusters(bs, meta.alloc_offset, meta.nb_clusters); + qcow2_free_any_clusters(bs, meta->alloc_offset, meta->nb_clusters); return ret; } /* There are no dependent requests, but we need to remove our request * from the list of in-flight requests */ - run_dependent_requests(bs->opaque, &meta); + if (meta != NULL) { + run_dependent_requests(bs->opaque, meta); + } /* TODO Preallocate data if requested */ -- cgit v1.2.3