mirror of https://github.com/xemu-project/xemu.git
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;
|
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 *qmp_query_block(Error **errp)
|
||||||
{
|
{
|
||||||
BlockInfoList *head = NULL, *cur_item = NULL;
|
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 nb_sectors);
|
||||||
int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num,
|
int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num,
|
||||||
int nb_sectors, int *pnum);
|
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,
|
BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
|
||||||
const char *backing_file);
|
const char *backing_file);
|
||||||
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
|
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;
|
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)
|
static void coroutine_fn stream_run(void *opaque)
|
||||||
{
|
{
|
||||||
StreamBlockJob *s = opaque;
|
StreamBlockJob *s = opaque;
|
||||||
|
@ -196,10 +147,10 @@ wait:
|
||||||
} else {
|
} else {
|
||||||
/* Copy if allocated in the intermediate images. Limit to the
|
/* Copy if allocated in the intermediate images. Limit to the
|
||||||
* known-unallocated area [sector_num, sector_num+n). */
|
* 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);
|
copy = (ret == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_stream_one_iteration(s, sector_num, n, ret);
|
trace_stream_one_iteration(s, sector_num, n, ret);
|
||||||
if (ret >= 0 && copy) {
|
if (ret >= 0 && copy) {
|
||||||
if (s->common.speed) {
|
if (s->common.speed) {
|
||||||
|
|
Loading…
Reference in New Issue