static int coroutine_fn is_allocated_base(BlockDriverState *top, BlockDriverState *base, int64_t sector_num, int nb_sectors, int *pnum) { BlockDriverState *intermediate; int ret, n; ret = bdrv_co_is_allocated(top, sector_num, nb_sectors, &n); if (ret) { *pnum = n; return ret; } /* * Is the unallocated chunk [sector_num, n] also * unallocated between base and top? */ intermediate = top->backing_hd; while (intermediate != base) { int pnum_inter; ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors, &pnum_inter); if (ret < 0) { return ret; } else if (ret) { *pnum = pnum_inter; return 0; } /* * [sector_num, nb_sectors] is unallocated on top but intermediate * might have * * [sector_num+x, nr_sectors] allocated. */ if (n > pnum_inter) { n = pnum_inter; } intermediate = intermediate->backing_hd; } *pnum = n; return 1; }