struct devlink_fmsg {
        struct list_head item_list;
+       int err; /* first error encountered on some devlink_fmsg_XXX() call */
        bool putting_binary; /* This flag forces enclosing of binary data
                              * in an array brackets. It forces using
                              * of designated API:
                return 0;
 
        reporter->dump_fmsg = devlink_fmsg_alloc();
-       if (!reporter->dump_fmsg) {
-               err = -ENOMEM;
-               return err;
-       }
+       if (!reporter->dump_fmsg)
+               return -ENOMEM;
 
        err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
        if (err)
        return devlink_health_reporter_recover(reporter, NULL, info->extack);
 }
 
-static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
-                                   int attrtype)
+static void devlink_fmsg_err_if_binary(struct devlink_fmsg *fmsg)
+{
+       if (!fmsg->err && fmsg->putting_binary)
+               fmsg->err = -EINVAL;
+}
+
+static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg, int attrtype)
 {
        struct devlink_fmsg_item *item;
 
+       if (fmsg->err)
+               return fmsg->err;
+
        item = kzalloc(sizeof(*item), GFP_KERNEL);
-       if (!item)
-               return -ENOMEM;
+       if (!item) {
+               fmsg->err = -ENOMEM;
+               return fmsg->err;
+       }
 
        item->attrtype = attrtype;
        list_add_tail(&item->list, &fmsg->item_list);
 
 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
 {
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
+       devlink_fmsg_err_if_binary(fmsg);
        return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
 
 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
 {
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
+       devlink_fmsg_err_if_binary(fmsg);
        return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
 }
 
 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
 {
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
        return devlink_fmsg_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
 {
        struct devlink_fmsg_item *item;
 
-       if (fmsg->putting_binary)
-               return -EINVAL;
+       devlink_fmsg_err_if_binary(fmsg);
+       if (fmsg->err)
+               return fmsg->err;
 
-       if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
-               return -EMSGSIZE;
+       if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE) {
+               fmsg->err = -EMSGSIZE;
+               return fmsg->err;
+       }
 
        item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
-       if (!item)
-               return -ENOMEM;
+       if (!item) {
+               fmsg->err = -ENOMEM;
+               return fmsg->err;
+       }
 
        item->nla_type = NLA_NUL_STRING;
        item->len = strlen(name) + 1;
 
 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
 {
-       int err;
-
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
-       err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_put_name(fmsg, name);
-       if (err)
-               return err;
-
-       return 0;
+       devlink_fmsg_err_if_binary(fmsg);
+       devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
+       return devlink_fmsg_put_name(fmsg, name);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
 
 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
 {
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
        return devlink_fmsg_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
                                     const char *name)
 {
-       int err;
-
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
-       err = devlink_fmsg_pair_nest_start(fmsg, name);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
-       if (err)
-               return err;
-
-       return 0;
+       devlink_fmsg_pair_nest_start(fmsg, name);
+       return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
 
 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
 {
-       int err;
-
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
-       err = devlink_fmsg_nest_end(fmsg);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_nest_end(fmsg);
-       if (err)
-               return err;
-
-       return 0;
+       devlink_fmsg_nest_end(fmsg);
+       return devlink_fmsg_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
 
                return err;
 
        fmsg->putting_binary = true;
-       return err;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
 
 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
 {
-       if (!fmsg->putting_binary)
-               return -EINVAL;
+       if (fmsg->err)
+               return fmsg->err;
+
+       if (!fmsg->putting_binary) {
+               fmsg->err = -EINVAL;
+               return fmsg->err;
+       }
 
        fmsg->putting_binary = false;
        return devlink_fmsg_arr_pair_nest_end(fmsg);
 {
        struct devlink_fmsg_item *item;
 
-       if (value_len > DEVLINK_FMSG_MAX_SIZE)
-               return -EMSGSIZE;
+       if (value_len > DEVLINK_FMSG_MAX_SIZE) {
+               fmsg->err = -EMSGSIZE;
+               return fmsg->err;
+       }
 
        item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
-       if (!item)
-               return -ENOMEM;
+       if (!item) {
+               fmsg->err = -ENOMEM;
+               return fmsg->err;
+       }
 
        item->nla_type = value_nla_type;
        item->len = value_len;
 
 static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
 {
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
+       devlink_fmsg_err_if_binary(fmsg);
        return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
 }
 
 static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
 {
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
+       devlink_fmsg_err_if_binary(fmsg);
        return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
 }
 
 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
 {
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
+       devlink_fmsg_err_if_binary(fmsg);
        return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
 
 static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
 {
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
+       devlink_fmsg_err_if_binary(fmsg);
        return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
 }
 
 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
 {
-       if (fmsg->putting_binary)
-               return -EINVAL;
-
+       devlink_fmsg_err_if_binary(fmsg);
        return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
                                      NLA_NUL_STRING);
 }
 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
                               bool value)
 {
-       int err;
-
-       err = devlink_fmsg_pair_nest_start(fmsg, name);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_bool_put(fmsg, value);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_pair_nest_end(fmsg);
-       if (err)
-               return err;
-
-       return 0;
+       devlink_fmsg_pair_nest_start(fmsg, name);
+       devlink_fmsg_bool_put(fmsg, value);
+       return devlink_fmsg_pair_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
 
 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
                             u8 value)
 {
-       int err;
-
-       err = devlink_fmsg_pair_nest_start(fmsg, name);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_u8_put(fmsg, value);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_pair_nest_end(fmsg);
-       if (err)
-               return err;
-
-       return 0;
+       devlink_fmsg_pair_nest_start(fmsg, name);
+       devlink_fmsg_u8_put(fmsg, value);
+       return devlink_fmsg_pair_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
 
 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
                              u32 value)
 {
-       int err;
-
-       err = devlink_fmsg_pair_nest_start(fmsg, name);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_u32_put(fmsg, value);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_pair_nest_end(fmsg);
-       if (err)
-               return err;
-
-       return 0;
+       devlink_fmsg_pair_nest_start(fmsg, name);
+       devlink_fmsg_u32_put(fmsg, value);
+       return devlink_fmsg_pair_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
 
 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
                              u64 value)
 {
-       int err;
-
-       err = devlink_fmsg_pair_nest_start(fmsg, name);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_u64_put(fmsg, value);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_pair_nest_end(fmsg);
-       if (err)
-               return err;
-
-       return 0;
+       devlink_fmsg_pair_nest_start(fmsg, name);
+       devlink_fmsg_u64_put(fmsg, value);
+       return devlink_fmsg_pair_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
 
 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
                                 const char *value)
 {
-       int err;
-
-       err = devlink_fmsg_pair_nest_start(fmsg, name);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_string_put(fmsg, value);
-       if (err)
-               return err;
-
-       err = devlink_fmsg_pair_nest_end(fmsg);
-       if (err)
-               return err;
-
-       return 0;
+       devlink_fmsg_pair_nest_start(fmsg, name);
+       devlink_fmsg_string_put(fmsg, value);
+       return devlink_fmsg_pair_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
 
                                 const void *value, u32 value_len)
 {
        u32 data_size;
-       int end_err;
        u32 offset;
        int err;
 
                if (err)
                        break;
                /* Exit from loop with a break (instead of
-                * return) to make sure putting_binary is turned off in
-                * devlink_fmsg_binary_pair_nest_end
+                * return) to make sure putting_binary is turned off
                 */
        }
 
-       end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
-       if (end_err)
-               err = end_err;
+       err = devlink_fmsg_binary_pair_nest_end(fmsg);
+       fmsg->putting_binary = false;
 
        return err;
 }