static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs,

        BlockDriverState *base,

        bool want_zero,

        int64_t sector_num,

        int nb_sectors,

        int *pnum,

        BlockDriverState **file)

{

    BlockDriverState *p;

    int64_t ret = 0;

    bool first = true;



    assert(bs != base);

    for (p = bs; p != base; p = backing_bs(p)) {

        ret = bdrv_co_get_block_status(p, want_zero, sector_num, nb_sectors,

                                       pnum, file);

        if (ret < 0) {

            break;

        }

        if (ret & BDRV_BLOCK_ZERO && ret & BDRV_BLOCK_EOF && !first) {

            /*

             * Reading beyond the end of the file continues to read

             * zeroes, but we can only widen the result to the

             * unallocated length we learned from an earlier

             * iteration.

             */

            *pnum = nb_sectors;

        }

        if (ret & (BDRV_BLOCK_ZERO | BDRV_BLOCK_DATA)) {

            break;

        }

        /* [sector_num, pnum] unallocated on this layer, which could be only

         * the first part of [sector_num, nb_sectors].  */

        nb_sectors = MIN(nb_sectors, *pnum);

        first = false;

    }

    return ret;

}
