diff options
author | Kevin Wolf <kwolf@redhat.com> | 2010-04-16 19:28:14 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2010-05-03 10:07:31 +0200 |
commit | c336500df5bf08492f4e7796b2193cd4976f3548 (patch) | |
tree | 2ea0013567e432c50f27ea0f7231c61a20a0b9e7 /block/vmdk.c | |
parent | f2feebbd93c251ec0098a9ccf808f7cb1da7f67c (diff) |
vmdk: Fix COW
When trying to do COW, VMDK wrote the data back to the backing file. This
problem was revealed by the patch that made backing files read-only. This patch
does not only fix the problem, but also simplifies the VMDK code a bit.
This fixes the backing file qemu-iotests cases for VMDK.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/vmdk.c')
-rw-r--r-- | block/vmdk.c | 35 |
1 files changed, 11 insertions, 24 deletions
diff --git a/block/vmdk.c b/block/vmdk.c index 5ef4375f51..ae3412148b 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -87,14 +87,6 @@ typedef struct VmdkMetaData { int valid; } VmdkMetaData; -typedef struct ActiveBDRVState{ - BlockDriverState *hd; // active image handler - uint64_t cluster_offset; // current write offset -}ActiveBDRVState; - -static ActiveBDRVState activeBDRV; - - static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename) { uint32_t magic; @@ -492,30 +484,28 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data, static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset, uint64_t offset, int allocate) { - uint64_t parent_cluster_offset; BDRVVmdkState *s = bs->opaque; uint8_t whole_grain[s->cluster_sectors*512]; // 128 sectors * 512 bytes each = grain size 64KB // we will be here if it's first write on non-exist grain(cluster). // try to read from parent image, if exist if (bs->backing_hd) { - BDRVVmdkState *ps = bs->backing_hd->opaque; + int ret; if (!vmdk_is_cid_valid(bs)) return -1; - parent_cluster_offset = get_cluster_offset(bs->backing_hd, NULL, - offset, allocate); - - if (parent_cluster_offset) { - BDRVVmdkState *act_s = activeBDRV.hd->opaque; - - if (bdrv_pread(ps->hd, parent_cluster_offset, whole_grain, ps->cluster_sectors*512) != ps->cluster_sectors*512) - return -1; + ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain, + s->cluster_sectors); + if (ret < 0) { + return -1; + } - //Write grain only into the active image - if (bdrv_pwrite(act_s->hd, activeBDRV.cluster_offset << 9, whole_grain, sizeof(whole_grain)) != sizeof(whole_grain)) - return -1; + //Write grain only into the active image + ret = bdrv_write(s->hd, cluster_offset, whole_grain, + s->cluster_sectors); + if (ret < 0) { + return -1; } } return 0; @@ -601,9 +591,6 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data, cluster_offset >>= 9; tmp = cpu_to_le32(cluster_offset); l2_table[l2_index] = tmp; - // Save the active image state - activeBDRV.cluster_offset = cluster_offset; - activeBDRV.hd = bs; } /* First of all we write grain itself, to avoid race condition * that may to corrupt the image. |