If we want to add some info to errp (by error_prepend() or error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro. Otherwise, this info will not be added when errp == &fatal_err (the program will exit prior to the error_append_hint() or error_prepend() call). Fix such cases.
If we want to check error after errp-function call, we need to introduce local_err and than propagate it to errp. Instead, use ERRP_AUTO_PROPAGATE macro, benefits are: 1. No need of explicit error_propagate call 2. No need of explicit local_err variable: use errp directly 3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or &error_fatel, this means that we don't break error_abort (we'll abort on error_set, not on error_propagate) This commit (together with its neighbors) was generated by for f in $(git grep -l errp \*.[ch]); do \ spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \ --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff $f; \ done; then fix a bit of compilation problems: coccinelle for some reason leaves several f() { ... goto out; ... out: } patterns, with "out:" at function end. then ./python/commit-per-subsystem.py MAINTAINERS "$(< auto-msg)" (auto-msg was a file with this commit message) Still, for backporting it may be more comfortable to use only the first command and then do one huge commit. Reported-by: Kevin Wolf <kw...@redhat.com> Reported-by: Greg Kurz <gr...@kaod.org> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- include/block/nbd.h | 1 + block/nbd.c | 49 +++++++++++++++++++++------------------------ nbd/client.c | 5 +++++ nbd/server.c | 5 +++++ 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 316fd705a9..330f40142a 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -360,6 +360,7 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds, static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size, const char *desc, Error **errp) { + ERRP_AUTO_PROPAGATE(); int ret = qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0; if (ret < 0) { diff --git a/block/nbd.c b/block/nbd.c index c66fdf54b9..2f8a924562 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -805,10 +805,10 @@ static int nbd_co_receive_cmdread_reply(BDRVNBDState *s, uint64_t handle, uint64_t offset, QEMUIOVector *qiov, int *request_ret, Error **errp) { + ERRP_AUTO_PROPAGATE(); NBDReplyChunkIter iter; NBDReply reply; void *payload = NULL; - Error *local_err = NULL; NBD_FOREACH_REPLY_CHUNK(s, iter, handle, s->info.structured_reply, qiov, &reply, &payload) @@ -827,20 +827,20 @@ static int nbd_co_receive_cmdread_reply(BDRVNBDState *s, uint64_t handle, break; case NBD_REPLY_TYPE_OFFSET_HOLE: ret = nbd_parse_offset_hole_payload(s, &reply.structured, payload, - offset, qiov, &local_err); + offset, qiov, errp); if (ret < 0) { nbd_channel_error(s, ret); - nbd_iter_channel_error(&iter, ret, &local_err); + nbd_iter_channel_error(&iter, ret, errp); } break; default: if (!nbd_reply_type_is_error(chunk->type)) { /* not allowed reply type */ nbd_channel_error(s, -EINVAL); - error_setg(&local_err, + error_setg(errp, "Unexpected reply type: %d (%s) for CMD_READ", chunk->type, nbd_reply_type_lookup(chunk->type)); - nbd_iter_channel_error(&iter, -EINVAL, &local_err); + nbd_iter_channel_error(&iter, -EINVAL, errp); } } @@ -858,10 +858,10 @@ static int nbd_co_receive_blockstatus_reply(BDRVNBDState *s, NBDExtent *extent, int *request_ret, Error **errp) { + ERRP_AUTO_PROPAGATE(); NBDReplyChunkIter iter; NBDReply reply; void *payload = NULL; - Error *local_err = NULL; bool received = false; assert(!extent->length); @@ -875,27 +875,27 @@ static int nbd_co_receive_blockstatus_reply(BDRVNBDState *s, case NBD_REPLY_TYPE_BLOCK_STATUS: if (received) { nbd_channel_error(s, -EINVAL); - error_setg(&local_err, "Several BLOCK_STATUS chunks in reply"); - nbd_iter_channel_error(&iter, -EINVAL, &local_err); + error_setg(errp, "Several BLOCK_STATUS chunks in reply"); + nbd_iter_channel_error(&iter, -EINVAL, errp); } received = true; ret = nbd_parse_blockstatus_payload(s, &reply.structured, payload, length, extent, - &local_err); + errp); if (ret < 0) { nbd_channel_error(s, ret); - nbd_iter_channel_error(&iter, ret, &local_err); + nbd_iter_channel_error(&iter, ret, errp); } break; default: if (!nbd_reply_type_is_error(chunk->type)) { nbd_channel_error(s, -EINVAL); - error_setg(&local_err, + error_setg(errp, "Unexpected reply type: %d (%s) " "for CMD_BLOCK_STATUS", chunk->type, nbd_reply_type_lookup(chunk->type)); - nbd_iter_channel_error(&iter, -EINVAL, &local_err); + nbd_iter_channel_error(&iter, -EINVAL, errp); } } @@ -904,8 +904,8 @@ static int nbd_co_receive_blockstatus_reply(BDRVNBDState *s, } if (!extent->length && !iter.request_ret) { - error_setg(&local_err, "Server did not reply with any status extents"); - nbd_iter_channel_error(&iter, -EIO, &local_err); + error_setg(errp, "Server did not reply with any status extents"); + nbd_iter_channel_error(&iter, -EIO, errp); } error_propagate(errp, iter.err); @@ -1173,16 +1173,15 @@ static void nbd_client_close(BlockDriverState *bs) static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr, Error **errp) { + ERRP_AUTO_PROPAGATE(); QIOChannelSocket *sioc; - Error *local_err = NULL; sioc = qio_channel_socket_new(); qio_channel_set_name(QIO_CHANNEL(sioc), "nbd-client"); - qio_channel_socket_connect_sync(sioc, saddr, &local_err); - if (local_err) { + qio_channel_socket_connect_sync(sioc, saddr, errp); + if (*errp) { object_unref(OBJECT(sioc)); - error_propagate(errp, local_err); return NULL; } @@ -1486,10 +1485,10 @@ static bool nbd_process_legacy_socket_options(QDict *output_options, static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, Error **errp) { + ERRP_AUTO_PROPAGATE(); SocketAddress *saddr = NULL; QDict *addr = NULL; Visitor *iv = NULL; - Error *local_err = NULL; qdict_extract_subqdict(options, &addr, "server."); if (!qdict_size(addr)) { @@ -1502,9 +1501,8 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, goto done; } - visit_type_SocketAddress(iv, NULL, &saddr, &local_err); - if (local_err) { - error_propagate(errp, local_err); + visit_type_SocketAddress(iv, NULL, &saddr, errp); + if (*errp) { goto done; } @@ -1597,15 +1595,14 @@ static QemuOptsList nbd_runtime_opts = { static int nbd_process_options(BlockDriverState *bs, QDict *options, Error **errp) { + ERRP_AUTO_PROPAGATE(); BDRVNBDState *s = bs->opaque; QemuOpts *opts; - Error *local_err = NULL; int ret = -EINVAL; opts = qemu_opts_create(&nbd_runtime_opts, NULL, 0, &error_abort); - qemu_opts_absorb_qdict(opts, options, &local_err); - if (local_err) { - error_propagate(errp, local_err); + qemu_opts_absorb_qdict(opts, options, errp); + if (*errp) { goto error; } diff --git a/nbd/client.c b/nbd/client.c index f6733962b4..6e510f4a14 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -68,6 +68,7 @@ static int nbd_send_option_request(QIOChannel *ioc, uint32_t opt, uint32_t len, const char *data, Error **errp) { + ERRP_AUTO_PROPAGATE(); NBDOption req; QEMU_BUILD_BUG_ON(sizeof(req) != 16); @@ -153,6 +154,7 @@ static int nbd_receive_option_reply(QIOChannel *ioc, uint32_t opt, static int nbd_handle_reply_err(QIOChannel *ioc, NBDOptionReply *reply, bool strict, Error **errp) { + ERRP_AUTO_PROPAGATE(); g_autofree char *msg = NULL; if (!(reply->type & (1 << 31))) { @@ -331,6 +333,7 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, char **description, static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t opt, NBDExportInfo *info, Error **errp) { + ERRP_AUTO_PROPAGATE(); NBDOptionReply reply; uint32_t len = strlen(info->name); uint16_t type; @@ -870,6 +873,7 @@ static int nbd_start_negotiate(AioContext *aio_context, QIOChannel *ioc, bool structured_reply, bool *zeroes, Error **errp) { + ERRP_AUTO_PROPAGATE(); uint64_t magic; trace_nbd_start_negotiate(tlscreds, hostname ? hostname : "<null>"); @@ -1005,6 +1009,7 @@ int nbd_receive_negotiate(AioContext *aio_context, QIOChannel *ioc, const char *hostname, QIOChannel **outioc, NBDExportInfo *info, Error **errp) { + ERRP_AUTO_PROPAGATE(); int result; bool zeroes; bool base_allocation = info->base_allocation; diff --git a/nbd/server.c b/nbd/server.c index d8d1e62455..fdb93aab3f 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -211,6 +211,7 @@ static int GCC_FMT_ATTR(4, 0) nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type, Error **errp, const char *fmt, va_list va) { + ERRP_AUTO_PROPAGATE(); g_autofree char *msg = NULL; int ret; size_t len; @@ -365,6 +366,7 @@ static int nbd_opt_read_name(NBDClient *client, char *name, uint32_t *length, static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, Error **errp) { + ERRP_AUTO_PROPAGATE(); size_t name_len, desc_len; uint32_t len; const char *name = exp->name ? exp->name : ""; @@ -427,6 +429,7 @@ static void nbd_check_meta_export(NBDClient *client) static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes, Error **errp) { + ERRP_AUTO_PROPAGATE(); char name[NBD_MAX_NAME_SIZE + 1]; char buf[NBD_REPLY_EXPORT_NAME_SIZE] = ""; size_t len; @@ -1260,6 +1263,7 @@ static int nbd_negotiate_options(NBDClient *client, Error **errp) */ static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp) { + ERRP_AUTO_PROPAGATE(); char buf[NBD_OLDSTYLE_NEGOTIATE_SIZE] = ""; int ret; @@ -1631,6 +1635,7 @@ void nbd_export_close(NBDExport *exp) void nbd_export_remove(NBDExport *exp, NbdServerRemoveMode mode, Error **errp) { + ERRP_AUTO_PROPAGATE(); if (mode == NBD_SERVER_REMOVE_MODE_HARD || QTAILQ_EMPTY(&exp->clients)) { nbd_export_close(exp); return; -- 2.21.0