On 14.10.20 18:08, Andrey Shinkevich wrote: > On 14.10.2020 14:09, Max Reitz wrote: >> On 12.10.20 19:43, Andrey Shinkevich wrote: >>> We are going to use the COR-filter for a block-stream job. >>> To limit COR operations by the base node in the backing chain during >>> stream job, pass the name of overlay base node to the copy-on-read >>> driver as base node itself may change due to possible concurrent jobs. >>> The rest of the functionality will be implemented in the patch that >>> follows. >>> >>> Signed-off-by: Andrey Shinkevich <andrey.shinkev...@virtuozzo.com> >>> --- >>> block/copy-on-read.c | 14 ++++++++++++++ >>> 1 file changed, 14 insertions(+) >> >> Is there a reason why you didn’t add this option to QAPI (as part of a >> yet-to-be-created BlockdevOptionsCor)? Because I’d really like it there. >> > > I agree that passing a base overlay under the base option looks clumsy. > We could pass the base node name and find its overlay ourselves here in > cor_open(). In that case, we can use the existing QAPI.
Sounds more complicated than to just split off BlockdevOptionsCor (from BlockdevOptionsGenericFormat, like e.g. BlockdevOptionsRaw does it). > The reason I used the existing QAPI is to make it easier for a user to > operate with the traditional options and to keep things simple. So, the > user shouldn't think what overlay or above-base node to pass. Well, they don’t have to pass anything if they don’t need a bottom node. So unless they want to use a bottom/base-overlay node, it won’t become more complicated. > If we introduce the specific BlockdevOptionsCor, what other options may > come with? Nothing yet, I think. >>> diff --git a/block/copy-on-read.c b/block/copy-on-read.c >>> index bcccf0f..c578b1b 100644 >>> --- a/block/copy-on-read.c >>> +++ b/block/copy-on-read.c >>> @@ -24,19 +24,24 @@ >>> #include "block/block_int.h" >>> #include "qemu/module.h" >>> #include "qapi/error.h" >>> +#include "qapi/qmp/qerror.h" >>> #include "qapi/qmp/qdict.h" >>> #include "block/copy-on-read.h" >>> typedef struct BDRVStateCOR { >>> bool active; >>> + BlockDriverState *base_overlay; >>> } BDRVStateCOR; >>> static int cor_open(BlockDriverState *bs, QDict *options, int >>> flags, >>> Error **errp) >>> { >>> + BlockDriverState *base_overlay = NULL; >>> BDRVStateCOR *state = bs->opaque; >>> + /* We need the base overlay node rather than the base itself */ >>> + const char *base_overlay_node = qdict_get_try_str(options, "base"); >> >> Shouldn’t it be called base-overlay or above-base then? >> > > The base_overlay identifier is used below as the pointer to BS. The > base_overlay_node stands for the name of the node. I used that > identifier to differ between the types. And the above_base has another > meaning per block/stream.c - it can be a temporary filter with a JSON-name. Yes, agreed; I’m not talking about the variable identifier though. I’m talking about the option name, which in this version is just “base”. (And whenever that option is used, once here, once later in block/stream.c, there is an explanatory comment why we don’t pass the base node through it, but the first overlay above the base. Which makes me believe perhaps it shouldn’t be called “base”.) >>> bs->file = bdrv_open_child(NULL, options, "file", bs, >>> &child_of_bds, >>> BDRV_CHILD_FILTERED | >>> BDRV_CHILD_PRIMARY, >>> @@ -52,7 +57,16 @@ static int cor_open(BlockDriverState *bs, QDict >>> *options, int flags, >>> ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) & >>> bs->file->bs->supported_zero_flags); >>> + if (base_overlay_node) { >>> + qdict_del(options, "base"); >>> + base_overlay = bdrv_lookup_bs(NULL, base_overlay_node, errp); >> >> I think this is a use-after-free. The storage @base_overlay_node points >> to belongs to a QString, which is referenced only by @options; so >> deleting that element of @options should free that string. >> >> Max >> > > I will swap those two function calls (bdrv_lookup_bs(); qdict_del();). > Thank you. Don’t forget that the error_setg() below also makes use of it: >>> + if (!base_overlay) { >>> + error_setg(errp, QERR_BASE_NOT_FOUND, base_overlay_node); >>> + return -EINVAL; >>> + } >>> + } Max
signature.asc
Description: OpenPGP digital signature