Skip to content

Commit 84f1fd0

Browse files
sprasad-microsoftjohn-cabaj
authored andcommitted
cifs: serialize other channels when query server interfaces is pending
BugLink: https://bugs.launchpad.net/bugs/2118807 Today, during smb2_reconnect, session_mutex is released as soon as the tcon is reconnected and is in a good state. However, in case multichannel is enabled, there is also a query of server interfaces that follows. We've seen that this query can race with reconnects of other channels, causing them to step on each other with reconnects. This change extends the hold of session_mutex till after the query of server interfaces is complete. In order to avoid recursive smb2_reconnect checks during query ioctl, this change also introduces a session flag for sessions where such a query is in progress. Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Cc: stable@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com> (cherry picked from commit b5e3e6e28cf3853566ba5d816f79aba5be579158) Signed-off-by: Vinicius Peixoto <vinicius.peixoto@canonical.com> Acked-by: Manuel Diewald <manuel.diewald@canonical.com> Acked-by: Alessio Faina <alessio.faina@canonical.com> Signed-off-by: Vinicius Peixoto <vinicius.peixoto@canonical.com>
1 parent 2670047 commit 84f1fd0

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

fs/smb/client/cifsglob.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,7 @@ struct cifs_chan {
10831083
};
10841084

10851085
#define CIFS_SES_FLAG_SCALE_CHANNELS (0x1)
1086+
#define CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES (0x2)
10861087

10871088
/*
10881089
* Session structure. One of these for each uid session with a particular host

fs/smb/client/smb2pdu.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -410,14 +410,19 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
410410
if (!rc &&
411411
(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL) &&
412412
server->ops->query_server_interfaces) {
413-
mutex_unlock(&ses->session_mutex);
414-
415413
/*
416-
* query server network interfaces, in case they change
414+
* query server network interfaces, in case they change.
415+
* Also mark the session as pending this update while the query
416+
* is in progress. This will be used to avoid calling
417+
* smb2_reconnect recursively.
417418
*/
419+
ses->flags |= CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES;
418420
xid = get_xid();
419421
rc = server->ops->query_server_interfaces(xid, tcon, false);
420422
free_xid(xid);
423+
ses->flags &= ~CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES;
424+
425+
mutex_unlock(&ses->session_mutex);
421426

422427
if (rc == -EOPNOTSUPP && ses->chan_count > 1) {
423428
/*
@@ -559,11 +564,18 @@ static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon,
559564
struct TCP_Server_Info *server,
560565
void **request_buf, unsigned int *total_len)
561566
{
562-
/* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */
563-
if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) {
567+
/*
568+
* Skip reconnect in one of the following cases:
569+
* 1. For FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs
570+
* 2. For FSCTL_QUERY_NETWORK_INTERFACE_INFO IOCTL when called from
571+
* smb2_reconnect (indicated by CIFS_SES_FLAG_SCALE_CHANNELS ses flag)
572+
*/
573+
if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO ||
574+
(opcode == FSCTL_QUERY_NETWORK_INTERFACE_INFO &&
575+
(tcon->ses->flags & CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES)))
564576
return __smb2_plain_req_init(SMB2_IOCTL, tcon, server,
565577
request_buf, total_len);
566-
}
578+
567579
return smb2_plain_req_init(SMB2_IOCTL, tcon, server,
568580
request_buf, total_len);
569581
}

0 commit comments

Comments
 (0)