cifs: fix status checks in cifs_tree_connect
authorShyam Prasad N <sprasad@microsoft.com>
Fri, 9 Jun 2023 17:46:54 +0000 (17:46 +0000)
committerSteve French <stfrench@microsoft.com>
Mon, 12 Jun 2023 01:52:48 +0000 (20:52 -0500)
The ordering of status checks at the beginning of
cifs_tree_connect is wrong. As a result, a tcon
which is good may stay marked as needing reconnect
infinitely.

Fixes: 2f0e4f034220 ("cifs: check only tcon status on tcon related functions")
Cc: stable@vger.kernel.org # 6.3
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/connect.c
fs/smb/client/dfs.c

index 8e9a672320ab72dcdc26ed92310f0a5d0a2792eb..1250d156619b750e26d9f371425c8e93cbc2eb63 100644 (file)
@@ -4086,16 +4086,17 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
 
        /* only send once per connect */
        spin_lock(&tcon->tc_lock);
+       if (tcon->status == TID_GOOD) {
+               spin_unlock(&tcon->tc_lock);
+               return 0;
+       }
+
        if (tcon->status != TID_NEW &&
            tcon->status != TID_NEED_TCON) {
                spin_unlock(&tcon->tc_lock);
                return -EHOSTDOWN;
        }
 
-       if (tcon->status == TID_GOOD) {
-               spin_unlock(&tcon->tc_lock);
-               return 0;
-       }
        tcon->status = TID_IN_TCON;
        spin_unlock(&tcon->tc_lock);
 
index 2f93bf8c3325ac3d090600a21e3e660306dbc74c..2390b2fedd6a3292d9e48a600ec4da4166157bba 100644 (file)
@@ -575,16 +575,17 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
 
        /* only send once per connect */
        spin_lock(&tcon->tc_lock);
+       if (tcon->status == TID_GOOD) {
+               spin_unlock(&tcon->tc_lock);
+               return 0;
+       }
+
        if (tcon->status != TID_NEW &&
            tcon->status != TID_NEED_TCON) {
                spin_unlock(&tcon->tc_lock);
                return -EHOSTDOWN;
        }
 
-       if (tcon->status == TID_GOOD) {
-               spin_unlock(&tcon->tc_lock);
-               return 0;
-       }
        tcon->status = TID_IN_TCON;
        spin_unlock(&tcon->tc_lock);