]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cifs: Don't need state locking in smb2_get_mid_entry()
authorDavid Howells <dhowells@redhat.com>
Mon, 4 Aug 2025 08:38:21 +0000 (09:38 +0100)
committerSteve French <stfrench@microsoft.com>
Fri, 5 Dec 2025 23:11:06 +0000 (17:11 -0600)
There's no need to get ->srv_lock or ->ses_lock in smb2_get_mid_entry() as
all that happens of relevance (to the lock) inside the locked sections is
the reading of one status value in each.

Replace the locking with READ_ONCE() and use a switch instead of a chain of
if-statements.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/smb2transport.c

index d06f872c9ab25a3c4251c0f7909626c82416f4ec..99fa48bcd459866be1f52fa3ea690efdd6417cc4 100644 (file)
@@ -684,43 +684,35 @@ static int
 smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
                   struct smb2_hdr *shdr, struct mid_q_entry **mid)
 {
-       spin_lock(&server->srv_lock);
-       if (server->tcpStatus == CifsExiting) {
-               spin_unlock(&server->srv_lock);
+       switch (READ_ONCE(server->tcpStatus)) {
+       case CifsExiting:
                return -ENOENT;
-       }
-
-       if (server->tcpStatus == CifsNeedReconnect) {
-               spin_unlock(&server->srv_lock);
+       case CifsNeedReconnect:
                cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
                return -EAGAIN;
-       }
-
-       if (server->tcpStatus == CifsNeedNegotiate &&
-          shdr->Command != SMB2_NEGOTIATE) {
-               spin_unlock(&server->srv_lock);
-               return -EAGAIN;
-       }
-       spin_unlock(&server->srv_lock);
-
-       spin_lock(&ses->ses_lock);
-       if (ses->ses_status == SES_NEW) {
-               if ((shdr->Command != SMB2_SESSION_SETUP) &&
-                   (shdr->Command != SMB2_NEGOTIATE)) {
-                       spin_unlock(&ses->ses_lock);
+       case CifsNeedNegotiate:
+               if (shdr->Command != SMB2_NEGOTIATE)
                        return -EAGAIN;
-               }
-               /* else ok - we are setting up session */
+               break;
+       default:
+               break;
        }
 
-       if (ses->ses_status == SES_EXITING) {
-               if (shdr->Command != SMB2_LOGOFF) {
-                       spin_unlock(&ses->ses_lock);
+       switch (READ_ONCE(ses->ses_status)) {
+       case SES_NEW:
+               if (shdr->Command != SMB2_SESSION_SETUP &&
+                   shdr->Command != SMB2_NEGOTIATE)
+                       return -EAGAIN;
+                       /* else ok - we are setting up session */
+               break;
+       case SES_EXITING:
+               if (shdr->Command != SMB2_LOGOFF)
                        return -EAGAIN;
-               }
                /* else ok - we are shutting down the session */
+               break;
+       default:
+               break;
        }
-       spin_unlock(&ses->ses_lock);
 
        *mid = smb2_mid_entry_alloc(shdr, server);
        if (*mid == NULL)