cifs: avoid unnecessary iteration of tcp sessions
authorShyam Prasad N <sprasad@microsoft.com>
Fri, 28 Oct 2022 10:01:45 +0000 (10:01 +0000)
committerSteve French <stfrench@microsoft.com>
Sat, 5 Nov 2022 04:34:40 +0000 (23:34 -0500)
In a few places, we do unnecessary iterations of
tcp sessions, even when the server struct is provided.

The change avoids it and uses the server struct provided.

Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2transport.c

index e73a3c649b877728b7505e69549edce812f8813f..572293c18e16f5ab86a9b6e45515c49dc521a1c5 100644 (file)
@@ -612,51 +612,52 @@ smb2_tcon_find_pending_open_lease(struct cifs_tcon *tcon,
 }
 
 static bool
-smb2_is_valid_lease_break(char *buffer)
+smb2_is_valid_lease_break(char *buffer, struct TCP_Server_Info *server)
 {
        struct smb2_lease_break *rsp = (struct smb2_lease_break *)buffer;
-       struct TCP_Server_Info *server;
+       struct TCP_Server_Info *pserver;
        struct cifs_ses *ses;
        struct cifs_tcon *tcon;
        struct cifs_pending_open *open;
 
        cifs_dbg(FYI, "Checking for lease break\n");
 
+       /* If server is a channel, select the primary channel */
+       pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
+
        /* look up tcon based on tid & uid */
        spin_lock(&cifs_tcp_ses_lock);
-       list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
-               list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
-                       list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
-                               spin_lock(&tcon->open_file_lock);
-                               cifs_stats_inc(
-                                   &tcon->stats.cifs_stats.num_oplock_brks);
-                               if (smb2_tcon_has_lease(tcon, rsp)) {
-                                       spin_unlock(&tcon->open_file_lock);
-                                       spin_unlock(&cifs_tcp_ses_lock);
-                                       return true;
-                               }
-                               open = smb2_tcon_find_pending_open_lease(tcon,
-                                                                        rsp);
-                               if (open) {
-                                       __u8 lease_key[SMB2_LEASE_KEY_SIZE];
-                                       struct tcon_link *tlink;
-
-                                       tlink = cifs_get_tlink(open->tlink);
-                                       memcpy(lease_key, open->lease_key,
-                                              SMB2_LEASE_KEY_SIZE);
-                                       spin_unlock(&tcon->open_file_lock);
-                                       spin_unlock(&cifs_tcp_ses_lock);
-                                       smb2_queue_pending_open_break(tlink,
-                                                                     lease_key,
-                                                                     rsp->NewLeaseState);
-                                       return true;
-                               }
+       list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+               list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+                       spin_lock(&tcon->open_file_lock);
+                       cifs_stats_inc(
+                                      &tcon->stats.cifs_stats.num_oplock_brks);
+                       if (smb2_tcon_has_lease(tcon, rsp)) {
                                spin_unlock(&tcon->open_file_lock);
+                               spin_unlock(&cifs_tcp_ses_lock);
+                               return true;
+                       }
+                       open = smb2_tcon_find_pending_open_lease(tcon,
+                                                                rsp);
+                       if (open) {
+                               __u8 lease_key[SMB2_LEASE_KEY_SIZE];
+                               struct tcon_link *tlink;
+
+                               tlink = cifs_get_tlink(open->tlink);
+                               memcpy(lease_key, open->lease_key,
+                                      SMB2_LEASE_KEY_SIZE);
+                               spin_unlock(&tcon->open_file_lock);
+                               spin_unlock(&cifs_tcp_ses_lock);
+                               smb2_queue_pending_open_break(tlink,
+                                                             lease_key,
+                                                             rsp->NewLeaseState);
+                               return true;
+                       }
+                       spin_unlock(&tcon->open_file_lock);
 
-                               if (cached_dir_lease_break(tcon, rsp->LeaseKey)) {
-                                       spin_unlock(&cifs_tcp_ses_lock);
-                                       return true;
-                               }
+                       if (cached_dir_lease_break(tcon, rsp->LeaseKey)) {
+                               spin_unlock(&cifs_tcp_ses_lock);
+                               return true;
                        }
                }
        }
@@ -689,7 +690,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
        if (rsp->StructureSize !=
                                smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
                if (le16_to_cpu(rsp->StructureSize) == 44)
-                       return smb2_is_valid_lease_break(buffer);
+                       return smb2_is_valid_lease_break(buffer, server);
                else
                        return false;
        }
index cca12eadbb07306d28578bcefe30f962d85f81d0..880cd494afea443d8c91608dbb682f2ea5d18aeb 100644 (file)
@@ -4268,21 +4268,23 @@ init_sg(int num_rqst, struct smb_rqst *rqst, u8 *sign)
 static int
 smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
 {
+       struct TCP_Server_Info *pserver;
        struct cifs_ses *ses;
        u8 *ses_enc_key;
 
+       /* If server is a channel, select the primary channel */
+       pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
+
        spin_lock(&cifs_tcp_ses_lock);
-       list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
-               list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
-                       if (ses->Suid == ses_id) {
-                               spin_lock(&ses->ses_lock);
-                               ses_enc_key = enc ? ses->smb3encryptionkey :
-                                       ses->smb3decryptionkey;
-                               memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
-                               spin_unlock(&ses->ses_lock);
-                               spin_unlock(&cifs_tcp_ses_lock);
-                               return 0;
-                       }
+       list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+               if (ses->Suid == ses_id) {
+                       spin_lock(&ses->ses_lock);
+                       ses_enc_key = enc ? ses->smb3encryptionkey :
+                               ses->smb3decryptionkey;
+                       memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
+                       spin_unlock(&ses->ses_lock);
+                       spin_unlock(&cifs_tcp_ses_lock);
+                       return 0;
                }
        }
        spin_unlock(&cifs_tcp_ses_lock);
index 8a9d9d08cf19e7a2b156f592d24421a940efd3c8..381babc1212c9e8a95911e6382e5ba4ff5c3cc80 100644 (file)
@@ -77,18 +77,19 @@ static
 int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
 {
        struct cifs_chan *chan;
+       struct TCP_Server_Info *pserver;
        struct cifs_ses *ses = NULL;
-       struct TCP_Server_Info *it = NULL;
        int i;
        int rc = 0;
 
        spin_lock(&cifs_tcp_ses_lock);
 
-       list_for_each_entry(it, &cifs_tcp_ses_list, tcp_ses_list) {
-               list_for_each_entry(ses, &it->smb_ses_list, smb_ses_list) {
-                       if (ses->Suid == ses_id)
-                               goto found;
-               }
+       /* If server is a channel, select the primary channel */
+       pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
+
+       list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+               if (ses->Suid == ses_id)
+                       goto found;
        }
        cifs_server_dbg(VFS, "%s: Could not find session 0x%llx\n",
                        __func__, ses_id);