diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index cd54fee3f05c..2df8e6d0fb08 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -92,6 +92,8 @@ struct smb_vol { | |||
92 | bool seal:1; /* request transport encryption on share */ | 92 | bool seal:1; /* request transport encryption on share */ |
93 | bool nodfs:1; /* Do not request DFS, even if available */ | 93 | bool nodfs:1; /* Do not request DFS, even if available */ |
94 | bool local_lease:1; /* check leases only on local system, not remote */ | 94 | bool local_lease:1; /* check leases only on local system, not remote */ |
95 | bool noblocksnd:1; | ||
96 | bool noautotune:1; | ||
95 | unsigned int rsize; | 97 | unsigned int rsize; |
96 | unsigned int wsize; | 98 | unsigned int wsize; |
97 | unsigned int sockopt; | 99 | unsigned int sockopt; |
@@ -102,9 +104,11 @@ struct smb_vol { | |||
102 | static int ipv4_connect(struct sockaddr_in *psin_server, | 104 | static int ipv4_connect(struct sockaddr_in *psin_server, |
103 | struct socket **csocket, | 105 | struct socket **csocket, |
104 | char *netb_name, | 106 | char *netb_name, |
105 | char *server_netb_name); | 107 | char *server_netb_name, |
108 | bool noblocksnd, | ||
109 | bool nosndbuf); /* ipv6 never set sndbuf size */ | ||
106 | static int ipv6_connect(struct sockaddr_in6 *psin_server, | 110 | static int ipv6_connect(struct sockaddr_in6 *psin_server, |
107 | struct socket **csocket); | 111 | struct socket **csocket, bool noblocksnd); |
108 | 112 | ||
109 | 113 | ||
110 | /* | 114 | /* |
@@ -191,12 +195,13 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
191 | try_to_freeze(); | 195 | try_to_freeze(); |
192 | if (server->protocolType == IPV6) { | 196 | if (server->protocolType == IPV6) { |
193 | rc = ipv6_connect(&server->addr.sockAddr6, | 197 | rc = ipv6_connect(&server->addr.sockAddr6, |
194 | &server->ssocket); | 198 | &server->ssocket, server->noautotune); |
195 | } else { | 199 | } else { |
196 | rc = ipv4_connect(&server->addr.sockAddr, | 200 | rc = ipv4_connect(&server->addr.sockAddr, |
197 | &server->ssocket, | 201 | &server->ssocket, |
198 | server->workstation_RFC1001_name, | 202 | server->workstation_RFC1001_name, |
199 | server->server_RFC1001_name); | 203 | server->server_RFC1001_name, |
204 | server->noblocksnd, server->noautotune); | ||
200 | } | 205 | } |
201 | if (rc) { | 206 | if (rc) { |
202 | cFYI(1, ("reconnect error %d", rc)); | 207 | cFYI(1, ("reconnect error %d", rc)); |
@@ -1192,6 +1197,10 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1192 | /* ignore */ | 1197 | /* ignore */ |
1193 | } else if (strnicmp(data, "rw", 2) == 0) { | 1198 | } else if (strnicmp(data, "rw", 2) == 0) { |
1194 | vol->rw = true; | 1199 | vol->rw = true; |
1200 | } else if (strnicmp(data, "noblocksend", 11) == 0) { | ||
1201 | vol->noblocksnd = 1; | ||
1202 | } else if (strnicmp(data, "noautotune", 10) == 0) { | ||
1203 | vol->noautotune = 1; | ||
1195 | } else if ((strnicmp(data, "suid", 4) == 0) || | 1204 | } else if ((strnicmp(data, "suid", 4) == 0) || |
1196 | (strnicmp(data, "nosuid", 6) == 0) || | 1205 | (strnicmp(data, "nosuid", 6) == 0) || |
1197 | (strnicmp(data, "exec", 4) == 0) || | 1206 | (strnicmp(data, "exec", 4) == 0) || |
@@ -1518,7 +1527,8 @@ static void rfc1002mangle(char *target, char *source, unsigned int length) | |||
1518 | 1527 | ||
1519 | static int | 1528 | static int |
1520 | ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | 1529 | ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, |
1521 | char *netbios_name, char *target_name) | 1530 | char *netbios_name, char *target_name, |
1531 | bool noblocksnd, bool noautotune) | ||
1522 | { | 1532 | { |
1523 | int rc = 0; | 1533 | int rc = 0; |
1524 | int connected = 0; | 1534 | int connected = 0; |
@@ -1590,11 +1600,16 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1590 | (*csocket)->sk->sk_sndbuf, | 1600 | (*csocket)->sk->sk_sndbuf, |
1591 | (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo)); | 1601 | (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo)); |
1592 | (*csocket)->sk->sk_rcvtimeo = 7 * HZ; | 1602 | (*csocket)->sk->sk_rcvtimeo = 7 * HZ; |
1603 | if (!noblocksnd) | ||
1604 | (*csocket)->sk->sk_sndtimeo = 3 * HZ; | ||
1605 | |||
1593 | /* make the bufsizes depend on wsize/rsize and max requests */ | 1606 | /* make the bufsizes depend on wsize/rsize and max requests */ |
1594 | if ((*csocket)->sk->sk_sndbuf < (200 * 1024)) | 1607 | if (noautotune) { |
1595 | (*csocket)->sk->sk_sndbuf = 200 * 1024; | 1608 | if ((*csocket)->sk->sk_sndbuf < (200 * 1024)) |
1596 | if ((*csocket)->sk->sk_rcvbuf < (140 * 1024)) | 1609 | (*csocket)->sk->sk_sndbuf = 200 * 1024; |
1597 | (*csocket)->sk->sk_rcvbuf = 140 * 1024; | 1610 | if ((*csocket)->sk->sk_rcvbuf < (140 * 1024)) |
1611 | (*csocket)->sk->sk_rcvbuf = 140 * 1024; | ||
1612 | } | ||
1598 | 1613 | ||
1599 | /* send RFC1001 sessinit */ | 1614 | /* send RFC1001 sessinit */ |
1600 | if (psin_server->sin_port == htons(RFC1001_PORT)) { | 1615 | if (psin_server->sin_port == htons(RFC1001_PORT)) { |
@@ -1631,7 +1646,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1631 | /* sizeof RFC1002_SESSION_REQUEST with no scope */ | 1646 | /* sizeof RFC1002_SESSION_REQUEST with no scope */ |
1632 | smb_buf->smb_buf_length = 0x81000044; | 1647 | smb_buf->smb_buf_length = 0x81000044; |
1633 | rc = smb_send(*csocket, smb_buf, 0x44, | 1648 | rc = smb_send(*csocket, smb_buf, 0x44, |
1634 | (struct sockaddr *)psin_server); | 1649 | (struct sockaddr *)psin_server, noblocksnd); |
1635 | kfree(ses_init_buf); | 1650 | kfree(ses_init_buf); |
1636 | msleep(1); /* RFC1001 layer in at least one server | 1651 | msleep(1); /* RFC1001 layer in at least one server |
1637 | requires very short break before negprot | 1652 | requires very short break before negprot |
@@ -1651,7 +1666,8 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1651 | } | 1666 | } |
1652 | 1667 | ||
1653 | static int | 1668 | static int |
1654 | ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) | 1669 | ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket, |
1670 | bool noblocksnd) | ||
1655 | { | 1671 | { |
1656 | int rc = 0; | 1672 | int rc = 0; |
1657 | int connected = 0; | 1673 | int connected = 0; |
@@ -1720,6 +1736,9 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) | |||
1720 | the default. sock_setsockopt not used because it expects | 1736 | the default. sock_setsockopt not used because it expects |
1721 | user space buffer */ | 1737 | user space buffer */ |
1722 | (*csocket)->sk->sk_rcvtimeo = 7 * HZ; | 1738 | (*csocket)->sk->sk_rcvtimeo = 7 * HZ; |
1739 | if (!noblocksnd) | ||
1740 | (*csocket)->sk->sk_sndtimeo = 3 * HZ; | ||
1741 | |||
1723 | 1742 | ||
1724 | return rc; | 1743 | return rc; |
1725 | } | 1744 | } |
@@ -1983,11 +2002,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1983 | cFYI(1, ("attempting ipv6 connect")); | 2002 | cFYI(1, ("attempting ipv6 connect")); |
1984 | /* BB should we allow ipv6 on port 139? */ | 2003 | /* BB should we allow ipv6 on port 139? */ |
1985 | /* other OS never observed in Wild doing 139 with v6 */ | 2004 | /* other OS never observed in Wild doing 139 with v6 */ |
1986 | rc = ipv6_connect(&sin_server6, &csocket); | 2005 | rc = ipv6_connect(&sin_server6, &csocket, |
2006 | volume_info.noblocksnd); | ||
1987 | } else | 2007 | } else |
1988 | rc = ipv4_connect(&sin_server, &csocket, | 2008 | rc = ipv4_connect(&sin_server, &csocket, |
1989 | volume_info.source_rfc1001_name, | 2009 | volume_info.source_rfc1001_name, |
1990 | volume_info.target_rfc1001_name); | 2010 | volume_info.target_rfc1001_name, |
2011 | volume_info.noblocksnd, | ||
2012 | volume_info.noautotune); | ||
1991 | if (rc < 0) { | 2013 | if (rc < 0) { |
1992 | cERROR(1, ("Error connecting to IPv4 socket. " | 2014 | cERROR(1, ("Error connecting to IPv4 socket. " |
1993 | "Aborting operation")); | 2015 | "Aborting operation")); |
@@ -2002,6 +2024,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2002 | sock_release(csocket); | 2024 | sock_release(csocket); |
2003 | goto out; | 2025 | goto out; |
2004 | } else { | 2026 | } else { |
2027 | srvTcp->noblocksnd = volume_info.noblocksnd; | ||
2028 | srvTcp->noautotune = volume_info.noautotune; | ||
2005 | memcpy(&srvTcp->addr.sockAddr, &sin_server, | 2029 | memcpy(&srvTcp->addr.sockAddr, &sin_server, |
2006 | sizeof(struct sockaddr_in)); | 2030 | sizeof(struct sockaddr_in)); |
2007 | atomic_set(&srvTcp->inFlight, 0); | 2031 | atomic_set(&srvTcp->inFlight, 0); |