From: Fam Zheng <famz@redhat.com>
To: "Benoît Canet" <benoit@irqsave.net>
Cc: kwolf@redhat.com, jcody@redhat.com, qemu-devel@nongnu.org,
stefanha@redhat.com, armbru@redhat.com
Subject: Re: [Qemu-devel] [PATCH V5 5/7] block: Create authorizations mechanism for external snapshot and resize.
Date: Tue, 21 Jan 2014 11:45:42 +0800 [thread overview]
Message-ID: <20140121034542.GH29842@T430.redhat.com> (raw)
In-Reply-To: <1386862440-8003-6-git-send-email-benoit@irqsave.net>
On Thu, 12/12 16:33, Benoît Canet wrote:
> Signed-off-by: Benoit Canet <benoit@irqsave.net>
> ---
> block.c | 65 ++++++++++++++++++++++++++++++++++++++++-------
> block/blkverify.c | 2 +-
> blockdev.c | 2 +-
> include/block/block.h | 20 +++++++--------
> include/block/block_int.h | 12 ++++++---
> 5 files changed, 77 insertions(+), 24 deletions(-)
>
> diff --git a/block.c b/block.c
> index 22190a4..57946b7 100644
> --- a/block.c
> +++ b/block.c
> @@ -4992,21 +4992,68 @@ int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options)
> return bs->drv->bdrv_amend_options(bs, options);
> }
>
> -ExtSnapshotPerm bdrv_check_ext_snapshot(BlockDriverState *bs)
> +/* Used to recurse on single child block filters.
> + * Single child block filter will store their child in bs->file.
> + */
> +bool bdrv_generic_is_first_non_filter(BlockDriverState *bs,
> + BlockDriverState *candidate)
> {
> - if (bs->drv->bdrv_check_ext_snapshot) {
> - return bs->drv->bdrv_check_ext_snapshot(bs);
> + if (!bs->drv) {
> + return false;
> + }
> +
> + if (!bs->drv->authorizations[BS_IS_A_FILTER]) {
> + if (bs == candidate) {
> + return true;
> + } else {
> + return false;
> + }
> + }
> +
> + if (!bs->drv->authorizations[BS_FILTER_PASS_DOWN]) {
> + return false;
> }
>
> - if (bs->file && bs->file->drv && bs->file->drv->bdrv_check_ext_snapshot) {
> - return bs->file->drv->bdrv_check_ext_snapshot(bs);
> + if (!bs->file) {
> + return false;
> + }
> +
> + return bdrv_recurse_is_first_non_filter(bs->file, candidate);
> +}
> +
> +bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
> + BlockDriverState *candidate)
> +{
> + if (bs->drv && bs->drv->bdrv_recurse_is_first_non_filter) {
> + return bs->drv->bdrv_recurse_is_first_non_filter(bs, candidate);
> }
>
> - /* external snapshots are allowed by default */
> - return EXT_SNAPSHOT_ALLOWED;
> + return bdrv_generic_is_first_non_filter(bs, candidate);
> }
>
> -ExtSnapshotPerm bdrv_check_ext_snapshot_forbidden(BlockDriverState *bs)
> +/* This function check if the candidate is the first non filter bs down it's
s/check/checks/
> + * bs chain. Since we don't have pointers to parents it explore all bs chains
> + * from the top. Some filters can choose not to pass down the recursion.
> + */
> +bool bdrv_is_first_non_filter(BlockDriverState *candidate)
> {
> - return EXT_SNAPSHOT_FORBIDDEN;
> + BlockDriverState *bs;
> +
> + /* walk down the bs forest recursively */
> + QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
> + bool perm;
> +
> + if (!bs->file) {
> + continue;
> + }
> +
> + perm = bdrv_recurse_is_first_non_filter(bs->file, candidate);
> +
> + /* candidate is the first non filter */
> + if (perm) {
> + return true;
> + }
> + }
> +
> + return false;
> }
> diff --git a/block/blkverify.c b/block/blkverify.c
> index 3c63528..853afa9 100644
> --- a/block/blkverify.c
> +++ b/block/blkverify.c
> @@ -417,7 +417,7 @@ static BlockDriver bdrv_blkverify = {
> .bdrv_aio_writev = blkverify_aio_writev,
> .bdrv_aio_flush = blkverify_aio_flush,
>
> - .bdrv_check_ext_snapshot = bdrv_check_ext_snapshot_forbidden,
> + .authorizations = { true, false },
> };
>
> static void bdrv_blkverify_init(void)
> diff --git a/blockdev.c b/blockdev.c
> index 838df50..ebb8f48 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -1236,7 +1236,7 @@ static void external_snapshot_prepare(BlkTransactionState *common,
> }
> }
>
> - if (bdrv_check_ext_snapshot(state->old_bs) != EXT_SNAPSHOT_ALLOWED) {
> + if (!bdrv_is_first_non_filter(state->old_bs)) {
> error_set(errp, QERR_FEATURE_DISABLED, "snapshot");
> return;
> }
> diff --git a/include/block/block.h b/include/block/block.h
> index f7d8017..16812b0 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -283,16 +283,16 @@ int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options);
> /* external snapshots */
>
> typedef enum {
> - EXT_SNAPSHOT_ALLOWED,
> - EXT_SNAPSHOT_FORBIDDEN,
> -} ExtSnapshotPerm;
> -
> -/* return EXT_SNAPSHOT_ALLOWED if external snapshot is allowed
> - * return EXT_SNAPSHOT_FORBIDDEN if external snapshot is forbidden
> - */
> -ExtSnapshotPerm bdrv_check_ext_snapshot(BlockDriverState *bs);
> -/* helper used to forbid external snapshots like in blkverify */
> -ExtSnapshotPerm bdrv_check_ext_snapshot_forbidden(BlockDriverState *bs);
> + BS_IS_A_FILTER,
> + BS_FILTER_PASS_DOWN,
> + BS_AUTHORIZATION_COUNT,
> +} BsAuthorization;
> +
> +bool bdrv_generic_is_first_non_filter(BlockDriverState *bs,
> + BlockDriverState *candidate);
> +bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
> + BlockDriverState *candidate);
> +bool bdrv_is_first_non_filter(BlockDriverState *candidate);
>
> /* async block I/O */
> typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index bd5220f..7933ecc 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -69,10 +69,16 @@ struct BlockDriver {
> const char *format_name;
> int instance_size;
>
> - /* if not defined external snapshots are allowed
> - * future block filters will query their children to build the response
> + /* this table of boolean contains authorizations for the block operations */
> + bool authorizations[BS_AUTHORIZATION_COUNT];
> + /* for snapshots complex block filter like Quorum can implement the
> + * following recursive callback instead of BS_IS_A_FILTER.
> + * It's purpose is to recurse on the filter children while calling
> + * bdrv_recurse_is_first_non_filter on them.
> + * For a sample implentation look in the future Quorum block filter.
s/implentation/implementation/
> */
> - ExtSnapshotPerm (*bdrv_check_ext_snapshot)(BlockDriverState *bs);
> + bool (*bdrv_recurse_is_first_non_filter)(BlockDriverState *bs,
> + BlockDriverState *candidate);
>
> int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
> int (*bdrv_probe_device)(const char *filename);
> --
> 1.8.3.2
>
>
next prev parent reply other threads:[~2014-01-21 3:45 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-12 15:33 [Qemu-devel] [PATCH V5 0/7] Giving names to BlockDriverState graph nodes Benoît Canet
2013-12-12 15:33 ` [Qemu-devel] [PATCH V5 1/7] block: Add bs->node_name to hold the name of a bs node of the bs graph Benoît Canet
2014-01-21 3:10 ` Fam Zheng
2013-12-12 15:33 ` [Qemu-devel] [PATCH V5 2/7] block: Allow the user to define "node-name" option Benoît Canet
2014-01-21 3:15 ` Fam Zheng
2014-01-21 14:12 ` Kevin Wolf
2013-12-12 15:33 ` [Qemu-devel] [PATCH V5 3/7] qmp: Add a command to list the named BlockDriverState nodes Benoît Canet
2014-01-21 3:23 ` Fam Zheng
2013-12-12 15:33 ` [Qemu-devel] [PATCH V5 4/7] qmp: Allow to change password on named block driver states Benoît Canet
2014-01-21 3:27 ` Fam Zheng
2014-01-21 14:17 ` Kevin Wolf
2013-12-12 15:33 ` [Qemu-devel] [PATCH V5 5/7] block: Create authorizations mechanism for external snapshot and resize Benoît Canet
2014-01-21 3:45 ` Fam Zheng [this message]
2013-12-12 15:33 ` [Qemu-devel] [PATCH V5 6/7] qmp: Allow block_resize to manipulate bs graph nodes Benoît Canet
2014-01-21 3:46 ` Fam Zheng
2013-12-12 15:34 ` [Qemu-devel] [PATCH V5 7/7] qmp: Allow to take external snapshots on bs graphs node Benoît Canet
2014-01-21 3:54 ` Fam Zheng
2014-01-21 14:28 ` Kevin Wolf
2014-01-22 21:33 ` Benoît Canet
2014-01-23 10:20 ` Kevin Wolf
2014-01-16 17:18 ` [Qemu-devel] [PATCH V5 0/7] Giving names to BlockDriverState graph nodes Benoît Canet
2014-01-21 4:04 ` Fam Zheng
2014-01-21 14:33 ` Kevin Wolf
2014-01-21 15:36 ` Benoît Canet
2014-01-21 15:44 ` Kevin Wolf
2014-01-22 21:44 ` Benoît Canet
2014-01-23 10:14 ` Kevin Wolf
2014-01-22 22:03 ` Benoît Canet
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=20140121034542.GH29842@T430.redhat.com \
--to=famz@redhat.com \
--cc=armbru@redhat.com \
--cc=benoit@irqsave.net \
--cc=jcody@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.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.