]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - fs/cifs/connect.c
cifs: move smb version mount options into fs_context.c
[mirror_ubuntu-jammy-kernel.git] / fs / cifs / connect.c
index a5731dd6e6566e7f86bac2db176f3c640a4d266f..c38156f324ddb5c1499148c943b205235d07120b 100644 (file)
@@ -61,6 +61,7 @@
 #ifdef CONFIG_CIFS_DFS_UPCALL
 #include "dfs_cache.h"
 #endif
+#include "fs_context.h"
 
 extern mempool_t *cifs_req_poolp;
 extern bool disable_legacy_dialects;
@@ -69,6 +70,9 @@ extern bool disable_legacy_dialects;
 #define TLINK_ERROR_EXPIRE     (1 * HZ)
 #define TLINK_IDLE_EXPIRE      (600 * HZ)
 
+/* Drop the connection to not overload the server */
+#define NUM_STATUS_IO_TIMEOUT   5
+
 enum {
        /* Mount options that take no arguments */
        Opt_user_xattr, Opt_nouser_xattr,
@@ -276,66 +280,6 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_err, NULL }
 };
 
-enum {
-       Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p,
-       Opt_sec_ntlmsspi, Opt_sec_ntlmssp,
-       Opt_ntlm, Opt_sec_ntlmi, Opt_sec_ntlmv2,
-       Opt_sec_ntlmv2i, Opt_sec_lanman,
-       Opt_sec_none,
-
-       Opt_sec_err
-};
-
-static const match_table_t cifs_secflavor_tokens = {
-       { Opt_sec_krb5, "krb5" },
-       { Opt_sec_krb5i, "krb5i" },
-       { Opt_sec_krb5p, "krb5p" },
-       { Opt_sec_ntlmsspi, "ntlmsspi" },
-       { Opt_sec_ntlmssp, "ntlmssp" },
-       { Opt_ntlm, "ntlm" },
-       { Opt_sec_ntlmi, "ntlmi" },
-       { Opt_sec_ntlmv2, "nontlm" },
-       { Opt_sec_ntlmv2, "ntlmv2" },
-       { Opt_sec_ntlmv2i, "ntlmv2i" },
-       { Opt_sec_lanman, "lanman" },
-       { Opt_sec_none, "none" },
-
-       { Opt_sec_err, NULL }
-};
-
-/* cache flavors */
-enum {
-       Opt_cache_loose,
-       Opt_cache_strict,
-       Opt_cache_none,
-       Opt_cache_ro,
-       Opt_cache_rw,
-       Opt_cache_err
-};
-
-static const match_table_t cifs_cacheflavor_tokens = {
-       { Opt_cache_loose, "loose" },
-       { Opt_cache_strict, "strict" },
-       { Opt_cache_none, "none" },
-       { Opt_cache_ro, "ro" },
-       { Opt_cache_rw, "singleclient" },
-       { Opt_cache_err, NULL }
-};
-
-static const match_table_t cifs_smb_version_tokens = {
-       { Smb_1, SMB1_VERSION_STRING },
-       { Smb_20, SMB20_VERSION_STRING},
-       { Smb_21, SMB21_VERSION_STRING },
-       { Smb_30, SMB30_VERSION_STRING },
-       { Smb_302, SMB302_VERSION_STRING },
-       { Smb_302, ALT_SMB302_VERSION_STRING },
-       { Smb_311, SMB311_VERSION_STRING },
-       { Smb_311, ALT_SMB311_VERSION_STRING },
-       { Smb_3any, SMB3ANY_VERSION_STRING },
-       { Smb_default, SMBDEFAULT_VERSION_STRING },
-       { Smb_version_err, NULL }
-};
-
 static int ip_connect(struct TCP_Server_Info *server);
 static int generic_ip_connect(struct TCP_Server_Info *server);
 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
@@ -1117,7 +1061,7 @@ cifs_demultiplex_thread(void *p)
        struct task_struct *task_to_wake = NULL;
        struct mid_q_entry *mids[MAX_COMPOUND];
        char *bufs[MAX_COMPOUND];
