[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [patch 3/5][v2] Extract compressing part from alloc_cluster
From: |
Laurent Vivier |
Subject: |
[Qemu-devel] [patch 3/5][v2] Extract compressing part from alloc_cluster_offset() |
Date: |
Tue, 29 Jul 2008 16:13:55 +0200 |
User-agent: |
quilt/0.45-1 |
Divide alloc_cluster_offset() into alloc_cluster_offset() and
alloc_compressed_cluster_offset(). Factorize code to free clusters into
free_used_clusters().
Signed-off-by: Laurent Vivier <address@hidden>
---
block-qcow2.c | 105 ++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 66 insertions(+), 39 deletions(-)
Index: qemu/block-qcow2.c
===================================================================
--- qemu.orig/block-qcow2.c 2008-07-29 15:22:20.000000000 +0200
+++ qemu/block-qcow2.c 2008-07-29 15:22:26.000000000 +0200
@@ -598,14 +598,13 @@ static uint64_t get_cluster_offset(Block
return cluster_offset & ~QCOW_OFLAG_COPIED;
}
-static uint64_t alloc_cluster_offset(BlockDriverState *bs,
- uint64_t offset,
- int compressed_size,
- int n_start, int n_end)
+static uint64_t free_used_clusters(BlockDriverState *bs, uint64_t offset,
+ uint64_t **l2_table, uint64_t *l2_offset,
+ int *l2_index)
{
BDRVQcowState *s = bs->opaque;
- int l1_index, l2_index, ret;
- uint64_t l2_offset, *l2_table, cluster_offset;
+ int l1_index, ret;
+ uint64_t cluster_offset;
l1_index = offset >> (s->l2_bits + s->cluster_bits);
if (l1_index >= s->l1_size) {
@@ -614,24 +613,24 @@ static uint64_t alloc_cluster_offset(Blo
return 0;
}
- l2_offset = s->l1_table[l1_index];
- if (l2_offset & QCOW_OFLAG_COPIED) {
- ret = l2_load(bs, l1_index, &l2_table, &l2_offset);
+ *l2_offset = s->l1_table[l1_index];
+ if (*l2_offset & QCOW_OFLAG_COPIED) {
+ ret = l2_load(bs, l1_index, l2_table, l2_offset);
if (ret == 0)
return 0;
} else {
- if (l2_offset)
- free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
- ret = l2_allocate(bs, l1_index, &l2_table, &l2_offset);
+ if (*l2_offset)
+ free_clusters(bs, *l2_offset, s->l2_size * sizeof(uint64_t));
+ ret = l2_allocate(bs, l1_index, l2_table, l2_offset);
if (ret == 0)
return 0;
}
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
+ *l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
+ cluster_offset = be64_to_cpu((*l2_table)[*l2_index]);
if (cluster_offset & QCOW_OFLAG_COPIED)
- return cluster_offset & ~QCOW_OFLAG_COPIED;
+ return cluster_offset;
if (cluster_offset) {
/* free the cluster */
@@ -645,28 +644,56 @@ static uint64_t alloc_cluster_offset(Blo
free_clusters(bs, cluster_offset, s->cluster_size);
}
}
+ return 0;
+}
- if (compressed_size) {
- int nb_csectors;
- cluster_offset = alloc_bytes(bs, compressed_size);
- nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
- (cluster_offset >> 9);
- cluster_offset |= QCOW_OFLAG_COMPRESSED |
- ((uint64_t)nb_csectors << s->csize_shift);
-
- /* update L2 table
- * compressed clusters never have the copied flag
- */
-
- l2_table[l2_index] = cpu_to_be64(cluster_offset);
- if (bdrv_pwrite(s->hd,
- l2_offset + l2_index * sizeof(uint64_t),
- l2_table + l2_index,
- sizeof(uint64_t)) != sizeof(uint64_t))
- return 0;
+static uint64_t alloc_compressed_cluster_offset(BlockDriverState *bs,
+ uint64_t offset,
+ int compressed_size)
+{
+ BDRVQcowState *s = bs->opaque;
+ int l2_index;
+ uint64_t l2_offset, *l2_table, cluster_offset;
+ int nb_csectors;
+
+ cluster_offset = free_used_clusters(bs, offset,
+ &l2_table, &l2_offset, &l2_index);
+ if (cluster_offset & QCOW_OFLAG_COPIED)
+ return cluster_offset & ~QCOW_OFLAG_COPIED;
+
+ cluster_offset = alloc_bytes(bs, compressed_size);
+ nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
+ (cluster_offset >> 9);
+ cluster_offset |= QCOW_OFLAG_COMPRESSED |
+ ((uint64_t)nb_csectors << s->csize_shift);
+
+ /* update L2 table
+ * compressed clusters never have the copied flag
+ */
+
+ l2_table[l2_index] = cpu_to_be64(cluster_offset);
+ if (bdrv_pwrite(s->hd,
+ l2_offset + l2_index * sizeof(uint64_t),
+ l2_table + l2_index,
+ sizeof(uint64_t)) != sizeof(uint64_t))
+ return 0;
+
+ return cluster_offset;
+}
+
+static uint64_t alloc_cluster_offset(BlockDriverState *bs,
+ uint64_t offset,
+ int n_start, int n_end)
+{
+ BDRVQcowState *s = bs->opaque;
+ int l2_index, ret;
+ uint64_t l2_offset, *l2_table, cluster_offset;
- return cluster_offset;
- }
+
+ cluster_offset = free_used_clusters(bs, offset,
+ &l2_table, &l2_offset, &l2_index);
+ if (cluster_offset & QCOW_OFLAG_COPIED)
+ return cluster_offset & ~QCOW_OFLAG_COPIED;
/* allocate a new cluster */
@@ -838,7 +865,7 @@ static int qcow_write(BlockDriverState *
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
- cluster_offset = alloc_cluster_offset(bs, sector_num << 9, 0,
+ cluster_offset = alloc_cluster_offset(bs, sector_num << 9,
index_in_cluster,
index_in_cluster + n);
if (!cluster_offset)
@@ -1022,7 +1049,7 @@ static void qcow_aio_write_cb(void *opaq
acb->n = s->cluster_sectors - index_in_cluster;
if (acb->n > acb->nb_sectors)
acb->n = acb->nb_sectors;
- cluster_offset = alloc_cluster_offset(bs, acb->sector_num << 9, 0,
+ cluster_offset = alloc_cluster_offset(bs, acb->sector_num << 9,
index_in_cluster,
index_in_cluster + acb->n);
if (!cluster_offset || (cluster_offset & 511) != 0) {
@@ -1284,8 +1311,8 @@ static int qcow_write_compressed(BlockDr
/* could not compress: write normal cluster */
qcow_write(bs, sector_num, buf, s->cluster_sectors);
} else {
- cluster_offset = alloc_cluster_offset(bs, sector_num << 9,
- out_len, 0, 0);
+ cluster_offset = alloc_compressed_cluster_offset(bs, sector_num << 9,
+ out_len);
cluster_offset &= s->cluster_offset_mask;
if (bdrv_pwrite(s->hd, cluster_offset, out_buf, out_len) != out_len) {
qemu_free(out_buf);
--
- [Qemu-devel] [patch 0/5][v2] qcow2: improve I/O performance with cache=off, Laurent Vivier, 2008/07/29
- [Qemu-devel] [patch 1/5][v2] Extract code from get_cluster_offset(), Laurent Vivier, 2008/07/29
- [Qemu-devel] [patch 4/5][v2] Aggregate same type clusters., Laurent Vivier, 2008/07/29
- [Qemu-devel] [patch 3/5][v2] Extract compressing part from alloc_cluster_offset(),
Laurent Vivier <=
- [Qemu-devel] [patch 2/5][v2] Divide get_cluster_offset(), Laurent Vivier, 2008/07/29
- [Qemu-devel] [patch 5/5][v2] Try to aggregate free clusters and freed clusters, Laurent Vivier, 2008/07/29
- Re: [Qemu-devel] [patch 0/5][v2] qcow2: improve I/O performance with cache=off, Anthony Liguori, 2008/07/29