@@ -19,6 +19,7 @@ struct devlink_fmsg_item {
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:
@@ -562,10 +563,8 @@ static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
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)
@@ -670,43 +669,46 @@ int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
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);
return 0;
}
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);
@@ -717,15 +719,20 @@ static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
{
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;
@@ -738,68 +745,30 @@ static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
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);
@@ -813,14 +782,19 @@ int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
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);
@@ -833,12 +807,16 @@ static int devlink_fmsg_put_value(struct devlink_fmsg *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;
@@ -851,42 +829,32 @@ static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
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);
}
@@ -905,113 +873,52 @@ EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
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);
int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
const void *value, u32 value_len)
{
u32 data_size;
- int end_err;
u32 offset;
int err;
@@ -1027,14 +934,12 @@ int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
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;
}