aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2016-12-05 09:49:34 -0600
committerKevin Wolf <kwolf@redhat.com>2016-12-06 15:37:02 +0100
commita3e1505daec31ef56f0489f8c8fff1b8e4ca92bd (patch)
tree2614453febab9387fbaae68a83cf8b27f76a5109 /block
parentbc66cedb4141fb7588f2462c74310d8fb5dd4cf1 (diff)
qcow2: Don't strand clusters near 2G intervals during commit
The qcow2_make_empty() function is reached during 'qemu-img commit', in order to clear out ALL clusters of an image. However, if the image cannot use the fast code path (true if the image is format 0.10, or if the image contains a snapshot), the cluster size is larger than 512, and the image is larger than 2G in size, then our choice of sector_step causes problems. Since it is not cluster aligned, but qcow2_discard_clusters() silently ignores an unaligned head or tail, we are leaving clusters allocated. Enhance the testsuite to expose the flaw, and patch the problem by ensuring our step size is aligned. Signed-off-by: Eric Blake <eblake@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r--block/qcow2.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/block/qcow2.c b/block/qcow2.c
index ed9e0f31d6..96fb8a8f16 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2808,7 +2808,8 @@ static int qcow2_make_empty(BlockDriverState *bs)
{
BDRVQcow2State *s = bs->opaque;
uint64_t start_sector;
- int sector_step = INT_MAX / BDRV_SECTOR_SIZE;
+ int sector_step = (QEMU_ALIGN_DOWN(INT_MAX, s->cluster_size) /
+ BDRV_SECTOR_SIZE);
int l1_clusters, ret = 0;
l1_clusters = DIV_ROUND_UP(s->l1_size, s->cluster_size / sizeof(uint64_t));