提交 c883db0d 编写于 作者: M Max Reitz 提交者: Kevin Wolf

qcow2: Fix discard

discard_single_l2() should not implement its own version of
qcow2_get_cluster_type(), but rather rely on this already existing
function. By doing so, it will work for compressed clusters as well
(which it did not so far).

Also, rename "old_offset" to "old_l2_entry", as both are quite different
(and the value is indeed of the latter kind).
Signed-off-by: NMax Reitz <mreitz@redhat.com>
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
上级 cc8a7e56
......@@ -1360,9 +1360,9 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
for (i = 0; i < nb_clusters; i++) {
uint64_t old_offset;
uint64_t old_l2_entry;
old_offset = be64_to_cpu(l2_table[l2_index + i]);
old_l2_entry = be64_to_cpu(l2_table[l2_index + i]);
/*
* Make sure that a discarded area reads back as zeroes for v3 images
......@@ -1373,12 +1373,22 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
* TODO We might want to use bdrv_get_block_status(bs) here, but we're
* holding s->lock, so that doesn't work today.
*/
if (old_offset & QCOW_OFLAG_ZERO) {
continue;
}
switch (qcow2_get_cluster_type(old_l2_entry)) {
case QCOW2_CLUSTER_UNALLOCATED:
if (!bs->backing_hd) {
continue;
}
break;
if ((old_offset & L2E_OFFSET_MASK) == 0 && !bs->backing_hd) {
continue;
case QCOW2_CLUSTER_ZERO:
continue;
case QCOW2_CLUSTER_NORMAL:
case QCOW2_CLUSTER_COMPRESSED:
break;
default:
abort();
}
/* First remove L2 entries */
......@@ -1390,7 +1400,7 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
}
/* Then decrease the refcount */
qcow2_free_any_clusters(bs, old_offset, 1, type);
qcow2_free_any_clusters(bs, old_l2_entry, 1, type);
}
ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册