mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 01:03:55 -06:00
vmdk: Fix zero cluster allocation
m_data must contain valid data even for zero clusters when no cluster
was allocated in the image file. Without this, zero writes segfault with
images that have zeroed_grain=on.
For zero writes, we don't want to allocate a cluster in the image file
even in compressed files.
Fixes: 524089bce4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200430133007.170335-3-kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
4dc20e6465
commit
2821c1cc0f
1 changed files with 7 additions and 5 deletions
12
block/vmdk.c
12
block/vmdk.c
|
@ -1572,6 +1572,12 @@ static int get_cluster_offset(BlockDriverState *bs,
|
||||||
extent->l2_cache_counts[min_index] = 1;
|
extent->l2_cache_counts[min_index] = 1;
|
||||||
found:
|
found:
|
||||||
l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
|
l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
|
||||||
|
if (m_data) {
|
||||||
|
m_data->l1_index = l1_index;
|
||||||
|
m_data->l2_index = l2_index;
|
||||||
|
m_data->l2_offset = l2_offset;
|
||||||
|
m_data->l2_cache_entry = ((uint32_t *)l2_table) + l2_index;
|
||||||
|
}
|
||||||
|
|
||||||
if (extent->sesparse) {
|
if (extent->sesparse) {
|
||||||
cluster_sector = le64_to_cpu(((uint64_t *)l2_table)[l2_index]);
|
cluster_sector = le64_to_cpu(((uint64_t *)l2_table)[l2_index]);
|
||||||
|
@ -1631,10 +1637,6 @@ static int get_cluster_offset(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
if (m_data) {
|
if (m_data) {
|
||||||
m_data->new_allocation = true;
|
m_data->new_allocation = true;
|
||||||
m_data->l1_index = l1_index;
|
|
||||||
m_data->l2_index = l2_index;
|
|
||||||
m_data->l2_offset = l2_offset;
|
|
||||||
m_data->l2_cache_entry = ((uint32_t *)l2_table) + l2_index;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
|
*cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
|
||||||
|
@ -1990,7 +1992,7 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
|
||||||
error_report("Could not write to allocated cluster"
|
error_report("Could not write to allocated cluster"
|
||||||
" for streamOptimized");
|
" for streamOptimized");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
} else {
|
} else if (!zeroed) {
|
||||||
/* allocate */
|
/* allocate */
|
||||||
ret = get_cluster_offset(bs, extent, &m_data, offset,
|
ret = get_cluster_offset(bs, extent, &m_data, offset,
|
||||||
true, &cluster_offset, 0, 0);
|
true, &cluster_offset, 0, 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue