]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
cifs: Fix lookup of SMB connections on multichannel
authorPaulo Alcantara (SUSE) <pc@cjr.nz>
Wed, 4 Dec 2019 14:25:06 +0000 (11:25 -0300)
committerSteve French <stfrench@microsoft.com>
Wed, 4 Dec 2019 17:50:32 +0000 (11:50 -0600)
With the addition of SMB session channels, we introduced new TCP
server pointers that have no sessions or tcons associated with them.

In this case, when we started looking for TCP connections, we might
end up picking session channel rather than the master connection,
hence failing to get either a session or a tcon.

In order to fix that, this patch introduces a new "is_channel" field
to TCP_Server_Info structure so we can skip session channels during
lookup of connections.

Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/sess.c

index 5b976e01dd6be7970f70d0e886915e668432f376..fd0262ce5ad5b8ec55960c271ad72c960a2763c1 100644 (file)
@@ -777,6 +777,7 @@ struct TCP_Server_Info {
         */
        int nr_targets;
        bool noblockcnt; /* use non-blocking connect() */
+       bool is_channel; /* if a session channel */
 };
 
 struct cifs_credits {
index 86d1baedf21ca35d00337068a6d83125f15e6fab..05ea0e2b7e0e88cb63dcf546c777e2bbf4b9cf43 100644 (file)
@@ -2712,7 +2712,11 @@ cifs_find_tcp_session(struct smb_vol *vol)
 
        spin_lock(&cifs_tcp_ses_lock);
        list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
-               if (!match_server(server, vol))
+               /*
+                * Skip ses channels since they're only handled in lower layers
+                * (e.g. cifs_send_recv).
+                */
+               if (server->is_channel || !match_server(server, vol))
                        continue;
 
                ++server->srv_count;
index fb3bdc44775c118c0261dbceedc8071a0f25534c..d95137304224463e7ac0ca0b3aa4e785011d7269 100644 (file)
@@ -213,6 +213,9 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
                chan->server = NULL;
                goto out;
        }
+       spin_lock(&cifs_tcp_ses_lock);
+       chan->server->is_channel = true;
+       spin_unlock(&cifs_tcp_ses_lock);
 
        /*
         * We need to allocate the server crypto now as we will need