All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Benoît Canet" <benoit.canet@irqsave.net>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Stefan Hajnoczi" <stefanha@redhat.com>,
	"Benoit Canet" <benoit@irqsave.net>,
	"Anthony Liguori" <aliguori@amazon.com>
Subject: [Qemu-devel] [PULL v2 for-2.0 06/24] block: Rewrite the snapshot authorization mechanism for block filters.
Date: Thu, 13 Mar 2014 15:10:50 +0100	[thread overview]
Message-ID: <1394719868-24312-7-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1394719868-24312-1-git-send-email-stefanha@redhat.com>

From: Benoît Canet <benoit.canet@irqsave.net>

This patch keep the recursive way of doing things but simplify it by giving
two responsabilities to all block filters implementors.

They will need to do two things:

-Set the is_filter field of their block driver to true.

-Implement the bdrv_recurse_is_first_non_filter method of their block driver like
it is done on the Quorum block driver. (block/quorum.c)

[Paolo Bonzini <pbonzini@redhat.com> pointed out that this patch changes
the semantics of blkverify, which now recurses down both bs->file and
s->test_file.
-- Stefan]

Reported-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c                   | 47 +++++++++++++++++++++--------------------------
 block/blkverify.c         | 17 ++++++++++++++++-
 block/quorum.c            |  3 +--
 include/block/block.h     |  9 ---------
 include/block/block_int.h |  8 ++++----
 5 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/block.c b/block.c
index 09c9258..cf5645a 100644
--- a/block.c
+++ b/block.c
@@ -5398,43 +5398,37 @@ int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options)
     return bs->drv->bdrv_amend_options(bs, options);
 }
 
-/* Used to recurse on single child block filters.
- * Single child block filter will store their child in bs->file.
+/* This function will be called by the bdrv_recurse_is_first_non_filter method
+ * of block filter and by bdrv_is_first_non_filter.
+ * It is used to test if the given bs is the candidate or recurse more in the
+ * node graph.
  */
