qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v4 1/6] block-commit: Expose granularity


From: Fam Zheng
Subject: Re: [Qemu-devel] [PATCH v4 1/6] block-commit: Expose granularity
Date: Wed, 16 Apr 2014 09:40:29 +0800
User-agent: Mutt/1.5.23 (2014-03-12)

On Sat, 04/12 20:57, Max Reitz wrote:
> Allow QMP users to manipulate the granularity used in the block-commit
> command.
> 
> Signed-off-by: Max Reitz <address@hidden>
> Reviewed-by: Eric Blake <address@hidden>
> ---
>  block/commit.c            | 16 +++++++++++++---
>  block/mirror.c            |  4 ++--
>  blockdev.c                | 22 ++++++++++++++++------
>  include/block/block_int.h | 10 ++++++----
>  qapi-schema.json          |  6 +++++-
>  5 files changed, 42 insertions(+), 16 deletions(-)
> 
> diff --git a/block/commit.c b/block/commit.c
> index acec4ac..cf0e500 100644
> --- a/block/commit.c
> +++ b/block/commit.c
> @@ -37,6 +37,7 @@ typedef struct CommitBlockJob {
>      BlockdevOnError on_error;
>      int base_flags;
>      int orig_overlay_flags;
> +    int64_t granularity;
>  } CommitBlockJob;
>  
>  static int coroutine_fn commit_populate(BlockDriverState *bs,
> @@ -93,7 +94,7 @@ static void coroutine_fn commit_run(void *opaque)
>      }
>  
>      end = s->common.len >> BDRV_SECTOR_BITS;
> -    buf = qemu_blockalign(top, COMMIT_BUFFER_SIZE);
> +    buf = qemu_blockalign(top, s->granularity);
>  
>      for (sector_num = 0; sector_num < end; sector_num += n) {
>          uint64_t delay_ns = 0;
> @@ -109,7 +110,7 @@ wait:
>          }
>          /* Copy if allocated above the base */
>          ret = bdrv_is_allocated_above(top, base, sector_num,
> -                                      COMMIT_BUFFER_SIZE / BDRV_SECTOR_SIZE,
> +                                      s->granularity / BDRV_SECTOR_SIZE,
>                                        &n);
>          copy = (ret == 1);
>          trace_commit_one_iteration(s, sector_num, n, ret);
> @@ -180,7 +181,7 @@ static const BlockJobDriver commit_job_driver = {
>  };
>  
>  void commit_start(BlockDriverState *bs, BlockDriverState *base,
> -                  BlockDriverState *top, int64_t speed,
> +                  BlockDriverState *top, int64_t speed, int64_t granularity,
>                    BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
>                    void *opaque, Error **errp)
>  {
> @@ -214,6 +215,13 @@ void commit_start(BlockDriverState *bs, BlockDriverState 
> *base,
>      orig_base_flags    = bdrv_get_flags(base);
>      orig_overlay_flags = bdrv_get_flags(overlay_bs);
>  
> +    if (!granularity) {
> +        granularity = COMMIT_BUFFER_SIZE;
> +    }
> +
> +    assert(granularity >= BDRV_SECTOR_SIZE);
> +    assert(is_power_of_2(granularity));
> +
>      /* convert base & overlay_bs to r/w, if necessary */
>      if (!(orig_base_flags & BDRV_O_RDWR)) {
>          reopen_queue = bdrv_reopen_queue(reopen_queue, base,
> @@ -244,6 +252,8 @@ void commit_start(BlockDriverState *bs, BlockDriverState 
> *base,
>      s->base_flags          = orig_base_flags;
>      s->orig_overlay_flags  = orig_overlay_flags;
>  
> +    s->granularity = granularity;
> +
>      s->on_error = on_error;
>      s->common.co = qemu_coroutine_create(commit_run);
>  
> diff --git a/block/mirror.c b/block/mirror.c
> index 0ef41f9..5b1ebb2 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -632,7 +632,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState 
> *target,
>  }
>  
>  void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
> -                         int64_t speed,
> +                         int64_t speed, int64_t granularity,
>                           BlockdevOnError on_error,
>                           BlockDriverCompletionFunc *cb,
>                           void *opaque, Error **errp)
> @@ -674,7 +674,7 @@ void commit_active_start(BlockDriverState *bs, 
> BlockDriverState *base,
>      }
>  
>      bdrv_ref(base);
> -    mirror_start_job(bs, base, speed, 0, 0,
> +    mirror_start_job(bs, base, speed, granularity, 0,
>                       on_error, on_error, cb, opaque, &local_err,
>                       &commit_active_job_driver, false, base);
>      if (error_is_set(&local_err)) {
> diff --git a/blockdev.c b/blockdev.c
> index 5dd01ea..9d7bd04 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -1865,8 +1865,8 @@ void qmp_block_stream(const char *device, bool has_base,
>  
>  void qmp_block_commit(const char *device,
>                        bool has_base, const char *base, const char *top,
> -                      bool has_speed, int64_t speed,
> -                      Error **errp)
> +                      bool has_speed, int64_t speed, bool has_granularity,
> +                      int64_t granularity, Error **errp)
>  {
>      BlockDriverState *bs;
>      BlockDriverState *base_bs, *top_bs;
> @@ -1879,6 +1879,16 @@ void qmp_block_commit(const char *device,
>      if (!has_speed) {
>          speed = 0;
>      }
> +    if (!has_granularity) {
> +        granularity = 0;
> +    }
> +
> +    if (granularity &&
> +        (granularity < BDRV_SECTOR_SIZE || !is_power_of_2(granularity)))
> +    {
> +        error_set(errp, QERR_INVALID_PARAMETER, "granularity");
> +        return;
> +    }
>  
>      /* drain all i/o before commits */
>      bdrv_drain_all();
> @@ -1915,11 +1925,11 @@ void qmp_block_commit(const char *device,
>      }
>  
>      if (top_bs == bs) {
> -        commit_active_start(bs, base_bs, speed, on_error, block_job_cb,
> -                            bs, &local_err);
> +        commit_active_start(bs, base_bs, speed, granularity, on_error,
> +                            block_job_cb, bs, &local_err);
>      } else {
> -        commit_start(bs, base_bs, top_bs, speed, on_error, block_job_cb, bs,
> -                    &local_err);
> +        commit_start(bs, base_bs, top_bs, speed, granularity, on_error,
> +                     block_job_cb, bs, &local_err);
>      }
>      if (local_err != NULL) {
>          error_propagate(errp, local_err);
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index cd5bc73..c01b4aa 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -426,6 +426,7 @@ void stream_start(BlockDriverState *bs, BlockDriverState 
> *base,
>   * @top: Top block device to be committed.
>   * @base: Block device that will be written into, and become the new top.
>   * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
> + * @granularity: The granularity, in bytes, or 0 for a default value.
>   * @on_error: The action to take upon error.
>   * @cb: Completion function for the job.
>   * @opaque: Opaque pointer value passed to @cb.
> @@ -433,14 +434,15 @@ void stream_start(BlockDriverState *bs, 
> BlockDriverState *base,
>   *
>   */
>  void commit_start(BlockDriverState *bs, BlockDriverState *base,
> -                 BlockDriverState *top, int64_t speed,
> -                 BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
> -                 void *opaque, Error **errp);
> +                  BlockDriverState *top, int64_t speed, int64_t granularity,
> +                  BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
> +                  void *opaque, Error **errp);
>  /**
>   * commit_active_start:
>   * @bs: Active block device to be committed.
>   * @base: Block device that will be written into, and become the new top.
>   * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
> + * @granularity: The granularity, in bytes, or 0 for cluster size.
>   * @on_error: The action to take upon error.
>   * @cb: Completion function for the job.
>   * @opaque: Opaque pointer value passed to @cb.
> @@ -448,7 +450,7 @@ void commit_start(BlockDriverState *bs, BlockDriverState 
> *base,
>   *
>   */
>  void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
> -                         int64_t speed,
> +                         int64_t speed, int64_t granularity,
>                           BlockdevOnError on_error,
>                           BlockDriverCompletionFunc *cb,
>                           void *opaque, Error **errp);
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 391356f..151fad3 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2112,6 +2112,10 @@
>  #
>  # @speed:  #optional the maximum speed, in bytes per second
>  #
> +# @granularity: #optional the granularity to be used for the operation, in
> +#               bytes; has to be a power of two and at least 512, or 0 for 
> the
> +#               default value (since 2.1)
> +#
>  # Returns: Nothing on success
>  #          If commit or stream is already active on this device, DeviceInUse
>  #          If @device does not exist, DeviceNotFound
> @@ -2124,7 +2128,7 @@
>  ##
>  { 'command': 'block-commit',
>    'data': { 'device': 'str', '*base': 'str', 'top': 'str',
> -            '*speed': 'int' } }
> +            '*speed': 'int', '*granularity': 'int' } }
>  
>  ##
>  # @drive-backup
> -- 
> 1.9.2
> 
> 

Reviewed-by: Fam Zheng <address@hidden>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]