Message ID | 20200625152215.941773-8-mreitz@redhat.com |
---|---|
State | New |
Headers | show |
Series | block: Deal with filters | expand |
On 25.06.2020 18:21, Max Reitz wrote: > Filters cannot compress data themselves but they have to implement > .bdrv_co_pwritev_compressed() still (or they cannot forward compressed > writes). Therefore, checking whether > bs->drv->bdrv_co_pwritev_compressed is non-NULL is not sufficient to > know whether the node can actually handle compressed writes. This > function looks down the filter chain to see whether there is a > non-filter that can actually convert the compressed writes into > compressed data (and thus normal writes). > > Signed-off-by: Max Reitz <mreitz@redhat.com> > --- > include/block/block.h | 1 + > block.c | 23 +++++++++++++++++++++++ > 2 files changed, 24 insertions(+) > > diff --git a/include/block/block.h b/include/block/block.h > index 0080fe1311..a905a5ec05 100644 > --- a/include/block/block.h > +++ b/include/block/block.h > @@ -538,6 +538,7 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it); > void bdrv_next_cleanup(BdrvNextIterator *it); > > BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs); > +bool bdrv_supports_compressed_writes(BlockDriverState *bs); > void bdrv_iterate_format(void (*it)(void *opaque, const char *name), > void *opaque, bool read_only); > const char *bdrv_get_node_name(const BlockDriverState *bs); > diff --git a/block.c b/block.c > index 76277ea4e0..6449f3a11d 100644 > --- a/block.c > +++ b/block.c > @@ -5044,6 +5044,29 @@ bool bdrv_is_sg(BlockDriverState *bs) > return bs->sg; > } > > +/** > + * Return whether the given node supports compressed writes. > + */ > +bool bdrv_supports_compressed_writes(BlockDriverState *bs) > +{ > + BlockDriverState *filtered; > + > + if (!bs->drv || !block_driver_can_compress(bs->drv)) { > + return false; > + } > + > + filtered = bdrv_filter_bs(bs); > + if (filtered) { > + /* > + * Filters can only forward compressed writes, so we have to > + * check the child. > + */ > + return bdrv_supports_compressed_writes(filtered); > + } > + > + return true; > +} > + > const char *bdrv_get_format_name(BlockDriverState *bs) > { > return bs->drv ? bs->drv->format_name : NULL; Reviewed-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
diff --git a/include/block/block.h b/include/block/block.h index 0080fe1311..a905a5ec05 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -538,6 +538,7 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it); void bdrv_next_cleanup(BdrvNextIterator *it); BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs); +bool bdrv_supports_compressed_writes(BlockDriverState *bs); void bdrv_iterate_format(void (*it)(void *opaque, const char *name), void *opaque, bool read_only); const char *bdrv_get_node_name(const BlockDriverState *bs); diff --git a/block.c b/block.c index 76277ea4e0..6449f3a11d 100644 --- a/block.c +++ b/block.c @@ -5044,6 +5044,29 @@ bool bdrv_is_sg(BlockDriverState *bs) return bs->sg; } +/** + * Return whether the given node supports compressed writes. + */ +bool bdrv_supports_compressed_writes(BlockDriverState *bs) +{ + BlockDriverState *filtered; + + if (!bs->drv || !block_driver_can_compress(bs->drv)) { + return false; + } + + filtered = bdrv_filter_bs(bs); + if (filtered) { + /* + * Filters can only forward compressed writes, so we have to + * check the child. + */ + return bdrv_supports_compressed_writes(filtered); + } + + return true; +} + const char *bdrv_get_format_name(BlockDriverState *bs) { return bs->drv ? bs->drv->format_name : NULL;
Filters cannot compress data themselves but they have to implement .bdrv_co_pwritev_compressed() still (or they cannot forward compressed writes). Therefore, checking whether bs->drv->bdrv_co_pwritev_compressed is non-NULL is not sufficient to know whether the node can actually handle compressed writes. This function looks down the filter chain to see whether there is a non-filter that can actually convert the compressed writes into compressed data (and thus normal writes). Signed-off-by: Max Reitz <mreitz@redhat.com> --- include/block/block.h | 1 + block.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+)