This function finds the common ancestor in backing chain of two BDSes. If there's no common ancestor, NULL is returned.
Signed-off-by: Fam Zheng <f...@redhat.com> --- block.c | 15 +++++++++++++++ include/block/block.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/block.c b/block.c index ea4956d..db1381d 100644 --- a/block.c +++ b/block.c @@ -3036,6 +3036,21 @@ BlockDriverState *bdrv_find(const char *name) return NULL; } +BlockDriverState *bdrv_common_ancestor(BlockDriverState *bs1, + BlockDriverState *bs2) +{ + /* TODO: higher efficiency with reverse linked backing chain */ + BlockDriverState *base1, *base2; + for (base1 = bs1; base1; base1 = base1->backing_hd) { + for (base2 = bs2; base2; base2 = base2->backing_hd) { + if (base1 == base2) { + return base1; + } + } + } + return NULL; +} + BlockDriverState *bdrv_next(BlockDriverState *bs) { if (!bs) { diff --git a/include/block/block.h b/include/block/block.h index f808550..e095f16 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -321,6 +321,8 @@ void bdrv_lock_medium(BlockDriverState *bs, bool locked); void bdrv_eject(BlockDriverState *bs, bool eject_flag); const char *bdrv_get_format_name(BlockDriverState *bs); BlockDriverState *bdrv_find(const char *name); +BlockDriverState *bdrv_common_ancestor(BlockDriverState *bs1, + BlockDriverState *bs2); BlockDriverState *bdrv_next(BlockDriverState *bs); void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque); -- 1.8.3.1