-       unsigned int noreclaim_flag;
+       unsigned int noreclaim_flag, num_io_timeout = 0;
 
        noreclaim_flag = memalloc_noreclaim_save();
        cifs_dbg(FYI, "Demultiplex PID: %d\n", task_pid_nr(current));
@@ -1213,6 +1157,16 @@ next_pdu:
                        continue;
                }
 
+               if (server->ops->is_status_io_timeout &&
+                   server->ops->is_status_io_timeout(buf)) {
+                       num_io_timeout++;
+                       if (num_io_timeout > NUM_STATUS_IO_TIMEOUT) {
+                               cifs_reconnect(server);
+                               num_io_timeout = 0;
+                               continue;
+                       }
+               }
+
                server->lstrp = jiffies;
 
                for (i = 0; i < num_mids; i++) {
@@ -1359,177 +1313,6 @@ static int get_option_gid(substring_t args[], kgid_t *result)
        return 0;
 }
 
-static int cifs_parse_security_flavors(char *value,
-                                      struct smb_vol *vol)
-{
-
-       substring_t args[MAX_OPT_ARGS];
-
-       /*
-        * With mount options, the last one should win. Reset any existing
-        * settings back to default.
-        */
-       vol->sectype = Unspecified;
-       vol->sign = false;
-
-       switch (match_token(value, cifs_secflavor_tokens, args)) {
-       case Opt_sec_krb5p:
-               cifs_dbg(VFS, "sec=krb5p is not supported!\n");
-               return 1;
-       case Opt_sec_krb5i:
-               vol->sign = true;
-               fallthrough;
-       case Opt_sec_krb5:
-               vol->sectype = Kerberos;
-               break;
-       case Opt_sec_ntlmsspi:
-               vol->sign = true;
-               fallthrough;
-       case Opt_sec_ntlmssp:
-               vol->sectype = RawNTLMSSP;
-               break;
-       case Opt_sec_ntlmi:
-               vol->sign = true;
-               fallthrough;
-       case Opt_ntlm:
-               vol->sectype = NTLM;
-               break;
-       case Opt_sec_ntlmv2i:
-               vol->sign = true;
-               fallthrough;
-       case Opt_sec_ntlmv2:
-               vol->sectype = NTLMv2;
-               break;
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-       case Opt_sec_lanman:
-               vol->sectype = LANMAN;
-               break;
-#endif
-       case Opt_sec_none:
-               vol->nullauth = 1;
-               break;
-       default:
-               cifs_dbg(VFS, "bad security option: %s\n", value);
-               return 1;
-       }
-
-       return 0;
-}
-
-static int
-cifs_parse_cache_flavor(char *value, struct smb_vol *vol)
-{
-       substring_t args[MAX_OPT_ARGS];
-
-       switch (match_token(value, cifs_cacheflavor_tokens, args)) {
-       case Opt_cache_loose:
-               vol->direct_io = false;
-               vol->strict_io = false;
-               vol->cache_ro = false;
-               vol->cache_rw = false;
-               break;
-       case Opt_cache_strict:
-               vol->direct_io = false;
-               vol->strict_io = true;
-               vol->cache_ro = false;
-               vol->cache_rw = false;
-               break;
-       case Opt_cache_none:
-               vol->direct_io = true;
-               vol->strict_io = false;
-               vol->cache_ro = false;
-               vol->cache_rw = false;
-               break;
-       case Opt_cache_ro:
-               vol->direct_io = false;
-               vol->strict_io = false;
-               vol->cache_ro = true;
-               vol->cache_rw = false;
-               break;
-       case Opt_cache_rw:
-               vol->direct_io = false;
-               vol->strict_io = false;
-               vol->cache_ro = false;
-               vol->cache_rw = true;
-               break;
-       default:
-               cifs_dbg(VFS, "bad cache= option: %s\n", value);
-               return 1;
-       }
-       return 0;
-}
-
-static int
-cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3)
-{
-       substring_t args[MAX_OPT_ARGS];
-
-       switch (match_token(value, cifs_smb_version_tokens, args)) {
-#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
-       case Smb_1:
-               if (disable_legacy_dialects) {
-                       cifs_dbg(VFS, "mount with legacy dialect disabled\n");
-                       return 1;
-               }
-               if (is_smb3) {
-                       cifs_dbg(VFS, "vers=1.0 (cifs) not permitted when mounting with smb3\n");
-                       return 1;
-               }
-               cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 is not recommended unless required for access to very old servers\n");
-               vol->ops = &smb1_operations;
-               vol->vals = &smb1_values;
-               break;
-       case Smb_20:
-               if (disable_legacy_dialects) {
-                       cifs_dbg(VFS, "mount with legacy dialect disabled\n");
-                       return 1;
-               }
-               if (is_smb3) {
-                       cifs_dbg(VFS, "vers=2.0 not permitted when mounting with smb3\n");
-                       return 1;
-               }
-               vol->ops = &smb20_operations;
-               vol->vals = &smb20_values;
-               break;
-#else
-       case Smb_1:
-               cifs_dbg(VFS, "vers=1.0 (cifs) mount not permitted when legacy dialects disabled\n");
-               return 1;
-       case Smb_20:
-               cifs_dbg(VFS, "vers=2.0 mount not permitted when legacy dialects disabled\n");
-               return 1;
-#endif /* CIFS_ALLOW_INSECURE_LEGACY */
-       case Smb_21:
-               vol->ops = &smb21_operations;
-               vol->vals = &smb21_values;
-               break;
-       case Smb_30:
-               vol->ops = &smb30_operations;
-               vol->vals = &smb30_values;
-               break;
-       case Smb_302:
-               vol->ops = &smb30_operations; /* currently identical with 3.0 */
-               vol->vals = &smb302_values;
-               break;
-       case Smb_311:
-               vol->ops = &smb311_operations;
-               vol->vals = &smb311_values;
-               break;
-       case Smb_3any:
-               vol->ops = &smb30_operations; /* currently identical with 3.0 */
-               vol->vals = &smb3any_values;
-               break;
-       case Smb_default:
-               vol->ops = &smb30_operations; /* currently identical with 3.0 */
-               vol->vals = &smbdefault_values;
-               break;
-       default:
-               cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value);
-               return 1;
-       }
-       return 0;
-}
-
 /*
  * Parse a devname into substrings and populate the vol->UNC and vol->prepath
  * fields with the result. Returns 0 on success and an error otherwise.
@@ -3595,7 +3378,10 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
         */
        tcon->retry = volume_info->retry;
        tcon->nocase = volume_info->nocase;
