static int get_block_status(BlockDriverState *bs, int64_t sector_num,

                            int nb_sectors, MapEntry *e)

{

    int64_t ret;

    int depth;



    /* As an optimization, we could cache the current range of unallocated

     * clusters in each file of the chain, and avoid querying the same

     * range repeatedly.

     */



    depth = 0;

    for (;;) {

        ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &nb_sectors);

        if (ret < 0) {

            return ret;

        }

        assert(nb_sectors);

        if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) {

            break;

        }

        bs = backing_bs(bs);

        if (bs == NULL) {

            ret = 0;

            break;

        }



        depth++;

    }



    e->start = sector_num * BDRV_SECTOR_SIZE;

    e->length = nb_sectors * BDRV_SECTOR_SIZE;

    e->flags = ret & ~BDRV_BLOCK_OFFSET_MASK;

    e->offset = ret & BDRV_BLOCK_OFFSET_MASK;

    e->depth = depth;

    e->bs = bs;

    return 0;

}

static int get_block_status(BlockDriverState *bs, int64_t sector_num,

                            int nb_sectors, MapEntry *e)

{

    int64_t ret;

    int depth;



    









    depth = 0;

    for (;;) {

        ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &nb_sectors);

        if (ret < 0) {

            return ret;

        }

        assert(nb_sectors);

        if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) {

            break;

        }

        bs = backing_bs(bs);

        if (bs == NULL) {

            ret = 0;

            break;

        }



        depth++;

    }



    e->start = sector_num * BDRV_SECTOR_SIZE;

    e->length = nb_sectors * BDRV_SECTOR_SIZE;

    e->flags = ret & ~BDRV_BLOCK_OFFSET_MASK;

    e->offset = ret & BDRV_BLOCK_OFFSET_MASK;

    e->depth = depth;

    e->bs = bs;

    return 0;

}

static int FUNC_0(BlockDriverState *VAR_0, int64_t VAR_1,

                            int VAR_2, MapEntry *VAR_3)

{

    int64_t ret;

    int VAR_4;



    









    VAR_4 = 0;

    for (;;) {

        ret = bdrv_get_block_status(VAR_0, VAR_1, VAR_2, &VAR_2);

        if (ret < 0) {

            return ret;

        }

        assert(VAR_2);

        if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) {

            break;

        }

        VAR_0 = backing_bs(VAR_0);

        if (VAR_0 == NULL) {

            ret = 0;

            break;

        }



        VAR_4++;

    }



    VAR_3->start = VAR_1 * BDRV_SECTOR_SIZE;

    VAR_3->length = VAR_2 * BDRV_SECTOR_SIZE;

    VAR_3->flags = ret & ~BDRV_BLOCK_OFFSET_MASK;

    VAR_3->offset = ret & BDRV_BLOCK_OFFSET_MASK;

    VAR_3->VAR_4 = VAR_4;

    VAR_3->VAR_0 = VAR_0;

    return 0;

}

static int FUNC_0(BlockDriverState *VAR_0, int64_t VAR_1,
int VAR_2, MapEntry *VAR_3)
{ int64_t ret; int VAR_4; VAR_4 = 0; for (;;) { ret = bdrv_get_block_status(VAR_0, VAR_1, VAR_2, &VAR_2); if (ret < 0) { return ret; } assert(VAR_2); if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) { break; } VAR_0 = backing_bs(VAR_0); if (VAR_0 == NULL) { ret = 0; break; } VAR_4++; } VAR_3->start = VAR_1 * BDRV_SECTOR_SIZE; VAR_3->length = VAR_2 * BDRV_SECTOR_SIZE; VAR_3->flags = ret & ~BDRV_BLOCK_OFFSET_MASK; VAR_3->offset = ret & BDRV_BLOCK_OFFSET_MASK; VAR_3->VAR_4 = VAR_4; VAR_3->VAR_0 = VAR_0; return 0; }