All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
To: John Snow <jsnow@redhat.com>,
	qemu-block@nongnu.org, qemu-devel@nongnu.org
Cc: kwolf@redhat.com, famz@redhat.com, armbru@redhat.com,
	mreitz@redhat.com, stefanha@redhat.com, pbonzini@redhat.com,
	den@openvz.org
Subject: Re: [Qemu-devel] [PATCH 09/25] block/dirty-bitmap: add readonly field to BdrvDirtyBitmap
Date: Fri, 2 Jun 2017 12:01:07 +0300	[thread overview]
Message-ID: <b5d84158-b1f9-d497-3231-be76565cb3b3@virtuozzo.com> (raw)
In-Reply-To: <d587d556-4807-46ff-3596-4c1c99edbcef@virtuozzo.com>

02.06.2017 11:56, Vladimir Sementsov-Ogievskiy wrote:
> 02.06.2017 02:25, John Snow wrote:
>>
>> On 06/01/2017 03:30 AM, Sementsov-Ogievskiy Vladimir wrote:
>>> Hi John!
>>>
>>> Look at our discussion about this in v18 thread.
>>>> Shortly: readonly is not the same as disabled. disabled= bitmap just
>>> ignores all writes. readonly= writes are not allowed at all.
>>>
>>> And I think, I'll try to go through way 2: "dirty" field instead of
>>> "readonly" (look at v18 discussion), as it a bit more flexible.
>>>
>> Not sure which I prefer...
>>
>> Method 1 is attractive in that it is fairly simple, and enforces fairly
>> loudly the inability to write to devices with RO bitmaps. It's a natural
>> extension of your current approach.
>
> For now I decided to realize this one, I think I'll publish it today. 
> Also, I'm going to rename s/readonly/in_use - to avoid the confuse 
> with disabled. So let this field just be mirror of IN_USE in the image 
> and just say "persistent storage knows, that bitmap is in use and may 
> be dirty".
>
> Also, optimization with 'dirty' flag may be added later.

