[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v4 1/4] block: support compressed write at generic layer
From: |
Vladimir Sementsov-Ogievskiy |
Subject: |
Re: [PATCH v4 1/4] block: support compressed write at generic layer |
Date: |
Thu, 17 Oct 2019 16:18:48 +0000 |
16.10.2019 19:28, Andrey Shinkevich wrote:
> To inform the block layer about writing all the data compressed, we
> introduce the 'compress' command line option. Based on that option, the
> written data will be aligned by the cluster size at the generic layer.
>
> Suggested-by: Roman Kagan <address@hidden>
> Suggested-by: Vladimir Sementsov-Ogievskiy <address@hidden>
> Signed-off-by: Andrey Shinkevich <address@hidden>
> ---
> block.c | 20 +++++++++++++++++++-
> block/io.c | 14 ++++++++++----
> block/qcow2.c | 4 ++++
> blockdev.c | 9 ++++++++-
> include/block/block.h | 1 +
> include/block/block_int.h | 2 ++
> qapi/block-core.json | 6 +++++-
> qemu-options.hx | 6 ++++--
> 8 files changed, 53 insertions(+), 9 deletions(-)
>
> diff --git a/block.c b/block.c
> index 1946fc6..a674920 100644
> --- a/block.c
> +++ b/block.c
> @@ -1418,6 +1418,11 @@ QemuOptsList bdrv_runtime_opts = {
> .type = QEMU_OPT_BOOL,
> .help = "always accept other writers (default: off)",
> },
> + {
> + .name = BDRV_OPT_COMPRESS,
> + .type = QEMU_OPT_BOOL,
> + .help = "compress all writes to the image (default: off)",
> + },
> { /* end of list */ }
> },
> };
> @@ -1545,6 +1550,14 @@ static int bdrv_open_common(BlockDriverState *bs,
> BlockBackend *file,
> }
> pstrcpy(bs->exact_filename, sizeof(bs->exact_filename), bs->filename);
>
> + if (bs->all_write_compressed && !drv->bdrv_co_pwritev_compressed_part) {
> + error_setg(errp, "Compression is not supported for the driver '%s'",
> + drv->format_name);
> + bs->all_write_compressed = false;
> + ret = -ENOTSUP;
> + goto fail_opts;
> + }
> +
> /* Open the image, either directly or using a protocol */
> open_flags = bdrv_open_flags(bs, bs->open_flags);
> node_name = qemu_opt_get(opts, "node-name");
> @@ -2983,6 +2996,11 @@ static BlockDriverState *bdrv_open_inherit(const char
> *filename,
> flags &= ~BDRV_O_RDWR;
> }
>
> + if (!g_strcmp0(qdict_get_try_str(options, BDRV_OPT_COMPRESS), "on") ||
> + qdict_get_try_bool(options, BDRV_OPT_COMPRESS, false)) {
> + bs->all_write_compressed = true;
> + }
> +
> if (flags & BDRV_O_SNAPSHOT) {
> snapshot_options = qdict_new();
> bdrv_temp_snapshot_options(&snapshot_flags, snapshot_options,
> @@ -3208,7 +3226,7 @@ static int bdrv_reset_options_allowed(BlockDriverState
> *bs,
> * in bdrv_reopen_prepare() so they can be left out of @new_opts */
> const char *const common_options[] = {
> "node-name", "discard", "cache.direct", "cache.no-flush",
> - "read-only", "auto-read-only", "detect-zeroes", NULL
> + "read-only", "auto-read-only", "detect-zeroes", "compress", NULL
> };
>
> for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
> diff --git a/block/io.c b/block/io.c
> index f0b86c1..3743a13 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -1360,9 +1360,15 @@ static int coroutine_fn
> bdrv_co_do_copy_on_readv(BdrvChild *child,
> /* This does not change the data on the disk, it is not
> * necessary to flush even in cache=writethrough mode.
> */
> - ret = bdrv_driver_pwritev(bs, cluster_offset, pnum,
> - &local_qiov, 0,
> - BDRV_REQ_WRITE_UNCHANGED);
> + if (bs->all_write_compressed) {
> + ret = bdrv_driver_pwritev_compressed(bs, cluster_offset,
> + pnum, &local_qiov,
> + qiov_offset);
last argument must be 0, we are using local_qiov, so, it's qiov_offset is 0.
> + } else {
> + ret = bdrv_driver_pwritev(bs, cluster_offset, pnum,
> + &local_qiov, 0,
> + BDRV_REQ_WRITE_UNCHANGED);
> + }
> }
>
> if (ret < 0) {
> @@ -1954,7 +1960,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild
> *child,
> } else if (flags & BDRV_REQ_ZERO_WRITE) {
> bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO);
> ret = bdrv_co_do_pwrite_zeroes(bs, offset, bytes, flags);
> - } else if (flags & BDRV_REQ_WRITE_COMPRESSED) {
> + } else if (flags & BDRV_REQ_WRITE_COMPRESSED ||
> bs->all_write_compressed) {
> ret = bdrv_driver_pwritev_compressed(bs, offset, bytes,
> qiov, qiov_offset);
> } else if (bytes <= max_transfer) {
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 7961c05..6b29e16 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -1787,6 +1787,10 @@ static void qcow2_refresh_limits(BlockDriverState *bs,
> Error **errp)
> /* Encryption works on a sector granularity */
> bs->bl.request_alignment = qcrypto_block_get_sector_size(s->crypto);
> }
> + if (bs->all_write_compressed) {
> + bs->bl.request_alignment = MAX(bs->bl.request_alignment,
> + s->cluster_size);
> + }
> bs->bl.pwrite_zeroes_alignment = s->cluster_size;
> bs->bl.pdiscard_alignment = s->cluster_size;
> }
> diff --git a/blockdev.c b/blockdev.c
> index f89e48f..0c0b398 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -471,7 +471,7 @@ static BlockBackend *blockdev_init(const char *file,
> QDict *bs_opts,
> int bdrv_flags = 0;
> int on_read_error, on_write_error;
> bool account_invalid, account_failed;
> - bool writethrough, read_only;
> + bool writethrough, read_only, compress;
> BlockBackend *blk;
> BlockDriverState *bs;
> ThrottleConfig cfg;
> @@ -570,6 +570,7 @@ static BlockBackend *blockdev_init(const char *file,
> QDict *bs_opts,
> }
>
> read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false);
> + compress = qemu_opt_get_bool(opts, BDRV_OPT_COMPRESS, false);
>
> /* init */
> if ((!file || !*file) && !qdict_size(bs_opts)) {
Do we need compress for root state here??
> @@ -595,6 +596,8 @@ static BlockBackend *blockdev_init(const char *file,
> QDict *bs_opts,
> qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY,
> read_only ? "on" : "off");
> qdict_set_default_str(bs_opts, BDRV_OPT_AUTO_READ_ONLY, "on");
> + qdict_set_default_str(bs_opts, BDRV_OPT_COMPRESS,
> + compress ? "on" : "off");
> assert((bdrv_flags & BDRV_O_CACHE_MASK) == 0);
>
> if (runstate_check(RUN_STATE_INMIGRATE)) {
> @@ -4683,6 +4686,10 @@ QemuOptsList qemu_common_drive_opts = {
> .name = BDRV_OPT_READ_ONLY,
> .type = QEMU_OPT_BOOL,
> .help = "open drive file as read-only",
> + },{
> + .name = BDRV_OPT_COMPRESS,
> + .type = QEMU_OPT_BOOL,
> + .help = "compress all writes to image",
> },
>
> THROTTLE_OPTS,
> diff --git a/include/block/block.h b/include/block/block.h
> index 792bb82..7e0a927 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -139,6 +139,7 @@ typedef struct HDGeometry {
> #define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
> #define BDRV_OPT_DISCARD "discard"
> #define BDRV_OPT_FORCE_SHARE "force-share"
> +#define BDRV_OPT_COMPRESS "compress"
>
>
> #define BDRV_SECTOR_BITS 9
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index 05056b3..3fe8923 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -923,6 +923,8 @@ struct BlockDriverState {
>
> /* BdrvChild links to this node may never be frozen */
> bool never_freeze;
> + /* Compress all writes to the image */
> + bool all_write_compressed;
> };
>
> struct BlockBackendRootState {
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index f66553a..6c1684f 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -4014,6 +4014,9 @@
> # @force-share: force share all permission on added nodes.
> # Requires read-only=true. (Since 2.10)
> #
No newlines between parameters above, I think don't add one.
> +# @compress: compress all writes to the image (Since 4.2)
> +# (default: false)
> +#
> # Remaining options are determined by the block driver.
> #
> # Since: 2.9
> @@ -4026,7 +4029,8 @@
> '*read-only': 'bool',
> '*auto-read-only': 'bool',
> '*force-share': 'bool',
> - '*detect-zeroes': 'BlockdevDetectZeroesOptions' },
> + '*detect-zeroes': 'BlockdevDetectZeroesOptions',
> + '*compress': 'bool' },
> 'discriminator': 'driver',
> 'data': {
> 'blkdebug': 'BlockdevOptionsBlkdebug',
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 793d70f..1bfbf1a 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -850,7 +850,7 @@ DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,
> "-blockdev [driver=]driver[,node-name=N][,discard=ignore|unmap]\n"
> " [,cache.direct=on|off][,cache.no-flush=on|off]\n"
> " [,read-only=on|off][,detect-zeroes=on|off|unmap]\n"
> - " [,driver specific parameters...]\n"
> + " [,compress=on|off][,driver specific parameters...]\n"
> " configure a block backend\n", QEMU_ARCH_ALL)
> STEXI
> @item -blockdev @var{option}[,@var{option}[,@var{option}[,...]]]
> @@ -905,6 +905,8 @@ discard requests.
> conversion of plain zero writes by the OS to driver specific optimized
> zero write commands. You may even choose "unmap" if @var{discard} is set
> to "unmap" to allow a zero write to be converted to an @code{unmap}
> operation.
> +@item compress
> +Compress all writes to the image.
> @end table
>
> @item Driver-specific options for @code{file}
> @@ -1026,7 +1028,7 @@ DEF("drive", HAS_ARG, QEMU_OPTION_drive,
> "
> [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n"
> " [,snapshot=on|off][,rerror=ignore|stop|report]\n"
> "
> [,werror=ignore|stop|report|enospc][,id=name][,aio=threads|native]\n"
> - " [,readonly=on|off][,copy-on-read=on|off]\n"
> + " [,readonly=on|off][,copy-on-read=on|off][,compress=on|off]\n"
> " [,discard=ignore|unmap][,detect-zeroes=on|off|unmap]\n"
> " [[,bps=b]|[[,bps_rd=r][,bps_wr=w]]]\n"
> " [[,iops=i]|[[,iops_rd=r][,iops_wr=w]]]\n"
>
With extra new line dropped and qiov_offset fixed to zero:
Reviewed-by: Vladimir Sementsov-Ogievskiy <address@hidden>
But, I can't be really sure, as I see from this patch, we have so many ways for
a simple option, and so many places where it should be added.. I just don't see
anything wrong (except for qiov_offset), so if tests work, it's OK for me.
Hope someone who knows the whole options architecture will look at it.
--
Best regards,
Vladimir
- [PATCH v4 0/4] qcow2: advanced compression options, Andrey Shinkevich, 2019/10/16
- [PATCH v4 4/4] tests/qemu-iotests: add case for block-stream compress, Andrey Shinkevich, 2019/10/16
- [PATCH v4 3/4] tests/qemu-iotests: add case to write compressed data of multiple clusters, Andrey Shinkevich, 2019/10/16
- [PATCH v4 1/4] block: support compressed write at generic layer, Andrey Shinkevich, 2019/10/16
- Re: [PATCH v4 1/4] block: support compressed write at generic layer,
Vladimir Sementsov-Ogievskiy <=
- [PATCH v4 2/4] qcow2: Allow writing compressed data of multiple clusters, Andrey Shinkevich, 2019/10/16
- Re: [PATCH v4 0/4] qcow2: advanced compression options, no-reply, 2019/10/16
- Re: [PATCH v4 0/4] qcow2: advanced compression options, no-reply, 2019/10/16