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.c52
1 files changed, 40 insertions, 12 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 63ea83ff687f..d9566bf8f917 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -23,6 +23,7 @@
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/list.h> 24#include <linux/list.h>
25#include <linux/wait.h> 25#include <linux/wait.h>
26#include <linux/slab.h>
26#include <linux/pagemap.h> 27#include <linux/pagemap.h>
27#include <linux/ctype.h> 28#include <linux/ctype.h>
28#include <linux/utsname.h> 29#include <linux/utsname.h>
@@ -98,7 +99,7 @@ struct smb_vol {
98 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ 99 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
99 unsigned int rsize; 100 unsigned int rsize;
100 unsigned int wsize; 101 unsigned int wsize;
101 unsigned int sockopt; 102 bool sockopt_tcp_nodelay:1;
102 unsigned short int port; 103 unsigned short int port;
103 char *prepath; 104 char *prepath;
104}; 105};
@@ -1142,9 +1143,11 @@ cifs_parse_mount_options(char *options, const char *devname,
1142 simple_strtoul(value, &value, 0); 1143 simple_strtoul(value, &value, 0);
1143 } 1144 }
1144 } else if (strnicmp(data, "sockopt", 5) == 0) { 1145 } else if (strnicmp(data, "sockopt", 5) == 0) {
1145 if (value && *value) { 1146 if (!value || !*value) {
1146 vol->sockopt = 1147 cERROR(1, ("no socket option specified"));
1147 simple_strtoul(value, &value, 0); 1148 continue;
1149 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
1150 vol->sockopt_tcp_nodelay = 1;
1148 } 1151 }
1149 } else if (strnicmp(data, "netbiosname", 4) == 0) { 1152 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1150 if (!value || !*value || (*value == ' ')) { 1153 if (!value || !*value || (*value == ' ')) {
@@ -1514,6 +1517,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1514 1517
1515 tcp_ses->noblocksnd = volume_info->noblocksnd; 1518 tcp_ses->noblocksnd = volume_info->noblocksnd;
1516 tcp_ses->noautotune = volume_info->noautotune; 1519 tcp_ses->noautotune = volume_info->noautotune;
1520 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
1517 atomic_set(&tcp_ses->inFlight, 0); 1521 atomic_set(&tcp_ses->inFlight, 0);
1518 init_waitqueue_head(&tcp_ses->response_q); 1522 init_waitqueue_head(&tcp_ses->response_q);
1519 init_waitqueue_head(&tcp_ses->request_q); 1523 init_waitqueue_head(&tcp_ses->request_q);
@@ -1764,6 +1768,7 @@ static int
1764ipv4_connect(struct TCP_Server_Info *server) 1768ipv4_connect(struct TCP_Server_Info *server)
1765{ 1769{
1766 int rc = 0; 1770 int rc = 0;
1771 int val;
1767 bool connected = false; 1772 bool connected = false;
1768 __be16 orig_port = 0; 1773 __be16 orig_port = 0;
1769 struct socket *socket = server->ssocket; 1774 struct socket *socket = server->ssocket;
@@ -1845,6 +1850,14 @@ ipv4_connect(struct TCP_Server_Info *server)
1845 socket->sk->sk_rcvbuf = 140 * 1024; 1850 socket->sk->sk_rcvbuf = 140 * 1024;
1846 } 1851 }
1847 1852
1853 if (server->tcp_nodelay) {
1854 val = 1;
1855 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
1856 (char *)&val, sizeof(val));
1857 if (rc)
1858 cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
1859 }
1860
1848 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx", 1861 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1849 socket->sk->sk_sndbuf, 1862 socket->sk->sk_sndbuf,
1850 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo)); 1863 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
@@ -1916,6 +1929,7 @@ static int
1916ipv6_connect(struct TCP_Server_Info *server) 1929ipv6_connect(struct TCP_Server_Info *server)
1917{ 1930{
1918 int rc = 0; 1931 int rc = 0;
1932 int val;
1919 bool connected = false; 1933 bool connected = false;
1920 __be16 orig_port = 0; 1934 __be16 orig_port = 0;
1921 struct socket *socket = server->ssocket; 1935 struct socket *socket = server->ssocket;
@@ -1987,6 +2001,15 @@ ipv6_connect(struct TCP_Server_Info *server)
1987 */ 2001 */
1988 socket->sk->sk_rcvtimeo = 7 * HZ; 2002 socket->sk->sk_rcvtimeo = 7 * HZ;
1989 socket->sk->sk_sndtimeo = 5 * HZ; 2003 socket->sk->sk_sndtimeo = 5 * HZ;
2004
2005 if (server->tcp_nodelay) {
2006 val = 1;
2007 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2008 (char *)&val, sizeof(val));
2009 if (rc)
2010 cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
2011 }
2012
1990 server->ssocket = socket; 2013 server->ssocket = socket;
1991 2014
1992 return rc; 2015 return rc;
@@ -2287,12 +2310,12 @@ int
2287cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, 2310cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2288 char *mount_data_global, const char *devname) 2311 char *mount_data_global, const char *devname)
2289{ 2312{
2290 int rc = 0; 2313 int rc;
2291 int xid; 2314 int xid;
2292 struct smb_vol *volume_info; 2315 struct smb_vol *volume_info;
2293 struct cifsSesInfo *pSesInfo = NULL; 2316 struct cifsSesInfo *pSesInfo;
2294 struct cifsTconInfo *tcon = NULL; 2317 struct cifsTconInfo *tcon;
2295 struct TCP_Server_Info *srvTcp = NULL; 2318 struct TCP_Server_Info *srvTcp;
2296 char *full_path; 2319 char *full_path;
2297 char *mount_data = mount_data_global; 2320 char *mount_data = mount_data_global;
2298#ifdef CONFIG_CIFS_DFS_UPCALL 2321#ifdef CONFIG_CIFS_DFS_UPCALL
@@ -2301,6 +2324,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2301 int referral_walks_count = 0; 2324 int referral_walks_count = 0;
2302try_mount_again: 2325try_mount_again:
2303#endif 2326#endif
2327 rc = 0;
2328 tcon = NULL;
2329 pSesInfo = NULL;
2330 srvTcp = NULL;
2304 full_path = NULL; 2331 full_path = NULL;
2305 2332
2306 xid = GetXid(); 2333 xid = GetXid();
@@ -2362,13 +2389,13 @@ try_mount_again:
2362 */ 2389 */
2363 cifs_put_tcp_session(srvTcp); 2390 cifs_put_tcp_session(srvTcp);
2364 2391
2365 down(&pSesInfo->sesSem); 2392 mutex_lock(&pSesInfo->session_mutex);
2366 if (pSesInfo->need_reconnect) { 2393 if (pSesInfo->need_reconnect) {
2367 cFYI(1, ("Session needs reconnect")); 2394 cFYI(1, ("Session needs reconnect"));
2368 rc = cifs_setup_session(xid, pSesInfo, 2395 rc = cifs_setup_session(xid, pSesInfo,
2369 cifs_sb->local_nls); 2396 cifs_sb->local_nls);
2370 } 2397 }
2371 up(&pSesInfo->sesSem); 2398 mutex_unlock(&pSesInfo->session_mutex);
2372 } else if (!rc) { 2399 } else if (!rc) {
2373 cFYI(1, ("Existing smb sess not found")); 2400 cFYI(1, ("Existing smb sess not found"));
2374 pSesInfo = sesInfoAlloc(); 2401 pSesInfo = sesInfoAlloc();
@@ -2411,12 +2438,12 @@ try_mount_again:
2411 } 2438 }
2412 pSesInfo->linux_uid = volume_info->linux_uid; 2439 pSesInfo->linux_uid = volume_info->linux_uid;
2413 pSesInfo->overrideSecFlg = volume_info->secFlg; 2440 pSesInfo->overrideSecFlg = volume_info->secFlg;
2414 down(&pSesInfo->sesSem); 2441 mutex_lock(&pSesInfo->session_mutex);
2415 2442
2416 /* BB FIXME need to pass vol->secFlgs BB */ 2443 /* BB FIXME need to pass vol->secFlgs BB */
2417 rc = cifs_setup_session(xid, pSesInfo, 2444 rc = cifs_setup_session(xid, pSesInfo,
2418 cifs_sb->local_nls); 2445 cifs_sb->local_nls);
2419 up(&pSesInfo->sesSem); 2446 mutex_unlock(&pSesInfo->session_mutex);
2420 } 2447 }
2421 2448
2422 /* search for existing tcon to this server share */ 2449 /* search for existing tcon to this server share */
@@ -2597,6 +2624,7 @@ remote_path_check:
2597 2624
2598 cleanup_volume_info(&volume_info); 2625 cleanup_volume_info(&volume_info);
2599 referral_walks_count++; 2626 referral_walks_count++;
2627 FreeXid(xid);
2600 goto try_mount_again; 2628 goto try_mount_again;
2601 } 2629 }
2602#else /* No DFS support, return error on mount */ 2630#else /* No DFS support, return error on mount */