block: return status from bdrv_append and friends
The recommended use of qemu error api assumes returning status together with setting errp and avoid void functions with errp parameter. Let's improve bdrv_append and some friends to reduce error-propagation overhead in further patches. Choose int return status, because bdrv_replace_node_common() has call to bdrv_check_update_perm(), which reports int status, which seems correct to propagate. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-Id: <20210202124956.63146-2-vsementsov@virtuozzo.com> Reviewed-by: Alberto Garcia <berto@igalia.com> Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
ca4bfec41d
commit
a1e708fcda
58
block.c
58
block.c
@ -2827,14 +2827,15 @@ static BdrvChildRole bdrv_backing_role(BlockDriverState *bs)
|
||||
* Sets the bs->backing link of a BDS. A new reference is created; callers
|
||||
* which don't need their own reference any more must call bdrv_unref().
|
||||
*/
|
||||
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||
Error **errp)
|
||||
int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||
Error **errp)
|
||||
{
|
||||
int ret = 0;
|
||||
bool update_inherits_from = bdrv_chain_contains(bs, backing_hd) &&
|
||||
bdrv_inherits_from_recursive(backing_hd, bs);
|
||||
|
||||
if (bdrv_is_backing_chain_frozen(bs, child_bs(bs->backing), errp)) {
|
||||
return;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (backing_hd) {
|
||||
@ -2853,15 +2854,22 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||
|
||||
bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_of_bds,
|
||||
bdrv_backing_role(bs), errp);
|
||||
if (!bs->backing) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If backing_hd was already part of bs's backing chain, and
|
||||
* inherits_from pointed recursively to bs then let's update it to
|
||||
* point directly to bs (else it will become NULL). */
|
||||
if (bs->backing && update_inherits_from) {
|
||||
if (update_inherits_from) {
|
||||
backing_hd->inherits_from = bs;
|
||||
}
|
||||
|
||||
out:
|
||||
bdrv_refresh_limits(bs, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4532,9 +4540,9 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
|
||||
* With auto_skip=false the error is returned if from has a parent which should
|
||||
* not be updated.
|
||||
*/
|
||||
static void bdrv_replace_node_common(BlockDriverState *from,
|
||||
BlockDriverState *to,
|
||||
bool auto_skip, Error **errp)
|
||||
static int bdrv_replace_node_common(BlockDriverState *from,
|
||||
BlockDriverState *to,
|
||||
bool auto_skip, Error **errp)
|
||||
{
|
||||
BdrvChild *c, *next;
|
||||
GSList *list = NULL, *p;
|
||||
@ -4556,11 +4564,13 @@ static void bdrv_replace_node_common(BlockDriverState *from,
|
||||
if (auto_skip) {
|
||||
continue;
|
||||
}
|
||||
ret = -EINVAL;
|
||||
error_setg(errp, "Should not change '%s' link to '%s'",
|
||||
c->name, from->node_name);
|
||||
goto out;
|
||||
}
|
||||
if (c->frozen) {
|
||||
ret = -EPERM;
|
||||
error_setg(errp, "Cannot change '%s' link to '%s'",
|
||||
c->name, from->node_name);
|
||||
goto out;
|
||||
@ -4591,14 +4601,18 @@ static void bdrv_replace_node_common(BlockDriverState *from,
|
||||
|
||||
bdrv_set_perm(to);
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
g_slist_free(list);
|
||||
bdrv_drained_end(from);
|
||||
bdrv_unref(from);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
||||
Error **errp)
|
||||
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
||||
Error **errp)
|
||||
{
|
||||
return bdrv_replace_node_common(from, to, true, errp);
|
||||
}
|
||||
@ -4619,28 +4633,30 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
||||
* parents of bs_top after bdrv_append() returns. If the caller needs to keep a
|
||||
* reference of its own, it must call bdrv_ref().
|
||||
*/
|
||||
void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
Error **errp)
|
||||
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
|
||||
bdrv_set_backing_hd(bs_new, bs_top, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
int ret = bdrv_set_backing_hd(bs_new, bs_top, errp);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
bdrv_replace_node(bs_top, bs_new, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
ret = bdrv_replace_node(bs_top, bs_new, errp);
|
||||
if (ret < 0) {
|
||||
bdrv_set_backing_hd(bs_new, NULL, &error_abort);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* bs_new is now referenced by its new parents, we don't need the
|
||||
* additional reference any more. */
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
/*
|
||||
* bs_new is now referenced by its new parents, we don't need the
|
||||
* additional reference any more.
|
||||
*/
|
||||
bdrv_unref(bs_new);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bdrv_delete(BlockDriverState *bs)
|
||||
|
@ -356,10 +356,10 @@ int bdrv_create(BlockDriver *drv, const char* filename,
|
||||
int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
|
||||
|
||||
BlockDriverState *bdrv_new(void);
|
||||
void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
Error **errp);
|
||||
void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
||||
Error **errp);
|
||||
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
Error **errp);
|
||||
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
||||
Error **errp);
|
||||
BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
|
||||
int flags, Error **errp);
|
||||
|
||||
@ -373,8 +373,8 @@ BdrvChild *bdrv_open_child(const char *filename,
|
||||
BdrvChildRole child_role,
|
||||
bool allow_none, Error **errp);
|
||||
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
|
||||
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||
Error **errp);
|
||||
int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||
Error **errp);
|
||||
int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
||||
const char *bdref_key, Error **errp);
|
||||
BlockDriverState *bdrv_open(const char *filename, const char *reference,
|
||||
|
Loading…
Reference in New Issue
Block a user