All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>, Fam Zheng <famz@redhat.com>,
	qemu-devel@nongnu.org, xiawenc@linux.vnet.ibm.com,
	imain@redhat.com, dietmar@proxmox.com
Subject: Re: [Qemu-devel] [PATCH v3 1/8] block: add bdrv_add_before_write_cb()
Date: Wed, 15 May 2013 16:42:57 +0200	[thread overview]
Message-ID: <51939EF1.6050800@redhat.com> (raw)
In-Reply-To: <1368628476-19622-2-git-send-email-stefanha@redhat.com>

Il 15/05/2013 16:34, Stefan Hajnoczi ha scritto:
> The bdrv_add_before_write_cb() function installs a callback that is
> invoked before a write request is processed.  This will be used to
> implement copy-on-write point-in-time snapshots where we need to copy
> out old data before overwriting it.

Perhaps a notifier list that receives the BdrvTrackedRequest?  (BTW we
should probably remove all the notifier_remove wrappers, they're useless).

The BdrvTrackedRequest pointer would also act as a unique id of the request.

> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
>  block.c                   | 37 +++++++++++++++++++++++++++++++++++++
>  include/block/block_int.h | 32 ++++++++++++++++++++++++++++++++
>  2 files changed, 69 insertions(+)
> 
> diff --git a/block.c b/block.c
> index 3f87489..0fd7167 100644
> --- a/block.c
> +++ b/block.c
> @@ -308,6 +308,7 @@ BlockDriverState *bdrv_new(const char *device_name)
>      }
>      bdrv_iostatus_disable(bs);
>      notifier_list_init(&bs->close_notifiers);
> +    QTAILQ_INIT(&bs->before_write_cbs);
>  
>      return bs;
>  }
> @@ -1383,6 +1384,8 @@ void bdrv_close(BlockDriverState *bs)
>          bs->growable = 0;
>          QDECREF(bs->options);
>          bs->options = NULL;
> +        assert(QTAILQ_EMPTY(&bs->before_write_cbs));
> +        QTAILQ_INIT(&bs->before_write_cbs);

INIT not needed if you assert before.

Paolo