And, also, I don't want to influence this "first write", on which we 
will set "IN_USE" in all bitmaps (for way (2). Reopening rw is less 
performance-demanding place than write.


>
>>
>> Method 2 is attractive in that it seems a little more efficient, and is
>> a little more clever. A dirty flag lets us avoid flushing bitmaps we
>> never even changed (though we still need to clean up the in_use flags.)
>>
>> What I wonder about #2 is what happens when a write sneaks in (due to a
>> bug or a use case we didn't see) on a bitmap attached to a read-only
>> node. We fail later on invalidate? It shouldn't happen in normal
>> circumstances, but I worry that the failure mode is messier.
>
> if bitmap is dirty - all ok, the problems will appear when we'll try 
> to save it, but these problems are not fatal - bitmap should be marked 
> 'in_use' in the image, so it will be lost (the worst case is when 
> in_use not set and bitmap is incorrect - it may lead to data loss for 
> user)
>
> if it is not dirty - we will fail to write 'in_use' before actual 
> write and the whole write will fail.
>
>>
>>
>> Well, either way I will be happy for now I think -- pick whichever
>> option feels easiest or best for you to implement.
>>
>> Thanks!
>>
>>> On 01.06.2017 02:48, John Snow wrote:
>>>> On 05/30/2017 04:17 AM, Vladimir Sementsov-Ogievskiy wrote:
>>>>> It will be needed in following commits for persistent bitmaps.
>>>>> If bitmap is loaded from read-only storage (and we can't mark it
>>>>> "in use" in this storage) corresponding BdrvDirtyBitmap should be
>>>>> read-only.
>>>>>
>>>>> Signed-off-by: Vladimir Sementsov-Ogievskiy 
>>>>> <vsementsov@virtuozzo.com>
>>>>> ---
>>>>>    block/dirty-bitmap.c         | 28 ++++++++++++++++++++++++++++
>>>>>    block/io.c                   |  8 ++++++++
>>>>>    blockdev.c                   |  6 ++++++
>>>>>    include/block/dirty-bitmap.h |  4 ++++
>>>>>    4 files changed, 46 insertions(+)
>>>>>
>>>>> diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
>>>>> index 90af37287f..733f19ca5e 100644
>>>>> --- a/block/dirty-bitmap.c
>>>>> +++ b/block/dirty-bitmap.c
>>>>> @@ -44,6 +44,8 @@ struct BdrvDirtyBitmap {
>>>>>        int64_t size;               /* Size of the bitmap (Number of
>>>>> sectors) */
>>>>>        bool disabled;              /* Bitmap is read-only */
>>>>>        int active_iterators;       /* How many iterators are 
>>>>> active */
>>>>> +    bool readonly;              /* Bitmap is read-only and may be
>>>>> changed only
>>>>> +                                   by deserialize* functions */
>>>>>        QLIST_ENTRY(BdrvDirtyBitmap) list;
>>>>>    };
>>>>>    @@ -436,6 +438,7 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap
>>>>> *bitmap,
>>>>>                               int64_t cur_sector, int64_t nr_sectors)
>>>>>    {
>>>>>        assert(bdrv_dirty_bitmap_enabled(bitmap));
>>>>> +    assert(!bdrv_dirty_bitmap_readonly(bitmap));
>>>> Not reasonable to add the condition for !readonly into
>>>> bdrv_dirty_bitmap_enabled?
>>>>
>>>> As is:
>>>>
>>>> If readonly is set to true on a bitmap, bdrv_dirty_bitmap_status is
>>>> going to return ACTIVE for such bitmaps, but DISABLED might be more
>>>> appropriate to indicate the read-only nature.
>>>>
>>>> If you add this condition into _enabled(), you can skip the extra
>>>> assertions you've added here.
>>>>
>>>>> hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
>>>>>    }
>>>>>    @@ -443,12 +446,14 @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap
>>>>> *bitmap,
>>>>>                                 int64_t cur_sector, int64_t 
>>>>> nr_sectors)
>>>>>    {
>>>>>        assert(bdrv_dirty_bitmap_enabled(bitmap));
>>>>> +    assert(!bdrv_dirty_bitmap_readonly(bitmap));
>>>>>        hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
>>>>>    }
>>>>>      void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap 
>>>>> **out)
>>>>>    {
>>>>>        assert(bdrv_dirty_bitmap_enabled(bitmap));
>>>>> +    assert(!bdrv_dirty_bitmap_readonly(bitmap));
>>>>>        if (!out) {
>>>>>            hbitmap_reset_all(bitmap->bitmap);
>>>>>        } else {
>>>>> @@ -519,6 +524,7 @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t
>>>>> cur_sector,
>>>>>            if (!bdrv_dirty_bitmap_enabled(bitmap)) {
>>>>>                continue;
>>>>>            }
>>>>> +        assert(!bdrv_dirty_bitmap_readonly(bitmap));
>>>>>            hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
>>>>>        }
>>>>>    }
>>>>> @@ -540,3 +546,25 @@ int64_t
>>>>> bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
>>>>>    {
>>>>>        return hbitmap_count(bitmap->meta);
>>>>>    }
>>>>> +
>>>>> +bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
>>>>> +{
>>>>> +    return bitmap->readonly;
>>>>> +}
>>>>> +
>>>>> +void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap)
>>>>> +{
>>>>> +    bitmap->readonly = true;
>>>>> +}
>>>>> +
>>>>> +bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
>>>>> +{
>>>>> +    BdrvDirtyBitmap *bm;
>>>>> +    QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
>>>>> +        if (bm->readonly) {
>>>>> +            return true;
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    return false;
>>>>> +}
>>>>> diff --git a/block/io.c b/block/io.c
>>>>> index fdd7485c22..0e28a1f595 100644
>>>>> --- a/block/io.c
>>>>> +++ b/block/io.c
>>>>> @@ -1349,6 +1349,10 @@ static int coroutine_fn
>>>>> bdrv_aligned_pwritev(BdrvChild *child,
>>>>>        uint64_t bytes_remaining = bytes;
>>>>>        int max_transfer;
>>>>>    +    if (bdrv_has_readonly_bitmaps(bs)) {
>>>>> +        return -EPERM;
>>>>> +    }
>>>>> +
>>>> Oh, hardcore. The original design for "disabled" was just that they
>>>> would become invalid after writes; but in this case a read-only bitmap
>>>> literally enforces the concept.
>>>>
>>>> I can envision usages for both.
>>>>
>>>>>        assert(is_power_of_2(align));
>>>>>        assert((offset & (align - 1)) == 0);
>>>>>        assert((bytes & (align - 1)) == 0);
>>>>> @@ -2437,6 +2441,10 @@ int coroutine_fn
>>>>> bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
>>>>>            return -ENOMEDIUM;
>>>>>        }
>>>>>    +    if (bdrv_has_readonly_bitmaps(bs)) {
>>>>> +        return -EPERM;
>>>>> +    }
>>>>> +
>>>>>        ret = bdrv_check_byte_request(bs, offset, count);
>>>>>        if (ret < 0) {
>>>>>            return ret;
>>>>> diff --git a/blockdev.c b/blockdev.c
>>>>> index c63f4e82c7..2b397abf66 100644
>>>>> --- a/blockdev.c
>>>>> +++ b/blockdev.c
>>>>> @@ -2033,6 +2033,9 @@ static void
>>>>> block_dirty_bitmap_clear_prepare(BlkActionState *common,
>>>>>        } else if (!bdrv_dirty_bitmap_enabled(state->bitmap)) {
>>>>>            error_setg(errp, "Cannot clear a disabled bitmap");
>>>>>            return;
>>>>> +    } else if (bdrv_dirty_bitmap_readonly(state->bitmap)) {
>>>>> +        error_setg(errp, "Cannot clear a readonly bitmap");
>>>>> +        return;
>>>>>        }
>>>> Oh, I see -- perhaps you wanted a better error message? That makes 
>>>> sense
>>>> to me....
>>>>
>>>>
>>>> ...Though, you know, bdrv_disable_dirty_bitmap accomplishes something
>>>> pretty similar here: we take the bitmap out of active RW state and put
>>>> it into RO mode, it's just done under the name enabled/disabled 
>>>> instead
>>>> of RO.
>>>>
>>>> As of this patch, nothing uses it yet. Is this patch necessary? Would
>>>> setting a bitmap as "disabled" to mean "RO" be sufficient, or are the
>>>> two flags truly semantically necessary?
>>>>
>>>>> bdrv_clear_dirty_bitmap(state->bitmap, &state->backup);
>>>>> @@ -2813,6 +2816,9 @@ void qmp_block_dirty_bitmap_clear(const char
>>>>> *node, const char *name,
>>>>>                       "Bitmap '%s' is currently disabled and 
>>>>> cannot be
>>>>> cleared",
>>>>>                       name);
>>>>>            goto out;
>>>>> +    } else if (bdrv_dirty_bitmap_readonly(bitmap)) {
>>>>> +        error_setg(errp, "Bitmap '%s' is readonly and cannot be
>>>>> cleared", name);
>>>>> +        goto out;
>>>>>        }
>>>>>          bdrv_clear_dirty_bitmap(bitmap, NULL);
>>>>> diff --git a/include/block/dirty-bitmap.h 
>>>>> b/include/block/dirty-bitmap.h
>>>>> index 1e17729ac2..c0c3ce9f85 100644
>>>>> --- a/include/block/dirty-bitmap.h
>>>>> +++ b/include/block/dirty-bitmap.h
>>>>> @@ -75,4 +75,8 @@ void
>>>>> bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
>>>>>                                            bool finish);
>>>>>    void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap 
>>>>> *bitmap);
>>>>>    +bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap);
>>>>> +void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap);
>>>>> +bool bdrv_has_readonly_bitmaps(BlockDriverState *bs);
>>>>> +
>>>>>    #endif
>>>>>
>>>> I realize I am being very bike-sheddy about this, so I might give 
>>>> an r-b
>>>> with a light justification.
>>>>
>>>> --js
>
>

