Skip to content

Commit 83e6c09

Browse files
sprasad-microsoftgregkh
authored andcommitted
cifs: reset iface weights when we cannot find a candidate
commit 9d5eff7 upstream. We now do a weighted selection of server interfaces when allocating new channels. The weights are decided based on the speed advertised. The fulfilled weight for an interface is a counter that is used to track the interface selection. It should be reset back to zero once all interfaces fulfilling their weight. In cifs_chan_update_iface, this reset logic was missing. As a result when the server interface list changes, the client may not be able to find a new candidate for other channels after all interfaces have been fulfilled. Fixes: a6d8fb5 ("cifs: distribute channels across interfaces based on speed") Cc: <stable@vger.kernel.org> Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent f1c5c55 commit 83e6c09

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

fs/smb/client/sess.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
360360
struct cifs_server_iface *old_iface = NULL;
361361
struct cifs_server_iface *last_iface = NULL;
362362
struct sockaddr_storage ss;
363+
int retry = 0;
363364

364365
spin_lock(&ses->chan_lock);
365366
chan_index = cifs_ses_get_chan_index(ses, server);
@@ -388,6 +389,7 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
388389
return;
389390
}
390391

392+
try_again:
391393
last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface,
392394
iface_head);
393395
iface_min_speed = last_iface->speed;
@@ -425,6 +427,13 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
425427
}
426428

427429
if (list_entry_is_head(iface, &ses->iface_list, iface_head)) {
430+
list_for_each_entry(iface, &ses->iface_list, iface_head)
431+
iface->weight_fulfilled = 0;
432+
433+
/* see if it can be satisfied in second attempt */
434+
if (!retry++)
435+
goto try_again;
436+
428437
iface = NULL;
429438
cifs_dbg(FYI, "unable to find a suitable iface\n");
430439
}

0 commit comments

Comments
 (0)