Skip to content

Commit 50e63d6

Browse files
ematsumiyasmfrench
authored andcommitted
smb/client: print "Unknown" instead of bogus link speed value
The virtio driver for Linux guests will not set a link speed to its paravirtualized NICs. This will be seen as -1 in the ethernet layer, and when some servers (e.g. samba) fetches it, it's converted to an unsigned value (and multiplied by 1000 * 1000), so in client side we end up with: 1) Speed: 4294967295000000 bps in DebugData. This patch introduces a helper that returns a speed string (in Mbps or Gbps) if interface speed is valid (>= SPEED_10 and <= SPEED_800000), or "Unknown" otherwise. The reason to not change the value in iface->speed is because we don't know the real speed of the HW backing the server NIC, so let's keep considering these as the fastest NICs available. Also print "Capabilities: None" when the interface doesn't support any. Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de> Reviewed-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 2a44b38 commit 50e63d6

1 file changed

Lines changed: 46 additions & 1 deletion

File tree

fs/smb/client/cifs_debug.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/module.h>
1313
#include <linux/proc_fs.h>
1414
#include <linux/uaccess.h>
15+
#include <uapi/linux/ethtool.h>
1516
#include "cifspdu.h"
1617
#include "cifsglob.h"
1718
#include "cifsproto.h"
@@ -148,18 +149,62 @@ cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan)
148149
atomic_read(&server->num_waiters));
149150
}
150151

152+
static inline const char *smb_speed_to_str(size_t bps)
153+
{
154+
size_t mbps = bps / 1000 / 1000;
155+
156+
switch (mbps) {
157+
case SPEED_10:
158+
return "10Mbps";
159+
case SPEED_100:
160+
return "100Mbps";
161+
case SPEED_1000:
162+
return "1Gbps";
163+
case SPEED_2500:
164+
return "2.5Gbps";
165+
case SPEED_5000:
166+
return "5Gbps";
167+
case SPEED_10000:
168+
return "10Gbps";
169+
case SPEED_14000:
170+
return "14Gbps";
171+
case SPEED_20000:
172+
return "20Gbps";
173+
case SPEED_25000:
174+
return "25Gbps";
175+
case SPEED_40000:
176+
return "40Gbps";
177+
case SPEED_50000:
178+
return "50Gbps";
179+
case SPEED_56000:
180+
return "56Gbps";
181+
case SPEED_100000:
182+
return "100Gbps";
183+
case SPEED_200000:
184+
return "200Gbps";
185+
case SPEED_400000:
186+
return "400Gbps";
187+
case SPEED_800000:
188+
return "800Gbps";
189+
default:
190+
return "Unknown";
191+
}
192+
}
193+
151194
static void
152195
cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface)
153196
{
154197
struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
155198
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
156199

157-
seq_printf(m, "\tSpeed: %zu bps\n", iface->speed);
200+
seq_printf(m, "\tSpeed: %s\n", smb_speed_to_str(iface->speed));
158201
seq_puts(m, "\t\tCapabilities: ");
159202
if (iface->rdma_capable)
160203
seq_puts(m, "rdma ");
161204
if (iface->rss_capable)
162205
seq_puts(m, "rss ");
206+
if (!iface->rdma_capable && !iface->rss_capable)
207+
seq_puts(m, "None");
163208
seq_putc(m, '\n');
164209
if (iface->sockaddr.ss_family == AF_INET)
165210
seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr);

0 commit comments

Comments
 (0)