>  
>          if (bs->file != NULL) {
>              bdrv_delete(bs->file);
> @@ -2587,6 +2590,22 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
>      return ret;
>  }
>  
> +struct BDRVBeforeWrite {
> +    BDRVBeforeWriteFunc *cb;
> +    QTAILQ_ENTRY(BDRVBeforeWrite) list;
> +};
> +
> +static void invoke_before_write_cb(BlockDriverState *bs, int64_t sector_num,
> +                                   int nb_sectors, QEMUIOVector *qiov)
> +{
> +    BDRVBeforeWrite *before_write;
> +    BDRVBeforeWrite *tmp;
> +    QTAILQ_FOREACH_SAFE(before_write, &bs->before_write_cbs, list, tmp) {
> +        before_write->cb(bs, sector_num, nb_sectors, qiov);
> +    }
> +}
> +
> +
>  /*
>   * Handle a write request in coroutine context
>   */
> @@ -2619,6 +2638,8 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
>  
>      tracked_request_begin(&req, bs, sector_num, nb_sectors, true);
>  
> +    invoke_before_write_cb(bs, sector_num, nb_sectors, qiov);
> +
>      if (flags & BDRV_REQ_ZERO_WRITE) {
>          ret = bdrv_co_do_write_zeroes(bs, sector_num, nb_sectors);
>      } else {
> @@ -4883,3 +4904,19 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs)
>      /* Currently BlockDriverState always uses the main loop AioContext */
>      return qemu_get_aio_context();
>  }
> +
> +BDRVBeforeWrite *bdrv_add_before_write_cb(BlockDriverState *bs,
> +                                          BDRVBeforeWriteFunc *cb)
> +{
> +    BDRVBeforeWrite *elem = g_slice_new(BDRVBeforeWrite);
> +    elem->cb = cb;
> +    QTAILQ_INSERT_TAIL(&bs->before_write_cbs, elem, list);
> +    return elem;
> +}
> +
> +void bdrv_remove_before_write_cb(BlockDriverState *bs,
> +                                 BDRVBeforeWrite *before_write)
> +{
> +    QTAILQ_REMOVE(&bs->before_write_cbs, before_write, list);
> +    g_slice_free(BDRVBeforeWrite, before_write);
> +}
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index 6078dd3..e2299df 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -211,6 +211,16 @@ struct BlockDriver {
>      QLIST_ENTRY(BlockDriver) list;
>  };
>  
> +/**
> + * BDRVBeforeWriteFunc:
> + *
> + * See #bdrv_add_before_write_cb().
> + */
> +typedef void coroutine_fn BDRVBeforeWriteFunc(BlockDriverState *bs,
> +        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
> +
> +typedef struct BDRVBeforeWrite BDRVBeforeWrite;
> +
>  /*
>   * Note: the function bdrv_append() copies and swaps contents of
>   * BlockDriverStates, so if you add new fields to this struct, please
> @@ -289,6 +299,9 @@ struct BlockDriverState {
>      /* long-running background operation */
>      BlockJob *job;
>  
> +    /* Callback before write request is processed */
> +    QTAILQ_HEAD(, BDRVBeforeWrite) before_write_cbs;
> +
>      QDict *options;
>  };
>  
> @@ -298,6 +311,25 @@ void bdrv_set_io_limits(BlockDriverState *bs,
>                          BlockIOLimit *io_limits);
>  
>  /**
> + * bdrv_add_before_write_cb:
> + *
> + * Register a callback that is invoked before write requests are processed but
> + * after any throttling or waiting for overlapping requests.
> + *
> + * Returns: a #BDRVBeforeWrite to use with bdrv_remove_before_write_cb()
> + */
> +BDRVBeforeWrite *bdrv_add_before_write_cb(BlockDriverState *bs,
> +                                          BDRVBeforeWriteFunc *cb);
> +
> +/**
> + * bdrv_remove_before_write_cb:
> + *
> + * Unregister a before write callback.
> + */
> +void bdrv_remove_before_write_cb(BlockDriverState *bs,
> +                                 BDRVBeforeWrite *before_write);
> +
> +/**
>   * bdrv_get_aio_context:
>   *
>   * Returns: the currently bound #AioContext
> 

  reply	other threads:[~2013-05-15 14:43 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-15 14:34 [Qemu-devel] [PATCH v3 0/8] block: drive-backup live backup command Stefan Hajnoczi
2013-05-15 14:34 ` [Qemu-devel] [PATCH v3 1/8] block: add bdrv_add_before_write_cb() Stefan Hajnoczi
2013-05-15 14:42   ` Paolo Bonzini [this message]
2013-05-16  2:42     ` Wenchao Xia
2013-05-16  8:11     ` Stefan Hajnoczi
2013-05-15 14:34 ` [Qemu-devel] [PATCH v3 2/8] block: add basic backup support to block driver Stefan Hajnoczi
2013-05-16  3:27   ` Wenchao Xia
2013-05-16  7:30     ` Stefan Hajnoczi
2013-05-20 11:30   ` Paolo Bonzini
2013-05-21 13:34     ` Stefan Hajnoczi
2013-05-21 15:11       ` Paolo Bonzini
2013-05-21 15:25         ` Dietmar Maurer
2013-05-21 15:35           ` Paolo Bonzini
2013-05-21 15:54             ` Dietmar Maurer
2013-05-21 16:03               ` Paolo Bonzini
2013-05-21 16:15                 ` Dietmar Maurer
2013-05-21 16:26         ` Dietmar Maurer
2013-05-21 16:46           ` Paolo Bonzini
2013-05-22 13:37             ` Stefan Hajnoczi
2013-05-15 14:34 ` [Qemu-devel] [PATCH v3 3/8] block: add drive-backup QMP command Stefan Hajnoczi
2013-05-15 19:04   ` Eric Blake
2013-05-16  7:31     ` Stefan Hajnoczi
2013-05-15 14:34 ` [Qemu-devel] [PATCH v3 4/8] qemu-iotests: add 055 drive-backup test case Stefan Hajnoczi
2013-05-15 14:34 ` [Qemu-devel] [PATCH v3 5/8] blockdev: rename BlkTransactionStates to singular Stefan Hajnoczi
2013-05-15 19:09   ` Eric Blake
2013-05-16  2:28   ` Wenchao Xia
2013-05-15 14:34 ` [Qemu-devel] [PATCH v3 6/8] blockdev: add DriveBackup transaction Stefan Hajnoczi
2013-05-15 19:13   ` Eric Blake
2013-05-16  7:36     ` Stefan Hajnoczi
2013-05-15 14:34 ` [Qemu-devel] [PATCH v3 7/8] blockdev: add Abort transaction Stefan Hajnoczi
2013-05-15 19:01   ` Eric Blake
2013-05-16  2:26     ` Wenchao Xia
2013-05-16  7:37     ` Stefan Hajnoczi
2013-05-15 14:34 ` [Qemu-devel] [PATCH v3 8/8] qemu-iotests: test 'drive-backup' transaction in 055 Stefan Hajnoczi
2013-05-16  6:16 ` [Qemu-devel] [PATCH v3 0/8] block: drive-backup live backup command Wenchao Xia
2013-05-16  7:47   ` Stefan Hajnoczi
2013-05-17  6:58     ` Wenchao Xia
2013-05-17  9:14       ` Stefan Hajnoczi
2013-05-21  3:25         ` Wenchao Xia
2013-05-21  7:34           ` Stefan Hajnoczi
2013-05-17 10:17     ` Paolo Bonzini
2013-05-20  6:24       ` Stefan Hajnoczi
2013-05-20  7:23         ` Paolo Bonzini
2013-05-21  7:31           ` Stefan Hajnoczi
2013-05-21  8:30             ` Paolo Bonzini
2013-05-21 10:34               ` Stefan Hajnoczi
2013-05-21 10:36                 ` Paolo Bonzini
2013-05-21 10:58                   ` Dietmar Maurer
2013-05-22 13:43                     ` Stefan Hajnoczi
2013-05-22 15:10                       ` Dietmar Maurer
2013-05-22 15:34                       ` Dietmar Maurer
2013-05-23  8:04                         ` Stefan Hajnoczi
2013-05-23  8:11                           ` Dietmar Maurer
2013-05-24  8:38                             ` Stefan Hajnoczi
2013-05-24  9:53                               ` Dietmar Maurer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51939EF1.6050800@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=dietmar@proxmox.com \
    --cc=famz@redhat.com \
    --cc=imain@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --cc=xiawenc@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.