Some image formats can represent zero regions efficiently even when a backing file is present. In order to use this feature they need to detect zero writes and handle them specially.
Since zero write detection consumes CPU cycles it is disabled by default and must be explicitly enabled. This patch adds an interface to do so. Currently no block drivers actually support zero write detection yet. This is addressed in follow-up patches. Signed-off-by: Stefan Hajnoczi <stefa...@linux.vnet.ibm.com> --- block.c | 16 ++++++++++++++++ block.h | 2 ++ block_int.h | 13 +++++++++++++ 3 files changed, 31 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index e3fe97f..5cf53d6 100644 --- a/block.c +++ b/block.c @@ -481,6 +481,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename, bs->valid_key = 0; bs->open_flags = flags; bs->buffer_alignment = 512; + bs->use_zero_detection = false; pstrcpy(bs->filename, sizeof(bs->filename), filename); @@ -3344,3 +3345,18 @@ out: return ret; } + +int bdrv_set_zero_detection(BlockDriverState *bs, bool enable) +{ + BlockDriver *drv = bs->drv; + + if (!drv) { + return -ENOMEDIUM; + } + if (!drv->has_zero_detection) { + return -ENOTSUP; + } + + bs->use_zero_detection = enable; + return 0; +} diff --git a/block.h b/block.h index 16bfa0a..283dc27 100644 --- a/block.h +++ b/block.h @@ -273,6 +273,8 @@ int bdrv_img_create(const char *filename, const char *fmt, void bdrv_set_buffer_alignment(BlockDriverState *bs, int align); void *qemu_blockalign(BlockDriverState *bs, size_t size); +int bdrv_set_zero_detection(BlockDriverState *bs, bool enable); + #define BDRV_SECTORS_PER_DIRTY_CHUNK 2048 void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable); diff --git a/block_int.h b/block_int.h index 8c3b863..3e8d768 100644 --- a/block_int.h +++ b/block_int.h @@ -146,6 +146,16 @@ struct BlockDriver { */ int (*bdrv_has_zero_init)(BlockDriverState *bs); + /* + * True if zero write detection is supported, false otherwise. + * + * Block drivers that declare support for zero detection should check + * BlockDriverState.use_zero_detection for each write request to decide + * whether or not to perform detection. Since zero detection consumes CPU + * cycles it is disabled by default. + */ + bool has_zero_detection; + QLIST_ENTRY(BlockDriver) list; }; @@ -195,6 +205,9 @@ struct BlockDriverState { /* do we need to tell the quest if we have a volatile write cache? */ int enable_write_cache; + /* is zero write detection enabled? */ + bool use_zero_detection; + /* NOTE: the following infos are only hints for real hardware drivers. They are not used by the block driver */ int cyls, heads, secs, translation; -- 1.7.6.3