aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c66
1 files changed, 57 insertions, 9 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8463c940e0e5..b95db2b593cb 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -102,7 +102,7 @@ enum {
102 Opt_backupuid, Opt_backupgid, Opt_uid, 102 Opt_backupuid, Opt_backupgid, Opt_uid,
103 Opt_cruid, Opt_gid, Opt_file_mode, 103 Opt_cruid, Opt_gid, Opt_file_mode,
104 Opt_dirmode, Opt_port, 104 Opt_dirmode, Opt_port,
105 Opt_rsize, Opt_wsize, Opt_actimeo, 105 Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo,
106 Opt_echo_interval, Opt_max_credits, 106 Opt_echo_interval, Opt_max_credits,
107 Opt_snapshot, 107 Opt_snapshot,
108 108
@@ -204,6 +204,7 @@ static const match_table_t cifs_mount_option_tokens = {
204 { Opt_dirmode, "dirmode=%s" }, 204 { Opt_dirmode, "dirmode=%s" },
205 { Opt_dirmode, "dir_mode=%s" }, 205 { Opt_dirmode, "dir_mode=%s" },
206 { Opt_port, "port=%s" }, 206 { Opt_port, "port=%s" },
207 { Opt_blocksize, "bsize=%s" },
207 { Opt_rsize, "rsize=%s" }, 208 { Opt_rsize, "rsize=%s" },
208 { Opt_wsize, "wsize=%s" }, 209 { Opt_wsize, "wsize=%s" },
209 { Opt_actimeo, "actimeo=%s" }, 210 { Opt_actimeo, "actimeo=%s" },
@@ -348,7 +349,7 @@ static int reconn_set_ipaddr(struct TCP_Server_Info *server)
348 cifs_dbg(FYI, "%s: failed to create UNC path\n", __func__); 349 cifs_dbg(FYI, "%s: failed to create UNC path\n", __func__);
349 return -ENOMEM; 350 return -ENOMEM;
350 } 351 }
351 snprintf(unc, len, "\\\\%s", server->hostname); 352 scnprintf(unc, len, "\\\\%s", server->hostname);
352 353
353 rc = dns_resolve_server_name_to_ip(unc, &ipaddr); 354 rc = dns_resolve_server_name_to_ip(unc, &ipaddr);
354 kfree(unc); 355 kfree(unc);
@@ -592,6 +593,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
592 msleep(3000); 593 msleep(3000);
593 } else { 594 } else {
594 atomic_inc(&tcpSesReconnectCount); 595 atomic_inc(&tcpSesReconnectCount);
596 set_credits(server, 1);
595 spin_lock(&GlobalMid_Lock); 597 spin_lock(&GlobalMid_Lock);
596 if (server->tcpStatus != CifsExiting) 598 if (server->tcpStatus != CifsExiting)
597 server->tcpStatus = CifsNeedNegotiate; 599 server->tcpStatus = CifsNeedNegotiate;
@@ -1053,7 +1055,7 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1053 } 1055 }
1054 1056
1055 if (server->ops->is_status_pending && 1057 if (server->ops->is_status_pending &&
1056 server->ops->is_status_pending(buf, server, length)) 1058 server->ops->is_status_pending(buf, server))
1057 return -1; 1059 return -1;
1058 1060
1059 if (!mid) 1061 if (!mid)
@@ -1063,6 +1065,26 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1063 return 0; 1065 return 0;
1064} 1066}
1065 1067
1068static void
1069smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
1070{
1071 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
1072
1073 /*
1074 * SMB1 does not use credits.
1075 */
1076 if (server->vals->header_preamble_size)
1077 return;
1078
1079 if (shdr->CreditRequest) {
1080 spin_lock(&server->req_lock);
1081 server->credits += le16_to_cpu(shdr->CreditRequest);
1082 spin_unlock(&server->req_lock);
1083 wake_up(&server->request_q);
1084 }
1085}
1086
1087
1066static int 1088static int
1067cifs_demultiplex_thread(void *p) 1089cifs_demultiplex_thread(void *p)
1068{ 1090{
@@ -1192,6 +1214,7 @@ next_pdu:
1192 } else if (server->ops->is_oplock_break && 1214 } else if (server->ops->is_oplock_break &&
1193 server->ops->is_oplock_break(bufs[i], 1215 server->ops->is_oplock_break(bufs[i],
1194 server)) { 1216 server)) {
1217 smb2_add_credits_from_hdr(bufs[i], server);
1195 cifs_dbg(FYI, "Received oplock break\n"); 1218 cifs_dbg(FYI, "Received oplock break\n");
1196 } else { 1219 } else {
1197 cifs_dbg(VFS, "No task to wake, unknown frame " 1220 cifs_dbg(VFS, "No task to wake, unknown frame "
@@ -1203,6 +1226,7 @@ next_pdu:
1203 if (server->ops->dump_detail) 1226 if (server->ops->dump_detail)
1204 server->ops->dump_detail(bufs[i], 1227 server->ops->dump_detail(bufs[i],
1205 server); 1228 server);
1229 smb2_add_credits_from_hdr(bufs[i], server);
1206 cifs_dump_mids(server); 1230 cifs_dump_mids(server);
1207#endif /* CIFS_DEBUG2 */ 1231#endif /* CIFS_DEBUG2 */
1208 } 1232 }
@@ -1486,6 +1510,11 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol)
1486 const char *delims = "/\\"; 1510 const char *delims = "/\\";
1487 size_t len; 1511 size_t len;
1488 1512
1513 if (unlikely(!devname || !*devname)) {
1514 cifs_dbg(VFS, "Device name not specified.\n");
1515 return -EINVAL;
1516 }
1517
1489 /* make sure we have a valid UNC double delimiter prefix */ 1518 /* make sure we have a valid UNC double delimiter prefix */
1490 len = strspn(devname, delims); 1519 len = strspn(devname, delims);
1491 if (len != 2) 1520 if (len != 2)
@@ -1571,7 +1600,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1571 vol->cred_uid = current_uid(); 1600 vol->cred_uid = current_uid();
1572 vol->linux_uid = current_uid(); 1601 vol->linux_uid = current_uid();
1573 vol->linux_gid = current_gid(); 1602 vol->linux_gid = current_gid();
1574 1603 vol->bsize = 1024 * 1024; /* can improve cp performance significantly */
1575 /* 1604 /*
1576 * default to SFM style remapping of seven reserved characters 1605 * default to SFM style remapping of seven reserved characters
1577 * unless user overrides it or we negotiate CIFS POSIX where 1606 * unless user overrides it or we negotiate CIFS POSIX where
@@ -1944,6 +1973,26 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1944 } 1973 }
1945 port = (unsigned short)option; 1974 port = (unsigned short)option;
1946 break; 1975 break;
1976 case Opt_blocksize:
1977 if (get_option_ul(args, &option)) {
1978 cifs_dbg(VFS, "%s: Invalid blocksize value\n",
1979 __func__);
1980 goto cifs_parse_mount_err;
1981 }
1982 /*
1983 * inode blocksize realistically should never need to be
1984 * less than 16K or greater than 16M and default is 1MB.
1985 * Note that small inode block sizes (e.g. 64K) can lead
1986 * to very poor performance of common tools like cp and scp
1987 */
1988 if ((option < CIFS_MAX_MSGSIZE) ||
1989 (option > (4 * SMB3_DEFAULT_IOSIZE))) {
1990 cifs_dbg(VFS, "%s: Invalid blocksize\n",
1991 __func__);
1992 goto cifs_parse_mount_err;
1993 }
1994 vol->bsize = option;
1995 break;
1947 case Opt_rsize: 1996 case Opt_rsize:
1948 if (get_option_ul(args, &option)) { 1997 if (get_option_ul(args, &option)) {
1949 cifs_dbg(VFS, "%s: Invalid rsize value\n", 1998 cifs_dbg(VFS, "%s: Invalid rsize value\n",
@@ -2609,7 +2658,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2609 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); 2658 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
2610 tcp_ses->session_estab = false; 2659 tcp_ses->session_estab = false;
2611 tcp_ses->sequence_number = 0; 2660 tcp_ses->sequence_number = 0;
2612 tcp_ses->reconnect_instance = 0; 2661 tcp_ses->reconnect_instance = 1;
2613 tcp_ses->lstrp = jiffies; 2662 tcp_ses->lstrp = jiffies;
2614 spin_lock_init(&tcp_ses->req_lock); 2663 spin_lock_init(&tcp_ses->req_lock);
2615 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); 2664 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
@@ -2770,7 +2819,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info)
2770 if (tcon == NULL) 2819 if (tcon == NULL)
2771 return -ENOMEM; 2820 return -ENOMEM;
2772 2821
2773 snprintf(unc, sizeof(unc), "\\\\%s\\IPC$", ses->server->hostname); 2822 scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", ses->server->hostname);
2774 2823
2775 /* cannot fail */ 2824 /* cannot fail */
2776 nls_codepage = load_nls_default(); 2825 nls_codepage = load_nls_default();
@@ -3839,6 +3888,7 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
3839 spin_lock_init(&cifs_sb->tlink_tree_lock); 3888 spin_lock_init(&cifs_sb->tlink_tree_lock);
3840 cifs_sb->tlink_tree = RB_ROOT; 3889 cifs_sb->tlink_tree = RB_ROOT;
3841 3890
3891 cifs_sb->bsize = pvolume_info->bsize;
3842 /* 3892 /*
3843 * Temporarily set r/wsize for matching superblock. If we end up using 3893 * Temporarily set r/wsize for matching superblock. If we end up using
3844 * new sb then client will later negotiate it downward if needed. 3894 * new sb then client will later negotiate it downward if needed.
@@ -4198,7 +4248,7 @@ static int update_vol_info(const struct dfs_cache_tgt_iterator *tgt_it,
4198 new_unc = kmalloc(len, GFP_KERNEL); 4248 new_unc = kmalloc(len, GFP_KERNEL);
4199 if (!new_unc) 4249 if (!new_unc)
4200 return -ENOMEM; 4250 return -ENOMEM;
4201 snprintf(new_unc, len, "\\%s", tgt); 4251 scnprintf(new_unc, len, "\\%s", tgt);
4202 4252
4203 kfree(vol->UNC); 4253 kfree(vol->UNC);
4204 vol->UNC = new_unc; 4254 vol->UNC = new_unc;
@@ -4902,8 +4952,6 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
4902 if (!server->ops->need_neg(server)) 4952 if (!server->ops->need_neg(server))
4903 return 0; 4953 return 0;
4904 4954
4905 set_credits(server, 1);
4906
4907 rc = server->ops->negotiate(xid, ses); 4955 rc = server->ops->negotiate(xid, ses);
4908 if (rc == 0) { 4956 if (rc == 0) {
4909 spin_lock(&GlobalMid_Lock); 4957 spin_lock(&GlobalMid_Lock);