diff options
Diffstat (limited to 'block.c')
| -rw-r--r-- | block.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/block.c b/block.c index 5944124845..1946fc6f57 100644 --- a/block.c +++ b/block.c @@ -5155,6 +5155,15 @@ ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs, return NULL; } +BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs) +{ + BlockDriver *drv = bs->drv; + if (!drv || !drv->bdrv_get_specific_stats) { + return NULL; + } + return drv->bdrv_get_specific_stats(bs); +} + void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event) { if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) { @@ -5164,14 +5173,35 @@ void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event) bs->drv->bdrv_debug_event(bs, event); } -int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, - const char *tag) +static BlockDriverState *bdrv_find_debug_node(BlockDriverState *bs) { while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) { - bs = bs->file ? bs->file->bs : NULL; + if (bs->file) { + bs = bs->file->bs; + continue; + } + + if (bs->drv->is_filter && bs->backing) { + bs = bs->backing->bs; + continue; + } + + break; } if (bs && bs->drv && bs->drv->bdrv_debug_breakpoint) { + assert(bs->drv->bdrv_debug_remove_breakpoint); + return bs; + } + + return NULL; +} + +int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, + const char *tag) +{ + bs = bdrv_find_debug_node(bs); + if (bs) { return bs->drv->bdrv_debug_breakpoint(bs, event, tag); } @@ -5180,11 +5210,8 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag) { - while (bs && bs->drv && !bs->drv->bdrv_debug_remove_breakpoint) { - bs = bs->file ? bs->file->bs : NULL; - } - - if (bs && bs->drv && bs->drv->bdrv_debug_remove_breakpoint) { + bs = bdrv_find_debug_node(bs); + if (bs) { return bs->drv->bdrv_debug_remove_breakpoint(bs, tag); } |