static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,

                            int64_t offset_in_cluster, QEMUIOVector *qiov,

                            uint64_t qiov_offset, uint64_t n_bytes,

                            uint64_t offset)

{

    int ret;

    VmdkGrainMarker *data = NULL;

    uLongf buf_len;

    QEMUIOVector local_qiov;

    struct iovec iov;

    int64_t write_offset;

    int64_t write_end_sector;



    if (extent->compressed) {

        void *compressed_data;



        if (!extent->has_marker) {

            ret = -EINVAL;

            goto out;

        }

        buf_len = (extent->cluster_sectors << 9) * 2;

        data = g_malloc(buf_len + sizeof(VmdkGrainMarker));



        compressed_data = g_malloc(n_bytes);

        qemu_iovec_to_buf(qiov, qiov_offset, compressed_data, n_bytes);

        ret = compress(data->data, &buf_len, compressed_data, n_bytes);

        g_free(compressed_data);



        if (ret != Z_OK || buf_len == 0) {

            ret = -EINVAL;

            goto out;

        }



        data->lba = offset >> BDRV_SECTOR_BITS;

        data->size = buf_len;



        n_bytes = buf_len + sizeof(VmdkGrainMarker);

        iov = (struct iovec) {

            .iov_base   = data,

            .iov_len    = n_bytes,

        };

        qemu_iovec_init_external(&local_qiov, &iov, 1);

    } else {

        qemu_iovec_init(&local_qiov, qiov->niov);

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

    }



    write_offset = cluster_offset + offset_in_cluster,

    ret = bdrv_co_pwritev(extent->file->bs, write_offset, n_bytes,

                          &local_qiov, 0);



    write_end_sector = DIV_ROUND_UP(write_offset + n_bytes, BDRV_SECTOR_SIZE);



    if (extent->compressed) {

        extent->next_cluster_sector = write_end_sector;

    } else {

        extent->next_cluster_sector = MAX(extent->next_cluster_sector,

                                          write_end_sector);

    }



    if (ret < 0) {

        goto out;

    }

    ret = 0;

 out:

    g_free(data);

    if (!extent->compressed) {

        qemu_iovec_destroy(&local_qiov);

    }

    return ret;

}

static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,

                            int64_t offset_in_cluster, QEMUIOVector *qiov,

                            uint64_t qiov_offset, uint64_t n_bytes,

                            uint64_t offset)

{

    int ret;

    VmdkGrainMarker *data = NULL;

    uLongf buf_len;

    QEMUIOVector local_qiov;

    struct iovec iov;

    int64_t write_offset;

    int64_t write_end_sector;



    if (extent->compressed) {

        void *compressed_data;



        if (!extent->has_marker) {

            ret = -EINVAL;

            goto out;

        }

        buf_len = (extent->cluster_sectors << 9) * 2;

        data = g_malloc(buf_len + sizeof(VmdkGrainMarker));



        compressed_data = g_malloc(n_bytes);

        qemu_iovec_to_buf(qiov, qiov_offset, compressed_data, n_bytes);

        ret = compress(data->data, &buf_len, compressed_data, n_bytes);

        g_free(compressed_data);



        if (ret != Z_OK || buf_len == 0) {

            ret = -EINVAL;

            goto out;

        }



        data->lba = offset >> BDRV_SECTOR_BITS;

        data->size = buf_len;



        n_bytes = buf_len + sizeof(VmdkGrainMarker);

        iov = (struct iovec) {

            .iov_base   = data,

            .iov_len    = n_bytes,

        };

        qemu_iovec_init_external(&local_qiov, &iov, 1);

    } else {

        qemu_iovec_init(&local_qiov, qiov->niov);

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

    }



    write_offset = cluster_offset + offset_in_cluster,

    ret = bdrv_co_pwritev(extent->file->bs, write_offset, n_bytes,

                          &local_qiov, 0);



    write_end_sector = DIV_ROUND_UP(write_offset + n_bytes, BDRV_SECTOR_SIZE);



    if (extent->compressed) {

        extent->next_cluster_sector = write_end_sector;

    } else {

        extent->next_cluster_sector = MAX(extent->next_cluster_sector,

                                          write_end_sector);

    }



    if (ret < 0) {

        goto out;

    }

    ret = 0;

 out:

    g_free(data);

    if (!extent->compressed) {

        qemu_iovec_destroy(&local_qiov);

    }

    return ret;

}

static int FUNC_0(VmdkExtent *VAR_0, int64_t VAR_1,

                            int64_t VAR_2, QEMUIOVector *VAR_3,

                            uint64_t VAR_4, uint64_t VAR_5,

                            uint64_t VAR_6)