-       tcon->nohandlecache = volume_info->nohandlecache;
+       if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING)
+               tcon->nohandlecache = volume_info->nohandlecache;
+       else
+               tcon->nohandlecache = 1;
        tcon->nodelete = volume_info->nodelete;
        tcon->local_lease = volume_info->local_lease;
        INIT_LIST_HEAD(&tcon->pending_opens);
@@ -3889,13 +3675,21 @@ generic_ip_connect(struct TCP_Server_Info *server)
        saddr = (struct sockaddr *) &server->dstaddr;
 
        if (server->dstaddr.ss_family == AF_INET6) {
-               sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
+               struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&server->dstaddr;
+
+               sport = ipv6->sin6_port;
                slen = sizeof(struct sockaddr_in6);
                sfamily = AF_INET6;
+               cifs_dbg(FYI, "%s: connecting to [%pI6]:%d\n", __func__, &ipv6->sin6_addr,
+                               ntohs(sport));
        } else {
-               sport = ((struct sockaddr_in *) saddr)->sin_port;
+               struct sockaddr_in *ipv4 = (struct sockaddr_in *)&server->dstaddr;
+
+               sport = ipv4->sin_port;
                slen = sizeof(struct sockaddr_in);
                sfamily = AF_INET;
+               cifs_dbg(FYI, "%s: connecting to %pI4:%d\n", __func__, &ipv4->sin_addr,
+                               ntohs(sport));
        }
 
        if (socket == NULL) {