[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH for-5.0 v2 06/23] block: Add bdrv_recurse_can_replace()
From: |
Max Reitz |
Subject: |
Re: [PATCH for-5.0 v2 06/23] block: Add bdrv_recurse_can_replace() |
Date: |
Fri, 29 Nov 2019 11:23:47 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 |
On 29.11.19 10:34, Vladimir Sementsov-Ogievskiy wrote:
> 11.11.2019 19:01, Max Reitz wrote:
>> After a couple of follow-up patches, this function will replace
>> bdrv_recurse_is_first_non_filter() in check_to_replace_node().
>>
>> bdrv_recurse_is_first_non_filter() is both not sufficiently specific for
>> check_to_replace_node() (it allows cases that should not be allowed,
>> like replacing child nodes of quorum with dissenting data that have more
>> parents than just quorum), and it is too restrictive (it is perfectly
>> fine to replace filters).
>>
>> Signed-off-by: Max Reitz <address@hidden>
>> ---
>> block.c | 38 ++++++++++++++++++++++++++++++++++++++
>> include/block/block_int.h | 10 ++++++++++
>> 2 files changed, 48 insertions(+)
>>
>> diff --git a/block.c b/block.c
>> index 9b1049786a..de53addeb0 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -6205,6 +6205,44 @@ bool
>> bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
>> return false;
>> }
>>
>> +/*
>> + * This function checks whether the given @to_replace is allowed to be
>> + * replaced by a node that always shows the same data as @bs. This is
>> + * used for example to verify whether the mirror job can replace
>> + * @to_replace by the target mirrored from @bs.
>> + * To be replaceable, @bs and @to_replace may either be guaranteed to
>> + * always show the same data (because they are only connected through
>> + * filters), or some driver may allow replacing one of its children
>> + * because it can guarantee that this child's data is not visible at
>> + * all (for example, for dissenting quorum children that have no other
>> + * parents).
>> + */
>> +bool bdrv_recurse_can_replace(BlockDriverState *bs,
>> + BlockDriverState *to_replace)
>> +{
>> + if (!bs || !bs->drv) {
>> + return false;
>> + }
>> +
>> + if (bs == to_replace) {
>> + return true;
>> + }
>> +
>> + /* See what the driver can do */
>> + if (bs->drv->bdrv_recurse_can_replace) {
>> + return bs->drv->bdrv_recurse_can_replace(bs, to_replace);
>> + }
>> +
>> + /* For filters without an own implementation, we can recurse on our own
>> */
>> + if (bs->drv->is_filter) {
>> + BdrvChild *child = bs->file ?: bs->backing;
>
> should we check that child != NULL ?
I’d say that normally (once they are open) filters must have a child,
and so I’d make it an assertion. But then again an assertion isn’t much
better than the dereferencing that follows, I think. :?
Max
>> + return bdrv_recurse_can_replace(child->bs, to_replace);
>> + }
>> +
>> + /* Safe default */
>> + return false;
>> +}
>> +
>> BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
>> const char *node_name, Error
>> **errp)
>> {
>> diff --git a/include/block/block_int.h b/include/block/block_int.h
>> index dd033d0b37..75f03dcc38 100644
>> --- a/include/block/block_int.h
>> +++ b/include/block/block_int.h
>> @@ -102,6 +102,13 @@ struct BlockDriver {
>> */
>> bool (*bdrv_recurse_is_first_non_filter)(BlockDriverState *bs,
>> BlockDriverState *candidate);
>> + /*
>> + * Return true if @to_replace can be replaced by a BDS with the
>> + * same data as @bs without it affecting @bs's behavior (that is,
>> + * without it being visible to @bs's parents).
>> + */
>> + bool (*bdrv_recurse_can_replace)(BlockDriverState *bs,
>> + BlockDriverState *to_replace);
>>
>> int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char
>> *filename);
>> int (*bdrv_probe_device)(const char *filename);
>> @@ -1264,6 +1271,9 @@ void bdrv_format_default_perms(BlockDriverState *bs,
>> BdrvChild *c,
>> uint64_t perm, uint64_t shared,
>> uint64_t *nperm, uint64_t *nshared);
>>
>> +bool bdrv_recurse_can_replace(BlockDriverState *bs,
>> + BlockDriverState *to_replace);
>> +
>> /*
>> * Default implementation for drivers to pass bdrv_co_block_status() to
>> * their file.
>>
>
>
signature.asc
Description: OpenPGP digital signature
- [PATCH for-5.0 v2 00/23] block: Fix check_to_replace_node(), Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 01/23] blockdev: Allow external snapshots everywhere, Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 02/23] blockdev: Allow resizing everywhere, Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 04/23] iotests: Let 041 use -blockdev for quorum children, Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 03/23] block: Drop bdrv_is_first_non_filter(), Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 05/23] quorum: Fix child permissions, Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 06/23] block: Add bdrv_recurse_can_replace(), Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 07/23] blkverify: Implement .bdrv_recurse_can_replace(), Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 08/23] quorum: Store children in own structure, Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 09/23] quorum: Add QuorumChild.to_be_replaced, Max Reitz, 2019/11/11
- [PATCH for-5.0 v2 10/23] quorum: Implement .bdrv_recurse_can_replace(), Max Reitz, 2019/11/11