vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,

               QEMUIOVector *qiov, int flags)

{

    BDRVVPCState *s = bs->opaque;

    int64_t image_offset;

    int64_t n_bytes;

    int64_t bytes_done = 0;

    int ret;

    VHDFooter *footer =  (VHDFooter *) s->footer_buf;

    QEMUIOVector local_qiov;



    if (be32_to_cpu(footer->type) == VHD_FIXED) {

        return bdrv_co_pwritev(bs->file->bs, offset, bytes, qiov, 0);

    }



    qemu_co_mutex_lock(&s->lock);

    qemu_iovec_init(&local_qiov, qiov->niov);



    while (bytes > 0) {

        image_offset = get_image_offset(bs, offset, true);

        n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));



        if (image_offset == -1) {

            image_offset = alloc_block(bs, offset);

            if (image_offset < 0) {

                ret = image_offset;

                goto fail;

            }

        }



        qemu_iovec_reset(&local_qiov);

        qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);



        ret = bdrv_co_pwritev(bs->file->bs, image_offset, n_bytes,

                              &local_qiov, 0);

        if (ret < 0) {

            goto fail;

        }



        bytes -= n_bytes;

        offset += n_bytes;

        bytes_done += n_bytes;

    }



    ret = 0;

fail:

    qemu_iovec_destroy(&local_qiov);

    qemu_co_mutex_unlock(&s->lock);



    return ret;

}
