| From foo@baz Sun 09 Feb 2020 10:47:54 PM CET |
| From: Jacob Keller <jacob.e.keller@intel.com> |
| Date: Tue, 4 Feb 2020 15:59:50 -0800 |
| Subject: devlink: report 0 after hitting end in region read |
| |
| From: Jacob Keller <jacob.e.keller@intel.com> |
| |
| [ Upstream commit d5b90e99e1d51b7b5d2b74fbc4c2db236a510913 ] |
| |
| commit fdd41ec21e15 ("devlink: Return right error code in case of errors |
| for region read") modified the region read code to report errors |
| properly in unexpected cases. |
| |
| In the case where the start_offset and ret_offset match, it unilaterally |
| converted this into an error. This causes an issue for the "dump" |
| version of the command. In this case, the devlink region dump will |
| always report an invalid argument: |
| |
| 000000000000ffd0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
| 000000000000ffe0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
| devlink answers: Invalid argument |
| 000000000000fff0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
| |
| This occurs because the expected flow for the dump is to return 0 after |
| there is no further data. |
| |
| The simplest fix would be to stop converting the error code to -EINVAL |
| if start_offset == ret_offset. However, avoid unnecessary work by |
| checking for when start_offset is larger than the region size and |
| returning 0 upfront. |
| |
| Fixes: fdd41ec21e15 ("devlink: Return right error code in case of errors for region read") |
| Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> |
| Acked-by: Jiri Pirko <jiri@mellanox.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/core/devlink.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/net/core/devlink.c |
| +++ b/net/core/devlink.c |
| @@ -3986,6 +3986,12 @@ static int devlink_nl_cmd_region_read_du |
| goto out_unlock; |
| } |
| |
| + /* return 0 if there is no further data to read */ |
| + if (start_offset >= region->size) { |
| + err = 0; |
| + goto out_unlock; |
| + } |
| + |
| hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, |
| &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, |
| DEVLINK_CMD_REGION_READ); |