aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/connect.c146
1 files changed, 69 insertions, 77 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c2ed0f57a66c..a36f4bd5a764 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -101,12 +101,7 @@ struct smb_vol {
101 char *prepath; 101 char *prepath;
102}; 102};
103 103
104static int ipv4_connect(struct sockaddr_in *psin_server, 104static int ipv4_connect(struct TCP_Server_Info *server);
105 struct socket **csocket,
106 char *netb_name,
107 char *server_netb_name,
108 bool noblocksnd,
109 bool nosndbuf); /* ipv6 never set sndbuf size */
110static int ipv6_connect(struct sockaddr_in6 *psin_server, 105static int ipv6_connect(struct sockaddr_in6 *psin_server,
111 struct socket **csocket, bool noblocksnd); 106 struct socket **csocket, bool noblocksnd);
112 107
@@ -187,16 +182,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
187 while ((server->tcpStatus != CifsExiting) && 182 while ((server->tcpStatus != CifsExiting) &&
188 (server->tcpStatus != CifsGood)) { 183 (server->tcpStatus != CifsGood)) {
189 try_to_freeze(); 184 try_to_freeze();
190 if (server->addr.sockAddr6.sin6_family == AF_INET6) { 185 if (server->addr.sockAddr6.sin6_family == AF_INET6)
191 rc = ipv6_connect(&server->addr.sockAddr6, 186 rc = ipv6_connect(&server->addr.sockAddr6,
192 &server->ssocket, server->noautotune); 187 &server->ssocket, server->noautotune);
193 } else { 188 else
194 rc = ipv4_connect(&server->addr.sockAddr, 189 rc = ipv4_connect(server);
195 &server->ssocket,
196 server->workstation_RFC1001_name,
197 server->server_RFC1001_name,
198 server->noblocksnd, server->noautotune);
199 }
200 if (rc) { 190 if (rc) {
201 cFYI(1, ("reconnect error %d", rc)); 191 cFYI(1, ("reconnect error %d", rc));
202 msleep(3000); 192 msleep(3000);
@@ -1517,11 +1507,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1517 memcpy(&tcp_ses->addr.sockAddr, sin_server, 1507 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1518 sizeof(struct sockaddr_in)); 1508 sizeof(struct sockaddr_in));
1519 sin_server->sin_port = htons(volume_info->port); 1509 sin_server->sin_port = htons(volume_info->port);
1520 rc = ipv4_connect(sin_server, &tcp_ses->ssocket, 1510 rc = ipv4_connect(tcp_ses);
1521 volume_info->source_rfc1001_name,
1522 volume_info->target_rfc1001_name,
1523 volume_info->noblocksnd,
1524 volume_info->noautotune);
1525 } 1511 }
1526 if (rc < 0) { 1512 if (rc < 0) {
1527 cERROR(1, ("Error connecting to socket. Aborting operation")); 1513 cERROR(1, ("Error connecting to socket. Aborting operation"));
@@ -1735,93 +1721,96 @@ static void rfc1002mangle(char *target, char *source, unsigned int length)
1735 1721
1736 1722
1737static int 1723static int
1738ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 1724ipv4_connect(struct TCP_Server_Info *server)
1739 char *netbios_name, char *target_name,
1740 bool noblocksnd, bool noautotune)
1741{ 1725{
1742 int rc = 0; 1726 int rc = 0;
1743 int connected = 0; 1727 bool connected = false;
1744 __be16 orig_port = 0; 1728 __be16 orig_port = 0;
1729 struct socket *socket = server->ssocket;
1745 1730
1746 if (*csocket == NULL) { 1731 if (socket == NULL) {
1747 rc = sock_create_kern(PF_INET, SOCK_STREAM, 1732 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1748 IPPROTO_TCP, csocket); 1733 IPPROTO_TCP, &socket);
1749 if (rc < 0) { 1734 if (rc < 0) {
1750 cERROR(1, ("Error %d creating socket", rc)); 1735 cERROR(1, ("Error %d creating socket", rc));
1751 *csocket = NULL;
1752 return rc; 1736 return rc;
1753 } else {
1754 /* BB other socket options to set KEEPALIVE, NODELAY? */
1755 cFYI(1, ("Socket created"));
1756 (*csocket)->sk->sk_allocation = GFP_NOFS;
1757 cifs_reclassify_socket4(*csocket);
1758 } 1737 }
1738
1739 /* BB other socket options to set KEEPALIVE, NODELAY? */
1740 cFYI(1, ("Socket created"));
1741 server->ssocket = socket;
1742 socket->sk->sk_allocation = GFP_NOFS;
1743 cifs_reclassify_socket4(socket);
1759 } 1744 }
1760 1745
1761 psin_server->sin_family = AF_INET; 1746 /* user overrode default port */
1762 if (psin_server->sin_port) { /* user overrode default port */ 1747 if (server->addr.sockAddr.sin_port) {
1763 rc = (*csocket)->ops->connect(*csocket, 1748 rc = socket->ops->connect(socket, (struct sockaddr *)
1764 (struct sockaddr *) psin_server, 1749 &server->addr.sockAddr,
1765 sizeof(struct sockaddr_in), 0); 1750 sizeof(struct sockaddr_in), 0);
1766 if (rc >= 0) 1751 if (rc >= 0)
1767 connected = 1; 1752 connected = true;
1768 } 1753 }
1769 1754
1770 if (!connected) { 1755 if (!connected) {
1771 /* save original port so we can retry user specified port 1756 /* save original port so we can retry user specified port
1772 later if fall back ports fail this time */ 1757 later if fall back ports fail this time */
1773 orig_port = psin_server->sin_port; 1758 orig_port = server->addr.sockAddr.sin_port;
1774 1759
1775 /* do not retry on the same port we just failed on */ 1760 /* do not retry on the same port we just failed on */
1776 if (psin_server->sin_port != htons(CIFS_PORT)) { 1761 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
1777 psin_server->sin_port = htons(CIFS_PORT); 1762 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
1778 1763 rc = socket->ops->connect(socket,
1779 rc = (*csocket)->ops->connect(*csocket, 1764 (struct sockaddr *)
1780 (struct sockaddr *) psin_server, 1765 &server->addr.sockAddr,
1781 sizeof(struct sockaddr_in), 0); 1766 sizeof(struct sockaddr_in), 0);
1782 if (rc >= 0) 1767 if (rc >= 0)
1783 connected = 1; 1768 connected = true;
1784 } 1769 }
1785 } 1770 }
1786 if (!connected) { 1771 if (!connected) {
1787 psin_server->sin_port = htons(RFC1001_PORT); 1772 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
1788 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) 1773 rc = socket->ops->connect(socket, (struct sockaddr *)
1789 psin_server, 1774 &server->addr.sockAddr,
1790 sizeof(struct sockaddr_in), 0); 1775 sizeof(struct sockaddr_in), 0);
1791 if (rc >= 0) 1776 if (rc >= 0)
1792 connected = 1; 1777 connected = true;
1793 } 1778 }
1794 1779
1795 /* give up here - unless we want to retry on different 1780 /* give up here - unless we want to retry on different
1796 protocol families some day */ 1781 protocol families some day */
1797 if (!connected) { 1782 if (!connected) {
1798 if (orig_port) 1783 if (orig_port)
1799 psin_server->sin_port = orig_port; 1784 server->addr.sockAddr.sin_port = orig_port;
1800 cFYI(1, ("Error %d connecting to server via ipv4", rc)); 1785 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1801 sock_release(*csocket); 1786 sock_release(socket);
1802 *csocket = NULL; 1787 server->ssocket = NULL;
1803 return rc; 1788 return rc;
1804 } 1789 }
1805 /* Eventually check for other socket options to change from 1790
1806 the default. sock_setsockopt not used because it expects 1791
1807 user space buffer */ 1792 /*
1808 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx", 1793 * Eventually check for other socket options to change from
1809 (*csocket)->sk->sk_sndbuf, 1794 * the default. sock_setsockopt not used because it expects
1810 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo)); 1795 * user space buffer
1811 (*csocket)->sk->sk_rcvtimeo = 7 * HZ; 1796 */
1812 if (!noblocksnd) 1797 socket->sk->sk_rcvtimeo = 7 * HZ;
1813 (*csocket)->sk->sk_sndtimeo = 3 * HZ; 1798 socket->sk->sk_sndtimeo = 3 * HZ;
1814 1799
1815 /* make the bufsizes depend on wsize/rsize and max requests */ 1800 /* make the bufsizes depend on wsize/rsize and max requests */
1816 if (noautotune) { 1801 if (server->noautotune) {
1817 if ((*csocket)->sk->sk_sndbuf < (200 * 1024)) 1802 if (socket->sk->sk_sndbuf < (200 * 1024))
1818 (*csocket)->sk->sk_sndbuf = 200 * 1024; 1803 socket->sk->sk_sndbuf = 200 * 1024;
1819 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024)) 1804 if (socket->sk->sk_rcvbuf < (140 * 1024))
1820 (*csocket)->sk->sk_rcvbuf = 140 * 1024; 1805 socket->sk->sk_rcvbuf = 140 * 1024;
1821 } 1806 }
1822 1807
1808 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1809 socket->sk->sk_sndbuf,
1810 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
1811
1823 /* send RFC1001 sessinit */ 1812 /* send RFC1001 sessinit */
1824 if (psin_server->sin_port == htons(RFC1001_PORT)) { 1813 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
1825 /* some servers require RFC1001 sessinit before sending 1814 /* some servers require RFC1001 sessinit before sending
1826 negprot - BB check reconnection in case where second 1815 negprot - BB check reconnection in case where second
1827 sessinit is sent but no second negprot */ 1816 sessinit is sent but no second negprot */
@@ -1831,39 +1820,42 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1831 GFP_KERNEL); 1820 GFP_KERNEL);
1832 if (ses_init_buf) { 1821 if (ses_init_buf) {
1833 ses_init_buf->trailer.session_req.called_len = 32; 1822 ses_init_buf->trailer.session_req.called_len = 32;
1834 if (target_name && (target_name[0] != 0)) { 1823 if (server->server_RFC1001_name &&
1824 server->server_RFC1001_name[0] != 0)
1835 rfc1002mangle(ses_init_buf->trailer. 1825 rfc1002mangle(ses_init_buf->trailer.
1836 session_req.called_name, 1826 session_req.called_name,
1837 target_name, 1827 server->server_RFC1001_name,
1838 RFC1001_NAME_LEN_WITH_NULL); 1828 RFC1001_NAME_LEN_WITH_NULL);
1839 } else { 1829 else
1840 rfc1002mangle(ses_init_buf->trailer. 1830 rfc1002mangle(ses_init_buf->trailer.
1841 session_req.called_name, 1831 session_req.called_name,
1842 DEFAULT_CIFS_CALLED_NAME, 1832 DEFAULT_CIFS_CALLED_NAME,
1843 RFC1001_NAME_LEN_WITH_NULL); 1833 RFC1001_NAME_LEN_WITH_NULL);
1844 }
1845 1834
1846 ses_init_buf->trailer.session_req.calling_len = 32; 1835 ses_init_buf->trailer.session_req.calling_len = 32;
1836
1847 /* calling name ends in null (byte 16) from old smb 1837 /* calling name ends in null (byte 16) from old smb
1848 convention. */ 1838 convention. */
1849 if (netbios_name && (netbios_name[0] != 0)) { 1839 if (server->workstation_RFC1001_name &&
1840 server->workstation_RFC1001_name[0] != 0)
1850 rfc1002mangle(ses_init_buf->trailer. 1841 rfc1002mangle(ses_init_buf->trailer.
1851 session_req.calling_name, 1842 session_req.calling_name,
1852 netbios_name, 1843 server->workstation_RFC1001_name,
1853 RFC1001_NAME_LEN_WITH_NULL); 1844 RFC1001_NAME_LEN_WITH_NULL);
1854 } else { 1845 else
1855 rfc1002mangle(ses_init_buf->trailer. 1846 rfc1002mangle(ses_init_buf->trailer.
1856 session_req.calling_name, 1847 session_req.calling_name,
1857 "LINUX_CIFS_CLNT", 1848 "LINUX_CIFS_CLNT",
1858 RFC1001_NAME_LEN_WITH_NULL); 1849 RFC1001_NAME_LEN_WITH_NULL);
1859 } 1850
1860 ses_init_buf->trailer.session_req.scope1 = 0; 1851 ses_init_buf->trailer.session_req.scope1 = 0;
1861 ses_init_buf->trailer.session_req.scope2 = 0; 1852 ses_init_buf->trailer.session_req.scope2 = 0;
1862 smb_buf = (struct smb_hdr *)ses_init_buf; 1853 smb_buf = (struct smb_hdr *)ses_init_buf;
1863 /* sizeof RFC1002_SESSION_REQUEST with no scope */ 1854 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1864 smb_buf->smb_buf_length = 0x81000044; 1855 smb_buf->smb_buf_length = 0x81000044;
1865 rc = smb_send(*csocket, smb_buf, 0x44, 1856 rc = smb_send(socket, smb_buf, 0x44,
1866 (struct sockaddr *)psin_server, noblocksnd); 1857 (struct sockaddr *) &server->addr.sockAddr,
1858 server->noblocksnd);
1867 kfree(ses_init_buf); 1859 kfree(ses_init_buf);
1868 msleep(1); /* RFC1001 layer in at least one server 1860 msleep(1); /* RFC1001 layer in at least one server
1869 requires very short break before negprot 1861 requires very short break before negprot