| @@ -2515,6 +2515,45 @@ static int devlink_nl_cmd_resource_dump(struct sk_buff *skb, · 2514 unmodified lines |
| 2515 | return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); | 2515 | return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); |
| 2516 | } | 2516 | } |
| 2517 | | 2517 | |
| | 2518 | static int |
| | 2519 | devlink_resources_validate(struct devlink *devlink, |
| | 2520 | struct devlink_resource *resource, |
| | 2521 | struct genl_info *info) |
| | 2522 | { |
| | 2523 | struct list_head *resource_list; |
| | 2524 | int err = 0; |
| | 2525 | |
| | 2526 | if (resource) |
| | 2527 | resource_list = &resource->resource_list; |
| | 2528 | else |
| | 2529 | resource_list = &devlink->resource_list; |
| | 2530 | |
| | 2531 | list_for_each_entry(resource, resource_list, list) { |
| | 2532 | if (!resource->size_valid) |
| | 2533 | return -EINVAL; |
| | 2534 | err = devlink_resources_validate(devlink, resource, info); |
| | 2535 | if (err) |
| | 2536 | return err; |
| | 2537 | } |
| | 2538 | return err; |
| | 2539 | } |
| | 2540 | |
| | 2541 | static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) |
| | 2542 | { |
| | 2543 | struct devlink *devlink = info->user_ptr[0]; |
| | 2544 | int err; |
| | 2545 | |
| | 2546 | if (!devlink->ops->reload) |
| | 2547 | return -EOPNOTSUPP; |
| | 2548 | |
| | 2549 | err = devlink_resources_validate(devlink, NULL, info); |
| | 2550 | if (err) { |
| | 2551 | NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed"); |
| | 2552 | return err; |
| | 2553 | } |
| | 2554 | return devlink->ops->reload(devlink); |
| | 2555 | } |
| | 2556 | |
| 2518 | static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { | 2557 | static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { |
| 2519 | [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, | 2558 | [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, |
| 2520 | [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, | 2559 | [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, |
| @@ -2709,6 +2748,14 @@ static const struct genl_ops devlink_nl_ops[] = { · 188 unmodified lines |
| 2709 | .flags = GENL_ADMIN_PERM, | 2748 | .flags = GENL_ADMIN_PERM, |
| 2710 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, | 2749 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, |
| 2711 | }, | 2750 | }, |
| | 2751 | { |
| | 2752 | .cmd = DEVLINK_CMD_RELOAD, |
| | 2753 | .doit = devlink_nl_cmd_reload, |
| | 2754 | .policy = devlink_nl_policy, |
| | 2755 | .flags = GENL_ADMIN_PERM, |
| | 2756 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | |
| | 2757 | DEVLINK_NL_FLAG_NO_LOCK, |
| | 2758 | }, |
| 2712 | }; | 2759 | }; |
| 2713 | | 2760 | |
| 2714 | static struct genl_family devlink_nl_family __ro_after_init = { | 2761 | static struct genl_family devlink_nl_family __ro_after_init = { |