block: Add bdrv_supports_compressed_writes()

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>
Reviewed-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Max Reitz 2019-06-12 22:57:15 +02:00 committed by Kevin Wolf
parent 8b8277cdb0
commit ae23f78646
2 changed files with 24 additions and 0 deletions

23
block.c
View File

@ -5065,6 +5065,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;

View File

@ -532,6 +532,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);