-bool bdrv_generic_is_first_non_filter(BlockDriverState *bs,
+bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
                                       BlockDriverState *candidate)
 {
-    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 basic checks fails */
+    if (!bs || !bs->drv) {
         return false;
     }
 
-    if (!bs->file) {
-        return false;
+    /* the code reached a non block filter driver -> check if the bs is
+     * the same as the candidate. It's the recursion termination condition.
+     */
+    if (!bs->drv->is_filter) {
+        return bs == candidate;
     }
+    /* Down this path the driver is a block filter driver */
 
-    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) {
+    /* If the block filter recursion method is defined use it to recurse down
+     * the node graph.
+     */
+    if (bs->drv->bdrv_recurse_is_first_non_filter) {
         return bs->drv->bdrv_recurse_is_first_non_filter(bs, candidate);
     }
 
-    return bdrv_generic_is_first_non_filter(bs, candidate);
+    /* the driver is a block filter but don't allow to recurse -> return false
+     */
+    return false;
 }
 
 /* This function checks if the candidate is the first non filter bs down it's
@@ -5449,6 +5443,7 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate)
     QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
         bool perm;
 
+        /* try to recurse in this top level bs */
         perm = bdrv_recurse_is_first_non_filter(bs, candidate);
 
         /* candidate is the first non filter */
diff --git a/block/blkverify.c b/block/blkverify.c
index b98b08b..e1c3117 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -288,6 +288,20 @@ static BlockDriverAIOCB *blkverify_aio_flush(BlockDriverState *bs,
     return bdrv_aio_flush(s->test_file, cb, opaque);
 }
 
+static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
+                                                  BlockDriverState *candidate)
+{
+    BDRVBlkverifyState *s = bs->opaque;
+
+    bool perm = bdrv_recurse_is_first_non_filter(bs->file, candidate);
+
+    if (perm) {
+        return true;
+    }
+
+    return bdrv_recurse_is_first_non_filter(s->test_file, candidate);
+}
+
 static BlockDriver bdrv_blkverify = {
     .format_name            = "blkverify",
     .protocol_name          = "blkverify",
@@ -302,7 +316,8 @@ static BlockDriver bdrv_blkverify = {
     .bdrv_aio_writev        = blkverify_aio_writev,
     .bdrv_aio_flush         = blkverify_aio_flush,
 
-    .authorizations         = { true, false },
+    .is_filter              = true,
+    .bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter,
 };
 
 static void bdrv_blkverify_init(void)
diff --git a/block/quorum.c b/block/quorum.c
index bd997b7..33bf2ae 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -852,8 +852,6 @@ static BlockDriver bdrv_quorum = {
     .bdrv_file_open     = quorum_open,
     .bdrv_close         = quorum_close,
 
-    .authorizations     = { true, true },
-
     .bdrv_co_flush_to_disk = quorum_co_flush,
 
     .bdrv_getlength     = quorum_getlength,
@@ -862,6 +860,7 @@ static BlockDriver bdrv_quorum = {
     .bdrv_aio_writev    = quorum_aio_writev,
     .bdrv_invalidate_cache = quorum_invalidate_cache,
 
+    .is_filter           = true,
     .bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
 };
 
diff --git a/include/block/block.h b/include/block/block.h
index 780f48b..bd34d14 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -286,15 +286,6 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
 int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options);
 
 /* external snapshots */
-
-typedef enum {
-    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);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 0bcf1c9..4fc5ea8 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -76,10 +76,10 @@ struct BlockDriver {
     const char *format_name;
     int instance_size;
 
-    /* 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.
+    /* set to true if the BlockDriver is a block filter */
+    bool is_filter;
+    /* for snapshots block filter like Quorum can implement the
+     * following recursive callback.
      * It's purpose is to recurse on the filter children while calling
      * bdrv_recurse_is_first_non_filter on them.
      * For a sample implementation look in the future Quorum block filter.
-- 
1.8.5.3

  parent reply	other threads:[~2014-03-13 14:11 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-13 14:10 [Qemu-devel] [PULL v2 for-2.0 00/24] Block patches Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 01/24] qcow2-refcount: Sanitize refcount table entry Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 02/24] block: Update image size in bdrv_invalidate_cache() Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 03/24] qcow2: Check bs->drv in copy_sectors() Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 04/24] block: bs->drv may be NULL in bdrv_debug_resume() Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 05/24] iotests: Test corruption during COW request Stefan Hajnoczi
2014-03-13 14:10 ` Stefan Hajnoczi [this message]
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 07/24] object: add object_get_canonical_path_component() Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 08/24] rfifolock: add recursive FIFO lock Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 09/24] aio: add aio_context_acquire() and aio_context_release() Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 10/24] iothread: add I/O thread object Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 11/24] qdev: make get_pointer() handle temporary strings Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 12/24] iothread: add "iothread" qdev property type Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 13/24] dataplane: replace internal thread with IOThread Stefan Hajnoczi
2014-03-17 15:52   ` Christian Borntraeger
2014-03-19 11:02     ` Christian Borntraeger
2014-03-19 12:37       ` Paolo Bonzini
2014-03-20 10:13     ` Stefan Hajnoczi
2014-03-20 13:39       ` Christian Borntraeger
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 14/24] iothread: stash thread ID away Stefan Hajnoczi
2014-03-13 14:10 ` [Qemu-devel] [PULL v2 for-2.0 15/24] qmp: add query-iothreads command Stefan Hajnoczi
2014-03-13 14:11 ` [Qemu-devel] [PULL v2 for-2.0 16/24] qcow2: Keep option in qcow2_invalidate_cache() Stefan Hajnoczi
2014-03-13 14:11 ` [Qemu-devel] [PULL v2 for-2.0 17/24] qcow2: Don't write with BDRV_O_INCOMING Stefan Hajnoczi
2014-03-13 14:11 ` [Qemu-devel] [PULL v2 for-2.0 18/24] block: Unlink temporary file Stefan Hajnoczi
2014-03-13 14:11 ` [Qemu-devel] [PULL v2 for-2.0 19/24] qemu-io: Fix warnings from static code analysis Stefan Hajnoczi
2014-03-13 14:11 ` [Qemu-devel] [PULL v2 for-2.0 20/24] block/raw-posix: bdrv_parse_filename() for hdev Stefan Hajnoczi
2014-03-13 14:11 ` [Qemu-devel] [PULL v2 for-2.0 21/24] block/raw-posix: bdrv_parse_filename() for floppy Stefan Hajnoczi
2014-03-13 14:11 ` [Qemu-devel] [PULL v2 for-2.0 22/24] block/raw-posix: bdrv_parse_filename() for cdrom Stefan Hajnoczi
2014-03-13 14:11 ` [Qemu-devel] [PULL v2 for-2.0 23/24] block/raw-posix: Strip protocol prefix on creation Stefan Hajnoczi
2014-03-13 14:11 ` [Qemu-devel] [PULL v2 for-2.0 24/24] block/raw-win32: bdrv_parse_filename() for hdev Stefan Hajnoczi
2014-03-13 16:45 ` [Qemu-devel] [PULL v2 for-2.0 00/24] Block patches Peter Maydell
2014-03-14  1:28 ` Hu Tao
2014-03-14 16:02   ` Stefan Hajnoczi

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=1394719868-24312-7-git-send-email-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=aliguori@amazon.com \
    --cc=benoit.canet@irqsave.net \
    --cc=benoit@irqsave.net \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /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.