cifs: fix reconnect with SMB1 UNIX Extensions
authorSteve French <stfrench@microsoft.com>
Tue, 23 Jul 2024 04:40:08 +0000 (23:40 -0500)
committerSteve French <stfrench@microsoft.com>
Tue, 23 Jul 2024 22:45:49 +0000 (17:45 -0500)
When mounting with the SMB1 Unix Extensions (e.g. mounts
to Samba with vers=1.0), reconnects no longer reset the
Unix Extensions (SetFSInfo SET_FILE_UNIX_BASIC) after tcon so most
operations (e.g. stat, ls, open, statfs) will fail continuously
with:
        "Operation not supported"
if the connection ever resets (e.g. due to brief network disconnect)

Cc: stable@vger.kernel.org
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/connect.c

index 7a16e12..89d9f86 100644 (file)
@@ -3686,6 +3686,7 @@ error:
 }
 #endif
 
+#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
 /*
  * Issue a TREE_CONNECT request.
  */
@@ -3807,11 +3808,25 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
                else
                        tcon->Flags = 0;
                cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
-       }
 
+               /*
+                * reset_cifs_unix_caps calls QFSInfo which requires
+                * need_reconnect to be false, but we would not need to call
+                * reset_caps if this were not a reconnect case so must check
+                * need_reconnect flag here.  The caller will also clear
+                * need_reconnect when tcon was successful but needed to be
+                * cleared earlier in the case of unix extensions reconnect
+                */
+               if (tcon->need_reconnect && tcon->unix_ext) {
+                       cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name);
+                       tcon->need_reconnect = false;
+                       reset_cifs_unix_caps(xid, tcon, NULL, NULL);
+               }
+       }
        cifs_buf_release(smb_buffer);
        return rc;
 }
+#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 
 static void delayed_free(struct rcu_head *p)
 {