summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2012-12-07 18:08:42 +0100
committerKevin Wolf <kwolf@redhat.com>2012-12-13 15:37:59 +0100
commit1d3afd649bc77aa14bc2741e2da6475822d41c5f (patch)
tree48d6c4f5fb3371a92b9e9c824e133cd121fa808f
parenta7f3d65b65b8c86a5ff0c0abcfefb45e2ec6fe4c (diff)
downloadqemu-1d3afd649bc77aa14bc2741e2da6475822d41c5f.tar.gz
qcow2: Round QCowL2Meta.offset down to cluster boundary
The offset within the cluster is already present as n_start and this is what the code uses. QCowL2Meta.offset is only needed at a cluster granularity. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r--block/qcow2-cluster.c4
-rw-r--r--block/qcow2.h22
2 files changed, 24 insertions, 2 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index e179211c57..d17a37c2fa 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -631,7 +631,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
old_cluster = g_malloc(m->nb_clusters * sizeof(uint64_t));
/* copy content of unmodified sectors */
- start_sect = (m->offset & ~(s->cluster_size - 1)) >> 9;
+ start_sect = m->offset >> 9;
if (m->n_start) {
cow = true;
qemu_co_mutex_unlock(&s->lock);
@@ -966,7 +966,7 @@ again:
.cluster_offset = keep_clusters == 0 ?
alloc_cluster_offset : cluster_offset,
.alloc_offset = alloc_cluster_offset,
- .offset = alloc_offset,
+ .offset = alloc_offset & ~(s->cluster_size - 1),
.n_start = keep_clusters == 0 ? n_start : 0,
.nb_clusters = nb_clusters,
.nb_available = MIN(requested_sectors, avail_sectors),
diff --git a/block/qcow2.h b/block/qcow2.h
index b4eb65470e..2a406a7e83 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -199,12 +199,34 @@ struct QCowAIOCB;
/* XXX This could be private for qcow2-cluster.c */
typedef struct QCowL2Meta
{
+ /** Guest offset of the first newly allocated cluster */
uint64_t offset;
+
+ /** Host offset of the first cluster of the request */
uint64_t cluster_offset;
+
+ /** Host offset of the first newly allocated cluster */
uint64_t alloc_offset;
+
+ /**
+ * Number of sectors between the start of the first allocated cluster and
+ * the area that the guest actually writes to.
+ */
int n_start;
+
+ /**
+ * Number of sectors from the start of the first allocated cluster to
+ * the end of the (possibly shortened) request
+ */
int nb_available;
+
+ /** Number of newly allocated clusters */
int nb_clusters;
+
+ /**
+ * Requests that overlap with this allocation and wait to be restarted
+ * when the allocating request has completed.
+ */
CoQueue dependent_requests;
QLIST_ENTRY(QCowL2Meta) next_in_flight;