static int vmdk_read(BlockDriverState *bs, int64_t sector_num, 

                    uint8_t *buf, int nb_sectors)

{

    BDRVVmdkState *s = bs->opaque;

    int index_in_cluster, n, ret;

    uint64_t cluster_offset;



    while (nb_sectors > 0) {

        cluster_offset = get_cluster_offset(bs, sector_num << 9, 0);

        index_in_cluster = sector_num % s->cluster_sectors;

        n = s->cluster_sectors - index_in_cluster;

        if (n > nb_sectors)

            n = nb_sectors;

        if (!cluster_offset) {

            // try to read from parent image, if exist

            if (s->hd->backing_hd) {

                if (!vmdk_is_cid_valid(bs))

                    return -1;

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

                if (ret < 0)

                    return -1;

            } else {

                memset(buf, 0, 512 * n);

            }

        } else {

            if(bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)

                return -1;

        }

        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 index_in_cluster, n, ret;

    uint64_t cluster_offset;



    while (nb_sectors > 0) {

        cluster_offset = get_cluster_offset(bs, sector_num << 9, 0);

        index_in_cluster = sector_num % s->cluster_sectors;

        n = s->cluster_sectors - index_in_cluster;

        if (n > nb_sectors)

            n = nb_sectors;

        if (!cluster_offset) {

            

            if (s->hd->backing_hd) {

                if (!vmdk_is_cid_valid(bs))

                    return -1;

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

                if (ret < 0)

                    return -1;

            } else {

                memset(buf, 0, 512 * n);

            }

        } else {

            if(bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)

                return -1;

        }

        nb_sectors -= n;

        sector_num += n;

        buf += n * 512;

    }

    return 0;

}

        cluster_offset = get_cluster_offset(bs, sector_num << 9, 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, VAR_5, VAR_6;

    uint64_t cluster_offset;



    while (VAR_3 > 0) {

        cluster_offset = get_cluster_offset(VAR_0, VAR_1 << 9, 0);

        VAR_4 = VAR_1 % s->cluster_sectors;

        VAR_5 = s->cluster_sectors - VAR_4;

        if (VAR_5 > VAR_3)

            VAR_5 = VAR_3;

        if (!cluster_offset) {

            

            if (s->hd->backing_hd) {

                if (!vmdk_is_cid_valid(VAR_0))

                    return -1;

                VAR_6 = bdrv_read(s->hd->backing_hd, VAR_1, VAR_2, VAR_5);

                if (VAR_6 < 0)

                    return -1;

            } else {

                memset(VAR_2, 0, 512 * VAR_5);

            }

        } else {

            if(bdrv_pread(s->hd, cluster_offset + VAR_4 * 512, VAR_2, VAR_5 * 512) != VAR_5 * 512)

                return -1;

        }

        VAR_3 -= VAR_5;

        VAR_1 += VAR_5;

        VAR_2 += VAR_5 * 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, VAR_5, VAR_6; uint64_t cluster_offset; while (VAR_3 > 0) { cluster_offset = get_cluster_offset(VAR_0, VAR_1 << 9, 0); VAR_4 = VAR_1 % s->cluster_sectors; VAR_5 = s->cluster_sectors - VAR_4; if (VAR_5 > VAR_3)
VAR_5 = VAR_3; if (!cluster_offset) { if (s->hd->backing_hd) { if (!vmdk_is_cid_valid(VAR_0))
return -1; VAR_6 = bdrv_read(s->hd->backing_hd, VAR_1, VAR_2, VAR_5); if (VAR_6 < 0)
return -1; } else { memset(VAR_2, 0, 512 * VAR_5); } } else { if(bdrv_pread(s->hd, cluster_offset + VAR_4 * 512, VAR_2, VAR_5 * 512) != VAR_5 * 512)
return -1; } VAR_3 -= VAR_5; VAR_1 += VAR_5; VAR_2 += VAR_5 * 512; } return 0; }