stream: move is_allocated_above to block.c
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
f9749f28b7
commit
188a7bbf94
49
block.c
49
block.c
@ -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;
|
||||
|
4
block.h
4
block.h
@ -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);
|
||||
|
@ -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;
|
||||
@ -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…
Reference in New Issue
Block a user