Skip to content

Commit

Permalink
qcow2: Move cluster gathering to a non-looping loop
Browse files Browse the repository at this point in the history
This patch is mainly to separate the indentation change from the
semantic changes. All that really changes here is that everything moves
into a while loop, all 'goto done' become 'break' and at the end of the
loop a new 'break is inserted.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
kevmw authored and stefanhaRH committed Mar 28, 2013
1 parent 88c6588 commit 2c3b32d
Showing 1 changed file with 70 additions and 64 deletions.
134 changes: 70 additions & 64 deletions block/qcow2-cluster.c
Expand Up @@ -1147,79 +1147,85 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
cluster_offset = 0;
*host_offset = 0;

/*
* Now start gathering as many contiguous clusters as possible:
*
* 1. Check for overlaps with in-flight allocations
*
* a) Overlap not in the first cluster -> shorten this request and let
* the caller handle the rest in its next loop iteration.
*
* b) Real overlaps of two requests. Yield and restart the search for
* contiguous clusters (the situation could have changed while we
* were sleeping)
*
* c) TODO: Request starts in the same cluster as the in-flight
* allocation ends. Shorten the COW of the in-fight allocation, set
* cluster_offset to write to the same cluster and set up the right
* synchronisation between the in-flight request and the new one.
*/
cur_bytes = remaining;
ret = handle_dependencies(bs, start, &cur_bytes);
if (ret == -EAGAIN) {
goto again;
} else if (ret < 0) {
return ret;
} else {
/* handle_dependencies() may have decreased cur_bytes (shortened
* the allocations below) so that the next dependency is processed
* correctly during the next loop iteration. */
}

/*
* 2. Count contiguous COPIED clusters.
*/
ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m);
if (ret < 0) {
return ret;
} else if (ret) {
if (!*host_offset) {
*host_offset = start_of_cluster(s, cluster_offset);
while (true) {
/*
* Now start gathering as many contiguous clusters as possible:
*
* 1. Check for overlaps with in-flight allocations
*
* a) Overlap not in the first cluster -> shorten this request and
* let the caller handle the rest in its next loop iteration.
*
* b) Real overlaps of two requests. Yield and restart the search
* for contiguous clusters (the situation could have changed
* while we were sleeping)
*
* c) TODO: Request starts in the same cluster as the in-flight
* allocation ends. Shorten the COW of the in-fight allocation,
* set cluster_offset to write to the same cluster and set up
* the right synchronisation between the in-flight request and
* the new one.
*/
cur_bytes = remaining;
ret = handle_dependencies(bs, start, &cur_bytes);
if (ret == -EAGAIN) {
goto again;
} else if (ret < 0) {
return ret;
} else {
/* handle_dependencies() may have decreased cur_bytes (shortened
* the allocations below) so that the next dependency is processed
* correctly during the next loop iteration. */
}

start += cur_bytes;
remaining -= cur_bytes;
cluster_offset += cur_bytes;
/*
* 2. Count contiguous COPIED clusters.
*/
ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m);
if (ret < 0) {
return ret;
} else if (ret) {
if (!*host_offset) {
*host_offset = start_of_cluster(s, cluster_offset);
}

cur_bytes = remaining;
} else if (cur_bytes == 0) {
goto done;
}
start += cur_bytes;
remaining -= cur_bytes;
cluster_offset += cur_bytes;

/* If there is something left to allocate, do that now */
if (remaining == 0) {
goto done;
}
cur_bytes = remaining;
} else if (cur_bytes == 0) {
break;
}

/*
* 3. If the request still hasn't completed, allocate new clusters,
* considering any cluster_offset of steps 1c or 2.
*/
ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m);
if (ret < 0) {
return ret;
} else if (ret) {
if (!*host_offset) {
*host_offset = start_of_cluster(s, cluster_offset);
/* If there is something left to allocate, do that now */
if (remaining == 0) {
break;
}

start += cur_bytes;
remaining -= cur_bytes;
cluster_offset += cur_bytes;
/*
* 3. If the request still hasn't completed, allocate new clusters,
* considering any cluster_offset of steps 1c or 2.
*/
ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m);
if (ret < 0) {
return ret;
} else if (ret) {
if (!*host_offset) {
*host_offset = start_of_cluster(s, cluster_offset);
}

start += cur_bytes;
remaining -= cur_bytes;
cluster_offset += cur_bytes;

break;
} else {
assert(cur_bytes == 0);
break;
}
}

/* Some cleanup work */
done:
*num = (n_end - n_start) - (remaining >> BDRV_SECTOR_BITS);
assert(*num > 0);
assert(*host_offset != 0);
Expand Down

0 comments on commit 2c3b32d

Please sign in to comment.