From 90418df62498257b19963b33a71285e6db623534 Mon Sep 17 00:00:00 2001 Message-Id: <90418df62498257b19963b33a71285e6db623534.1350493760.git.minovotn@redhat.com> In-Reply-To: References: From: Jeffrey Cody Date: Wed, 17 Oct 2012 05:59:22 +0200 Subject: [PATCH 09/35] stream: move is_allocated_above to block.c RH-Author: Jeffrey Cody Message-id: Patchwork-id: 43265 O-Subject: [RHEL6.4 qemu-kvm PATCH v4 09/35] stream: move is_allocated_above to block.c Bugzilla: 767233 RH-Acked-by: Paolo Bonzini RH-Acked-by: Eric Blake RH-Acked-by: Kevin Wolf From: Paolo Bonzini Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf (cherry picked from commit 188a7bbf94aa53019ef7d2438c8e9d900e590091) Conflicts: block.c Signed-off-by: Jeff Cody --- block.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ block.h | 4 ++++ block/stream.c | 53 ++--------------------------------------------------- 3 files changed, 55 insertions(+), 51 deletions(-) Signed-off-by: Michal Novotny --- block.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ block.h | 4 ++++ block/stream.c | 53 ++--------------------------------------------------- 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/block.c b/block.c index 7dd4e6b..a2cc214 100644 --- a/block.c +++ b/block.c @@ -2209,6 +2209,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; +} + static void bdrv_print_dict(QObject *obj, void *opaque) { QDict *bs_dict; diff --git a/block.h b/block.h index 9eb1d96..8fe6708 100644 --- a/block.h +++ b/block.h @@ -160,6 +160,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); diff --git a/block/stream.c b/block/stream.c index de76f76..f03c934 100644 --- a/block/stream.c +++ b/block/stream.c @@ -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) { -- 1.7.11.7