aboutsummaryrefslogtreecommitdiff
path: root/block/qcow2-cluster.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2012-12-07 18:08:46 +0100
committerKevin Wolf <kwolf@redhat.com>2012-12-13 15:37:59 +0100
commitf50f88b9fea09fef12cc293126cf45dcf0ef600b (patch)
tree2060b173e0069405cca56846cce4fe44e793952c /block/qcow2-cluster.c
parent060bee8943c27d4d53f65570fafaa2559fcd87c3 (diff)
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 <kwolf@redhat.com>
Diffstat (limited to 'block/qcow2-cluster.c')
-rw-r--r--block/qcow2-cluster.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index c4752ee812..c2b59e7d6a 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -652,9 +652,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
uint64_t cluster_offset = m->alloc_offset;
trace_qcow2_cluster_link_l2(qemu_coroutine_self(), m->nb_clusters);
-
- if (m->nb_clusters == 0)
- return 0;
+ assert(m->nb_clusters > 0);
old_cluster = g_malloc(m->nb_clusters * sizeof(uint64_t));
@@ -856,7 +854,7 @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
* Return 0 on success and -errno in error cases
*/
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
- int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta *m)
+ int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m)
{
BDRVQcowState *s = bs->opaque;
int l2_index, ret, sectors;
@@ -928,11 +926,6 @@ again:
}
/* If there is something left to allocate, do that now */
- *m = (QCowL2Meta) {
- .nb_clusters = 0,
- };
- qemu_co_queue_init(&m->dependent_requests);
-
if (nb_clusters > 0) {
uint64_t alloc_offset;
uint64_t alloc_cluster_offset;
@@ -980,7 +973,9 @@ again:
cluster_offset = alloc_cluster_offset;
}
- *m = (QCowL2Meta) {
+ *m = g_malloc0(sizeof(**m));
+
+ **m = (QCowL2Meta) {
.alloc_offset = alloc_cluster_offset,
.offset = alloc_offset & ~(s->cluster_size - 1),
.nb_clusters = nb_clusters,
@@ -995,8 +990,8 @@ again:
.nb_sectors = avail_sectors - nb_sectors,
},
};
- qemu_co_queue_init(&m->dependent_requests);
- QLIST_INSERT_HEAD(&s->cluster_allocs, m, next_in_flight);
+ qemu_co_queue_init(&(*m)->dependent_requests);
+ QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);
}
}
@@ -1013,8 +1008,8 @@ again:
return 0;
fail:
- if (m->nb_clusters > 0) {
- QLIST_REMOVE(m, next_in_flight);
+ if (*m && (*m)->nb_clusters > 0) {
+ QLIST_REMOVE(*m, next_in_flight);
}
return ret;
}