Skip to content

Commit

Permalink
smb3: do not log confusing message when server returns no network int…
Browse files Browse the repository at this point in the history
…erfaces

Some servers can return an empty network interface list so, unless
multichannel is requested, no need to log an error for this, and
when multichannel is requested on mount but no interfaces, log
something less confusing.  For this case change
   parse_server_interfaces: malformed interface info
to
   empty network interface list returned by server localhost

Also do not relog this error every ten minutes (only log on mount, once)

Cc: <stable@vger.kernel.org>
Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Signed-off-by: Steve French <stfrench@microsoft.com>
  • Loading branch information
Steve French committed Oct 5, 2022
1 parent 3afdfb0 commit 4659f01
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
2 changes: 1 addition & 1 deletion fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ cifs_chan_is_iface_active(struct cifs_ses *ses,
int
cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server);
int
SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon);
SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount);

void extract_unc_hostname(const char *unc, const char **h, size_t *len);
int copy_path_name(char *dst, const char *src);
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ static void smb2_query_server_interfaces(struct work_struct *work)
/*
* query server network interfaces, in case they change
*/
rc = SMB3_request_interfaces(0, tcon);
rc = SMB3_request_interfaces(0, tcon, false);
if (rc) {
cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
__func__, rc);
Expand Down
23 changes: 18 additions & 5 deletions fs/cifs/smb2ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,7 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)

static int
parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
size_t buf_len,
struct cifs_ses *ses)
size_t buf_len, struct cifs_ses *ses, bool in_mount)
{
struct network_interface_info_ioctl_rsp *p;
struct sockaddr_in *addr4;
Expand Down Expand Up @@ -543,6 +542,20 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
}
spin_unlock(&ses->iface_lock);

/*
* Samba server e.g. can return an empty interface list in some cases,
* which would only be a problem if we were requesting multichannel
*/
if (bytes_left == 0) {
/* avoid spamming logs every 10 minutes, so log only in mount */
if ((ses->chan_max > 1) && in_mount)
cifs_dbg(VFS,
"empty network interface list returned by server %s\n",
ses->server->hostname);
rc = -EINVAL;
goto out;
}

while (bytes_left >= sizeof(*p)) {
memset(&tmp_iface, 0, sizeof(tmp_iface));
tmp_iface.speed = le64_to_cpu(p->LinkSpeed);
Expand Down Expand Up @@ -673,7 +686,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
}

int
SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount)
{
int rc;
unsigned int ret_data_len = 0;
Expand All @@ -693,7 +706,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
goto out;
}

rc = parse_server_interfaces(out_buf, ret_data_len, ses);
rc = parse_server_interfaces(out_buf, ret_data_len, ses, in_mount);
if (rc)
goto out;

Expand Down Expand Up @@ -729,7 +742,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
if (rc)
return;

SMB3_request_interfaces(xid, tcon);
SMB3_request_interfaces(xid, tcon, true /* called during mount */);

SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
FS_ATTRIBUTE_INFORMATION);
Expand Down

0 comments on commit 4659f01

Please sign in to comment.