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
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;
|
||||
found:
|
||||
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) {
|
||||
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) {
|
||||
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;
|
||||
@ -1990,7 +1992,7 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
|
||||
error_report("Could not write to allocated cluster"
|
||||
" for streamOptimized");
|
||||
return -EIO;
|
||||
} else {
|
||||
} else if (!zeroed) {
|
||||
/* allocate */
|
||||
ret = get_cluster_offset(bs, extent, &m_data, offset,
|
||||
true, &cluster_offset, 0, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user