static int vmdk_read(BlockDriverState *bs, int64_t sector_num,

                    uint8_t *buf, int nb_sectors)

{

    BDRVVmdkState *s = bs->opaque;

    int ret;

    uint64_t n, index_in_cluster;

    VmdkExtent *extent = NULL;

    uint64_t cluster_offset;



    while (nb_sectors > 0) {

        extent = find_extent(s, sector_num, extent);

        if (!extent) {

            return -EIO;

        }

        ret = get_cluster_offset(

                            bs, extent, NULL,

                            sector_num << 9, 0, &cluster_offset);

        index_in_cluster = sector_num % extent->cluster_sectors;

        n = extent->cluster_sectors - index_in_cluster;

        if (n > nb_sectors) {

            n = nb_sectors;

        }

        if (ret) {

            /* if not allocated, try to read from parent image, if exist */

            if (bs->backing_hd) {

                if (!vmdk_is_cid_valid(bs)) {

                    return -EINVAL;

                }

                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);

                if (ret < 0) {

                    return ret;

                }

            } else {

                memset(buf, 0, 512 * n);

            }

        } else {

            ret = vmdk_read_extent(extent,

                            cluster_offset, index_in_cluster * 512,

                            buf, n);

            if (ret) {

                return ret;

            }

        }

        nb_sectors -= n;

        sector_num += n;

        buf += n * 512;

    }

    return 0;

}

static int vmdk_read(BlockDriverState *bs, int64_t sector_num,

                    uint8_t *buf, int nb_sectors)

{

    BDRVVmdkState *s = bs->opaque;

    int ret;

    uint64_t n, index_in_cluster;

    VmdkExtent *extent = NULL;

    uint64_t cluster_offset;



    while (nb_sectors > 0) {

        extent = find_extent(s, sector_num, extent);

        if (!extent) {

            return -EIO;

        }

        ret = get_cluster_offset(

                            bs, extent, NULL,

                            sector_num << 9, 0, &cluster_offset);

        index_in_cluster = sector_num % extent->cluster_sectors;

        n = extent->cluster_sectors - index_in_cluster;

        if (n > nb_sectors) {

            n = nb_sectors;

        }

        if (ret) {

            

            if (bs->backing_hd) {

                if (!vmdk_is_cid_valid(bs)) {

                    return -EINVAL;

                }

                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);

                if (ret < 0) {

                    return ret;

                }

            } else {

                memset(buf, 0, 512 * n);

            }

        } else {

            ret = vmdk_read_extent(extent,

                            cluster_offset, index_in_cluster * 512,

                            buf, n);

            if (ret) {

                return ret;

            }

        }

        nb_sectors -= n;

        sector_num += n;

        buf += n * 512;

    }

    return 0;

}

        index_in_cluster = sector_num % extent->cluster_sectors;         index_in_cluster = sector_num % extent->cluster_sectors;
static int FUNC_0(BlockDriverState *VAR_0, int64_t VAR_1,

                    uint8_t *VAR_2, int VAR_3)

{

    BDRVVmdkState *s = VAR_0->opaque;

    int VAR_4;

    uint64_t n, index_in_cluster;

    VmdkExtent *extent = NULL;

    uint64_t cluster_offset;



    while (VAR_3 > 0) {

        extent = find_extent(s, VAR_1, extent);

        if (!extent) {

            return -EIO;

        }

        VAR_4 = get_cluster_offset(

                            VAR_0, extent, NULL,

                            VAR_1 << 9, 0, &cluster_offset);

        index_in_cluster = VAR_1 % extent->cluster_sectors;

        n = extent->cluster_sectors - index_in_cluster;

        if (n > VAR_3) {

            n = VAR_3;

        }

        if (VAR_4) {

            

            if (VAR_0->backing_hd) {

                if (!vmdk_is_cid_valid(VAR_0)) {

                    return -EINVAL;

                }

                VAR_4 = bdrv_read(VAR_0->backing_hd, VAR_1, VAR_2, n);

                if (VAR_4 < 0) {

                    return VAR_4;

                }

            } else {

                memset(VAR_2, 0, 512 * n);

            }

        } else {

            VAR_4 = vmdk_read_extent(extent,

                            cluster_offset, index_in_cluster * 512,

                            VAR_2, n);

            if (VAR_4) {

                return VAR_4;

            }

        }

        VAR_3 -= n;

        VAR_1 += n;

        VAR_2 += n * 512;

    }

    return 0;

}

static int FUNC_0(BlockDriverState *VAR_0, int64_t VAR_1,
uint8_t *VAR_2, int VAR_3)
{ BDRVVmdkState *s = VAR_0->opaque; int VAR_4; uint64_t n, index_in_cluster; VmdkExtent *extent = NULL; uint64_t cluster_offset; while (VAR_3 > 0) { extent = find_extent(s, VAR_1, extent); if (!extent) { return -EIO; } VAR_4 = get_cluster_offset(
VAR_0, extent, NULL,
VAR_1 << 9, 0, &cluster_offset); index_in_cluster = VAR_1 % extent->cluster_sectors; n = extent->cluster_sectors - index_in_cluster; if (n > VAR_3) { n = VAR_3; } if (VAR_4) { if (VAR_0->backing_hd) { if (!vmdk_is_cid_valid(VAR_0)) { return -EINVAL; } VAR_4 = bdrv_read(VAR_0->backing_hd, VAR_1, VAR_2, n); if (VAR_4 < 0) { return VAR_4; } } else { memset(VAR_2, 0, 512 * n); } } else { VAR_4 = vmdk_read_extent(extent,
cluster_offset, index_in_cluster * 512,
VAR_2, n); if (VAR_4) { return VAR_4; } } VAR_3 -= n; VAR_1 += n; VAR_2 += n * 512; } return 0; }