-- 
Best regards,
Vladimir

  reply	other threads:[~2017-06-02  9:01 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-30  8:16 [Qemu-devel] [PATCH v19 00/25] qcow2: persistent dirty bitmaps Vladimir Sementsov-Ogievskiy
2017-05-30  8:16 ` [Qemu-devel] [PATCH 01/25] specs/qcow2: fix bitmap granularity qemu-specific note Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 02/25] specs/qcow2: do not use wording 'bitmap header' Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 03/25] hbitmap: improve dirty iter Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 04/25] tests: add hbitmap iter test Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 05/25] block: fix bdrv_dirty_bitmap_granularity signature Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 06/25] block/dirty-bitmap: add deserialize_ones func Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 07/25] qcow2-refcount: rename inc_refcounts() and make it public Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 08/25] qcow2: add bitmaps extension Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 09/25] block/dirty-bitmap: add readonly field to BdrvDirtyBitmap Vladimir Sementsov-Ogievskiy
2017-05-31 23:48   ` John Snow
2017-06-01  7:30     ` Sementsov-Ogievskiy Vladimir
2017-06-01 18:55       ` John Snow
2017-06-01 23:25       ` John Snow
2017-06-02  8:56         ` Vladimir Sementsov-Ogievskiy
2017-06-02  9:01           ` Vladimir Sementsov-Ogievskiy [this message]
2017-06-02  9:45             ` Vladimir Sementsov-Ogievskiy
2017-06-02 18:46               ` John Snow
2017-06-03 17:02                 ` Sementsov-Ogievskiy Vladimir
2017-05-30  8:17 ` [Qemu-devel] [PATCH 10/25] qcow2: autoloading dirty bitmaps Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 11/25] block/dirty-bitmap: add autoload field to BdrvDirtyBitmap Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 12/25] block: bdrv_close: release bitmaps after drv->bdrv_close Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 13/25] block: introduce persistent dirty bitmaps Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 14/25] block/dirty-bitmap: add bdrv_dirty_bitmap_next() Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 15/25] qcow2: add persistent dirty bitmaps support Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 16/25] block: add bdrv_can_store_new_dirty_bitmap Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 17/25] qcow2: add .bdrv_can_store_new_dirty_bitmap Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 18/25] qmp: add persistent flag to block-dirty-bitmap-add Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 19/25] qmp: add autoload parameter " Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 20/25] qmp: add x-debug-block-dirty-bitmap-sha256 Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 21/25] iotests: test qcow2 persistent dirty bitmap Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 22/25] block/dirty-bitmap: add bdrv_remove_persistent_dirty_bitmap Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 23/25] qcow2: add .bdrv_remove_persistent_dirty_bitmap Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 24/25] qmp: block-dirty-bitmap-remove: remove persistent Vladimir Sementsov-Ogievskiy
2017-05-30  8:17 ` [Qemu-devel] [PATCH 25/25] block: release persistent bitmaps on inactivate Vladimir Sementsov-Ogievskiy
2017-05-31 16:08 ` [Qemu-devel] [PATCH v19 00/25] qcow2: persistent dirty bitmaps Vladimir Sementsov-Ogievskiy
  -- strict thread matches above, loose matches on Subject: below --
2017-05-03 12:25 [Qemu-devel] [PATCH v18 " Vladimir Sementsov-Ogievskiy
2017-05-03 12:25 ` [Qemu-devel] [PATCH 09/25] block/dirty-bitmap: add readonly field to BdrvDirtyBitmap Vladimir Sementsov-Ogievskiy
2017-05-19 23:02   ` John Snow
2017-05-25  9:34     ` Vladimir Sementsov-Ogievskiy
2017-05-31 22:58     ` John Snow
2017-06-01  7:23       ` Sementsov-Ogievskiy Vladimir
2017-05-29 15:49   ` Max Reitz
2017-05-29 18:35   ` Max Reitz
2017-05-30  6:50     ` Vladimir Sementsov-Ogievskiy
2017-05-30  7:31       ` Vladimir Sementsov-Ogievskiy
2017-05-30  7:47         ` Vladimir Sementsov-Ogievskiy
2017-05-31 13:43       ` Max Reitz
2017-05-31 14:29         ` Vladimir Sementsov-Ogievskiy
2017-05-31 14:44           ` Max Reitz
2017-05-31 15:05             ` Vladimir Sementsov-Ogievskiy
2017-05-31 15:53               ` Max Reitz
2017-06-01 22:35                 ` John Snow
2017-06-01 22:29         ` John Snow
2017-06-07 12:40           ` Max Reitz

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=b5d84158-b1f9-d497-3231-be76565cb3b3@virtuozzo.com \
    --to=vsementsov@virtuozzo.com \
    --cc=armbru@redhat.com \
    --cc=den@openvz.org \
    --cc=famz@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --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.