Loading block.c +49 −0 Original line number Diff line number Diff line Loading @@ -2569,6 +2569,55 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, return data.ret; } /* * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP] * * Return true if the given sector is allocated in any image between * BASE and TOP (inclusive). BASE can be NULL to check if the given * sector is allocated in any image of the chain. Return false otherwise. * * 'pnum' is set to the number of sectors (including and immediately following * the specified sector) that are known to be in the same * allocated/unallocated state. * */ int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, BlockDriverState *base, int64_t sector_num, int nb_sectors, int *pnum) { BlockDriverState *intermediate; int ret, n = nb_sectors; intermediate = top; while (intermediate && 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 1; } /* * [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 0; } BlockInfoList *qmp_query_block(Error **errp) { BlockInfoList *head = NULL, *cur_item = NULL; Loading block.h +4 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,10 @@ int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, BlockDriverState *base, int64_t sector_num, int nb_sectors, int *pnum); BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); int bdrv_truncate(BlockDriverState *bs, int64_t offset); Loading block/stream.c +2 −51 Original line number Diff line number Diff line Loading @@ -98,55 +98,6 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base, top->backing_hd = base; } /* * Given an image chain: [BASE] -> [INTER1] -> [INTER2] -> [TOP] * * Return true if the given sector is allocated in any image between * BASE and TOP (inclusive). BASE can be NULL to check if the given * sector is allocated in any image of the chain. Return false otherwise. * * 'pnum' is set to the number of sectors (including and immediately following * the specified sector) that are known to be in the same * allocated/unallocated state. * */ static int coroutine_fn is_allocated_above(BlockDriverState *top, BlockDriverState *base, int64_t sector_num, int nb_sectors, int *pnum) { BlockDriverState *intermediate; int ret, n = nb_sectors; intermediate = top; 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 1; } /* * [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 0; } static void coroutine_fn stream_run(void *opaque) { StreamBlockJob *s = opaque; Loading Loading @@ -196,10 +147,10 @@ wait: } else { /* Copy if allocated in the intermediate images. Limit to the * known-unallocated area [sector_num, sector_num+n). */ ret = is_allocated_above(bs->backing_hd, base, sector_num, n, &n); ret = bdrv_co_is_allocated_above(bs->backing_hd, base, sector_num, n, &n); copy = (ret == 1); } trace_stream_one_iteration(s, sector_num, n, ret); if (ret >= 0 && copy) { if (s->common.speed) { Loading Loading
block.c +49 −0 Original line number Diff line number Diff line Loading @@ -2569,6 +2569,55 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, return data.ret; } /* * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP] * * Return true if the given sector is allocated in any image between * BASE and TOP (inclusive). BASE can be NULL to check if the given * sector is allocated in any image of the chain. Return false otherwise. * * 'pnum' is set to the number of sectors (including and immediately following * the specified sector) that are known to be in the same * allocated/unallocated state. * */ int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, BlockDriverState *base, int64_t sector_num, int nb_sectors, int *pnum) { BlockDriverState *intermediate; int ret, n = nb_sectors; intermediate = top; while (intermediate && 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 1; } /* * [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 0; } BlockInfoList *qmp_query_block(Error **errp) { BlockInfoList *head = NULL, *cur_item = NULL; Loading
block.h +4 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,10 @@ int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, BlockDriverState *base, int64_t sector_num, int nb_sectors, int *pnum); BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); int bdrv_truncate(BlockDriverState *bs, int64_t offset); Loading
block/stream.c +2 −51 Original line number Diff line number Diff line Loading @@ -98,55 +98,6 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base, top->backing_hd = base; } /* * Given an image chain: [BASE] -> [INTER1] -> [INTER2] -> [TOP] * * Return true if the given sector is allocated in any image between * BASE and TOP (inclusive). BASE can be NULL to check if the given * sector is allocated in any image of the chain. Return false otherwise. * * 'pnum' is set to the number of sectors (including and immediately following * the specified sector) that are known to be in the same * allocated/unallocated state. * */ static int coroutine_fn is_allocated_above(BlockDriverState *top, BlockDriverState *base, int64_t sector_num, int nb_sectors, int *pnum) { BlockDriverState *intermediate; int ret, n = nb_sectors; intermediate = top; 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 1; } /* * [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 0; } static void coroutine_fn stream_run(void *opaque) { StreamBlockJob *s = opaque; Loading Loading @@ -196,10 +147,10 @@ wait: } else { /* Copy if allocated in the intermediate images. Limit to the * known-unallocated area [sector_num, sector_num+n). */ ret = is_allocated_above(bs->backing_hd, base, sector_num, n, &n); ret = bdrv_co_is_allocated_above(bs->backing_hd, base, sector_num, n, &n); copy = (ret == 1); } trace_stream_one_iteration(s, sector_num, n, ret); if (ret >= 0 && copy) { if (s->common.speed) { Loading