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
|
* 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().
|
* which don't need their own reference any more must call bdrv_unref().
|
||||||
*/
|
*/
|
||||||
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
bool update_inherits_from = bdrv_chain_contains(bs, backing_hd) &&
|
bool update_inherits_from = bdrv_chain_contains(bs, backing_hd) &&
|
||||||
bdrv_inherits_from_recursive(backing_hd, bs);
|
bdrv_inherits_from_recursive(backing_hd, bs);
|
||||||
|
|
||||||
if (bdrv_is_backing_chain_frozen(bs, child_bs(bs->backing), errp)) {
|
if (bdrv_is_backing_chain_frozen(bs, child_bs(bs->backing), errp)) {
|
||||||
return;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backing_hd) {
|
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,
|
bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_of_bds,
|
||||||
bdrv_backing_role(bs), errp);
|
bdrv_backing_role(bs), errp);
|
||||||
|
if (!bs->backing) {
|
||||||
|
ret = -EPERM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* If backing_hd was already part of bs's backing chain, and
|
/* If backing_hd was already part of bs's backing chain, and
|
||||||
* inherits_from pointed recursively to bs then let's update it to
|
* inherits_from pointed recursively to bs then let's update it to
|
||||||
* point directly to bs (else it will become NULL). */
|
* point directly to bs (else it will become NULL). */
|
||||||
if (bs->backing && update_inherits_from) {
|
if (update_inherits_from) {
|
||||||
backing_hd->inherits_from = bs;
|
backing_hd->inherits_from = bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
bdrv_refresh_limits(bs, NULL);
|
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
|
* With auto_skip=false the error is returned if from has a parent which should
|
||||||
* not be updated.
|
* not be updated.
|
||||||
*/
|
*/
|
||||||
static void bdrv_replace_node_common(BlockDriverState *from,
|
static int bdrv_replace_node_common(BlockDriverState *from,
|
||||||
BlockDriverState *to,
|
BlockDriverState *to,
|
||||||
bool auto_skip, Error **errp)
|
bool auto_skip, Error **errp)
|
||||||
{
|
{
|
||||||
BdrvChild *c, *next;
|
BdrvChild *c, *next;
|
||||||
GSList *list = NULL, *p;
|
GSList *list = NULL, *p;
|
||||||
|
@ -4556,11 +4564,13 @@ static void bdrv_replace_node_common(BlockDriverState *from,
|
||||||
if (auto_skip) {
|
if (auto_skip) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
ret = -EINVAL;
|
||||||
error_setg(errp, "Should not change '%s' link to '%s'",
|
error_setg(errp, "Should not change '%s' link to '%s'",
|
||||||
c->name, from->node_name);
|
c->name, from->node_name);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (c->frozen) {
|
if (c->frozen) {
|
||||||
|
ret = -EPERM;
|
||||||
error_setg(errp, "Cannot change '%s' link to '%s'",
|
error_setg(errp, "Cannot change '%s' link to '%s'",
|
||||||
c->name, from->node_name);
|
c->name, from->node_name);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -4591,14 +4601,18 @@ static void bdrv_replace_node_common(BlockDriverState *from,
|
||||||
|
|
||||||
bdrv_set_perm(to);
|
bdrv_set_perm(to);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_slist_free(list);
|
g_slist_free(list);
|
||||||
bdrv_drained_end(from);
|
bdrv_drained_end(from);
|
||||||
bdrv_unref(from);
|
bdrv_unref(from);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
return bdrv_replace_node_common(from, to, true, 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
|
* parents of bs_top after bdrv_append() returns. If the caller needs to keep a
|
||||||
* reference of its own, it must call bdrv_ref().
|
* reference of its own, it must call bdrv_ref().
|
||||||
*/
|
*/
|
||||||
void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
int ret = bdrv_set_backing_hd(bs_new, bs_top, errp);
|
||||||
|
if (ret < 0) {
|
||||||
bdrv_set_backing_hd(bs_new, bs_top, &local_err);
|
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bdrv_replace_node(bs_top, bs_new, &local_err);
|
ret = bdrv_replace_node(bs_top, bs_new, errp);
|
||||||
if (local_err) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
|
||||||
bdrv_set_backing_hd(bs_new, NULL, &error_abort);
|
bdrv_set_backing_hd(bs_new, NULL, &error_abort);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bs_new is now referenced by its new parents, we don't need the
|
ret = 0;
|
||||||
* additional reference any more. */
|
|
||||||
out:
|
out:
|
||||||
|
/*
|
||||||
|
* bs_new is now referenced by its new parents, we don't need the
|
||||||
|
* additional reference any more.
|
||||||
|
*/
|
||||||
bdrv_unref(bs_new);
|
bdrv_unref(bs_new);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bdrv_delete(BlockDriverState *bs)
|
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);
|
int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
|
||||||
|
|
||||||
BlockDriverState *bdrv_new(void);
|
BlockDriverState *bdrv_new(void);
|
||||||
void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
|
BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
|
||||||
int flags, Error **errp);
|
int flags, Error **errp);
|
||||||
|
|
||||||
|
@ -373,8 +373,8 @@ BdrvChild *bdrv_open_child(const char *filename,
|
||||||
BdrvChildRole child_role,
|
BdrvChildRole child_role,
|
||||||
bool allow_none, Error **errp);
|
bool allow_none, Error **errp);
|
||||||
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
|
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
|
||||||
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
||||||
const char *bdref_key, Error **errp);
|
const char *bdref_key, Error **errp);
|
||||||
BlockDriverState *bdrv_open(const char *filename, const char *reference,
|
BlockDriverState *bdrv_open(const char *filename, const char *reference,
|
||||||
|
|
Loading…
Reference in New Issue