{

    int VAR_7;

    VmdkGrainMarker *data = NULL;

    uLongf buf_len;

    QEMUIOVector local_qiov;

    struct iovec VAR_8;

    int64_t write_offset;

    int64_t write_end_sector;



    if (VAR_0->compressed) {

        void *VAR_9;



        if (!VAR_0->has_marker) {

            VAR_7 = -EINVAL;

            goto out;

        }

        buf_len = (VAR_0->cluster_sectors << 9) * 2;

        data = g_malloc(buf_len + sizeof(VmdkGrainMarker));



        VAR_9 = g_malloc(VAR_5);

        qemu_iovec_to_buf(VAR_3, VAR_4, VAR_9, VAR_5);

        VAR_7 = compress(data->data, &buf_len, VAR_9, VAR_5);

        g_free(VAR_9);



        if (VAR_7 != Z_OK || buf_len == 0) {

            VAR_7 = -EINVAL;

            goto out;

        }



        data->lba = VAR_6 >> BDRV_SECTOR_BITS;

        data->size = buf_len;



        VAR_5 = buf_len + sizeof(VmdkGrainMarker);

        VAR_8 = (struct iovec) {

            .iov_base   = data,

            .iov_len    = VAR_5,

        };

        qemu_iovec_init_external(&local_qiov, &VAR_8, 1);

    } else {

        qemu_iovec_init(&local_qiov, VAR_3->niov);

        qemu_iovec_concat(&local_qiov, VAR_3, VAR_4, VAR_5);

    }



    write_offset = VAR_1 + VAR_2,

    VAR_7 = bdrv_co_pwritev(VAR_0->file->bs, write_offset, VAR_5,

                          &local_qiov, 0);



    write_end_sector = DIV_ROUND_UP(write_offset + VAR_5, BDRV_SECTOR_SIZE);



    if (VAR_0->compressed) {

        VAR_0->next_cluster_sector = write_end_sector;

    } else {

        VAR_0->next_cluster_sector = MAX(VAR_0->next_cluster_sector,

                                          write_end_sector);

    }



    if (VAR_7 < 0) {

        goto out;

    }

    VAR_7 = 0;

 out:

    g_free(data);

    if (!VAR_0->compressed) {

        qemu_iovec_destroy(&local_qiov);

    }

    return VAR_7;

}

static int FUNC_0(VmdkExtent *VAR_0, int64_t VAR_1,
int64_t VAR_2, QEMUIOVector *VAR_3,
uint64_t VAR_4, uint64_t VAR_5,
uint64_t VAR_6)
{ int VAR_7; VmdkGrainMarker *data = NULL; uLongf buf_len; QEMUIOVector local_qiov; struct iovec VAR_8; int64_t write_offset; int64_t write_end_sector; if (VAR_0->compressed) { void *VAR_9; if (!VAR_0->has_marker) { VAR_7 = -EINVAL; goto out; } buf_len = (VAR_0->cluster_sectors << 9) * 2; data = g_malloc(buf_len + sizeof(VmdkGrainMarker)); VAR_9 = g_malloc(VAR_5); qemu_iovec_to_buf(VAR_3, VAR_4, VAR_9, VAR_5); VAR_7 = compress(data->data, &buf_len, VAR_9, VAR_5); g_free(VAR_9); if (VAR_7 != Z_OK || buf_len == 0) { VAR_7 = -EINVAL; goto out; } data->lba = VAR_6 >> BDRV_SECTOR_BITS; data->size = buf_len; VAR_5 = buf_len + sizeof(VmdkGrainMarker); VAR_8 = (struct iovec) { .iov_base   = data,
.iov_len    = VAR_5,
}; qemu_iovec_init_external(&local_qiov, &VAR_8, 1); } else { qemu_iovec_init(&local_qiov, VAR_3->niov); qemu_iovec_concat(&local_qiov, VAR_3, VAR_4, VAR_5); } write_offset = VAR_1 + VAR_2,
VAR_7 = bdrv_co_pwritev(VAR_0->file->bs, write_offset, VAR_5,
&local_qiov, 0); write_end_sector = DIV_ROUND_UP(write_offset + VAR_5, BDRV_SECTOR_SIZE); if (VAR_0->compressed) { VAR_0->next_cluster_sector = write_end_sector; } else { VAR_0->next_cluster_sector = MAX(VAR_0->next_cluster_sector,
write_end_sector); } if (VAR_7 < 0) { goto out; } VAR_7 = 0; out:
g_free(data); if (!VAR_0->compressed) { qemu_iovec_destroy(&local_qiov); } return VAR_7; }