@@ -1641,6 +1641,7 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
uint64_t cluster_offset;
uint64_t bytes_done = 0;
VmdkMetaData m_data;
+ uint64_t extent_end;
if (DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) > bs->total_sectors) {
error_report("Wrong offset: offset=0x%" PRIx64
@@ -1654,9 +1655,17 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
if (!extent) {
return -EIO;
}
+ extent_end = extent->end_sector * BDRV_SECTOR_SIZE;
+
offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
- n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
- - offset_in_cluster);
+
+ /* truncate n_bytes to first cluster because we need to perform COW */
+ if (offset_in_cluster > 0) {
+ n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
+ - offset_in_cluster);
+ } else {
+ n_bytes = MIN(bytes, extent_end - offset);
+ }
ret = vmdk_get_cluster_offset(bs, extent, &m_data, offset,
!(extent->compressed || zeroed),