aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-11-26 11:09:55 -0500
committerSteve French <smfrench@gmail.com>2012-12-05 14:27:30 -0500
commitb979aaa1777259330435c47f900833dabe9189e8 (patch)
tree45db63a100144fd74e5997ab329f855bed520ed1 /fs
parentccb5c001b3035ca470fe21424e439530ba838510 (diff)
cifs: get rid of smb_vol->UNCip and smb_vol->port
Passing this around as a string is contorted and painful. Instead, just convert these to a sockaddr as soon as possible, since that's how we're going to work with it later anyway. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsglob.h3
-rw-r--r--fs/cifs/cifsproto.h4
-rw-r--r--fs/cifs/connect.c91
-rw-r--r--fs/cifs/netmisc.c14
4 files changed, 36 insertions, 76 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index ac66409fb9d3..052d85b333f3 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -394,7 +394,6 @@ struct smb_vol {
394 char *password; 394 char *password;
395 char *domainname; 395 char *domainname;
396 char *UNC; 396 char *UNC;
397 char *UNCip;
398 char *iocharset; /* local code page for mapping to and from Unicode */ 397 char *iocharset; /* local code page for mapping to and from Unicode */
399 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ 398 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
400 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ 399 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
@@ -442,11 +441,11 @@ struct smb_vol {
442 unsigned int rsize; 441 unsigned int rsize;
443 unsigned int wsize; 442 unsigned int wsize;
444 bool sockopt_tcp_nodelay:1; 443 bool sockopt_tcp_nodelay:1;
445 unsigned short int port;
446 unsigned long actimeo; /* attribute cache timeout (jiffies) */ 444 unsigned long actimeo; /* attribute cache timeout (jiffies) */
447 struct smb_version_operations *ops; 445 struct smb_version_operations *ops;
448 struct smb_version_values *vals; 446 struct smb_version_values *vals;
449 char *prepath; 447 char *prepath;
448 struct sockaddr_storage dstaddr; /* destination address */
450 struct sockaddr_storage srcaddr; /* allow binding to a local IP */ 449 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
451 struct nls_table *local_nls; 450 struct nls_table *local_nls;
452}; 451};
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7494358ba533..15a8cb66a07b 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -110,9 +110,7 @@ extern unsigned int smbCalcSize(void *buf);
110extern int decode_negTokenInit(unsigned char *security_blob, int length, 110extern int decode_negTokenInit(unsigned char *security_blob, int length,
111 struct TCP_Server_Info *server); 111 struct TCP_Server_Info *server);
112extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); 112extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
113extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); 113extern void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
114extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
115 const unsigned short int port);
116extern int map_smb_to_linux_error(char *buf, bool logErr); 114extern int map_smb_to_linux_error(char *buf, bool logErr);
117extern void header_assemble(struct smb_hdr *, char /* command */ , 115extern void header_assemble(struct smb_hdr *, char /* command */ ,
118 const struct cifs_tcon *, int /* length of 116 const struct cifs_tcon *, int /* length of
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index dec7c15d886a..428d8a12b827 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1114,6 +1114,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1114 char *string = NULL; 1114 char *string = NULL;
1115 char *tmp_end, *value; 1115 char *tmp_end, *value;
1116 char delim; 1116 char delim;
1117 bool got_ip = false;
1118 unsigned short port = 0;
1119 struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr;
1117 1120
1118 separator[0] = ','; 1121 separator[0] = ',';
1119 separator[1] = 0; 1122 separator[1] = 0;
@@ -1422,12 +1425,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1422 vol->dir_mode = option; 1425 vol->dir_mode = option;
1423 break; 1426 break;
1424 case Opt_port: 1427 case Opt_port:
1425 if (get_option_ul(args, &option)) { 1428 if (get_option_ul(args, &option) ||
1426 cERROR(1, "%s: Invalid port value", 1429 option > USHRT_MAX) {
1427 __func__); 1430 cERROR(1, "%s: Invalid port value", __func__);
1428 goto cifs_parse_mount_err; 1431 goto cifs_parse_mount_err;
1429 } 1432 }
1430 vol->port = option; 1433 port = (unsigned short)option;
1431 break; 1434 break;
1432 case Opt_rsize: 1435 case Opt_rsize:
1433 if (get_option_ul(args, &option)) { 1436 if (get_option_ul(args, &option)) {
@@ -1543,25 +1546,21 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1543 vol->password[j] = '\0'; 1546 vol->password[j] = '\0';
1544 break; 1547 break;
1545 case Opt_blank_ip: 1548 case Opt_blank_ip:
1546 vol->UNCip = NULL; 1549 /* FIXME: should this be an error instead? */
1550 got_ip = false;
1547 break; 1551 break;
1548 case Opt_ip: 1552 case Opt_ip:
1549 string = match_strdup(args); 1553 string = match_strdup(args);
1550 if (string == NULL) 1554 if (string == NULL)
1551 goto out_nomem; 1555 goto out_nomem;
1552 1556
1553 if (strnlen(string, INET6_ADDRSTRLEN) > 1557 if (!cifs_convert_address(dstaddr, string,
1554 INET6_ADDRSTRLEN) { 1558 strlen(string))) {
1555 printk(KERN_WARNING "CIFS: ip address " 1559 printk(KERN_ERR "CIFS: bad ip= option (%s).\n",
1556 "too long\n"); 1560 string);
1557 goto cifs_parse_mount_err;
1558 }
1559 vol->UNCip = kstrdup(string, GFP_KERNEL);
1560 if (!vol->UNCip) {
1561 printk(KERN_WARNING "CIFS: no memory "
1562 "for UNC IP\n");
1563 goto cifs_parse_mount_err; 1561 goto cifs_parse_mount_err;
1564 } 1562 }
1563 got_ip = true;
1565 break; 1564 break;
1566 case Opt_unc: 1565 case Opt_unc:
1567 string = match_strdup(args); 1566 string = match_strdup(args);
@@ -1811,8 +1810,18 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1811 goto cifs_parse_mount_err; 1810 goto cifs_parse_mount_err;
1812 } 1811 }
1813 1812
1814 if (vol->UNCip == NULL) 1813 if (!got_ip) {
1815 vol->UNCip = &vol->UNC[2]; 1814 /* No ip= option specified? Try to get it from UNC */
1815 if (!cifs_convert_address(dstaddr, &vol->UNC[2],
1816 strlen(&vol->UNC[2]))) {
1817 printk(KERN_ERR "Unable to determine destination "
1818 "address.\n");
1819 goto cifs_parse_mount_err;
1820 }
1821 }
1822
1823 /* set the port that we got earlier */
1824 cifs_set_port(dstaddr, port);
1816 1825
1817 if (uid_specified) 1826 if (uid_specified)
1818 vol->override_uid = override_uid; 1827 vol->override_uid = override_uid;
@@ -2062,29 +2071,13 @@ static struct TCP_Server_Info *
2062cifs_get_tcp_session(struct smb_vol *volume_info) 2071cifs_get_tcp_session(struct smb_vol *volume_info)
2063{ 2072{
2064 struct TCP_Server_Info *tcp_ses = NULL; 2073 struct TCP_Server_Info *tcp_ses = NULL;
2065 struct sockaddr_storage addr; 2074 struct sockaddr *dstaddr = (struct sockaddr *)&volume_info->dstaddr;
2066 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
2067 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
2068 int rc; 2075 int rc;
2069 2076
2070 memset(&addr, 0, sizeof(struct sockaddr_storage)); 2077 cFYI(1, "UNC: %s", volume_info->UNC);
2071
2072 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
2073
2074 if (volume_info->UNCip && volume_info->UNC) {
2075 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
2076 volume_info->UNCip,
2077 strlen(volume_info->UNCip),
2078 volume_info->port);
2079 if (!rc) {
2080 /* we failed translating address */
2081 rc = -EINVAL;
2082 goto out_err;
2083 }
2084 }
2085 2078
2086 /* see if we already have a matching tcp_ses */ 2079 /* see if we already have a matching tcp_ses */
2087 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info); 2080 tcp_ses = cifs_find_tcp_session(dstaddr, volume_info);
2088 if (tcp_ses) 2081 if (tcp_ses)
2089 return tcp_ses; 2082 return tcp_ses;
2090 2083
@@ -2140,15 +2133,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2140 sizeof(tcp_ses->srcaddr)); 2133 sizeof(tcp_ses->srcaddr));
2141 ++tcp_ses->srv_count; 2134 ++tcp_ses->srv_count;
2142 2135
2143 if (addr.ss_family == AF_INET6) { 2136 memcpy(&tcp_ses->dstaddr, dstaddr, sizeof(tcp_ses->dstaddr));
2144 cFYI(1, "attempting ipv6 connect");
2145 /* BB should we allow ipv6 on port 139? */
2146 /* other OS never observed in Wild doing 139 with v6 */
2147 memcpy(&tcp_ses->dstaddr, sin_server6,
2148 sizeof(struct sockaddr_in6));
2149 } else
2150 memcpy(&tcp_ses->dstaddr, sin_server,
2151 sizeof(struct sockaddr_in));
2152 2137
2153 rc = ip_connect(tcp_ses); 2138 rc = ip_connect(tcp_ses);
2154 if (rc < 0) { 2139 if (rc < 0) {
@@ -2708,11 +2693,9 @@ cifs_match_super(struct super_block *sb, void *data)
2708 struct cifs_ses *ses; 2693 struct cifs_ses *ses;
2709 struct cifs_tcon *tcon; 2694 struct cifs_tcon *tcon;
2710 struct tcon_link *tlink; 2695 struct tcon_link *tlink;
2711 struct sockaddr_storage addr; 2696 struct sockaddr *dstaddr;
2712 int rc = 0; 2697 int rc = 0;
2713 2698
2714 memset(&addr, 0, sizeof(struct sockaddr_storage));
2715
2716 spin_lock(&cifs_tcp_ses_lock); 2699 spin_lock(&cifs_tcp_ses_lock);
2717 cifs_sb = CIFS_SB(sb); 2700 cifs_sb = CIFS_SB(sb);
2718 tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); 2701 tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
@@ -2725,15 +2708,9 @@ cifs_match_super(struct super_block *sb, void *data)
2725 tcp_srv = ses->server; 2708 tcp_srv = ses->server;
2726 2709
2727 volume_info = mnt_data->vol; 2710 volume_info = mnt_data->vol;
2711 dstaddr = (struct sockaddr *)&volume_info->dstaddr;
2728 2712
2729 rc = cifs_fill_sockaddr((struct sockaddr *)&addr, 2713 if (!match_server(tcp_srv, dstaddr, volume_info) ||
2730 volume_info->UNCip,
2731 strlen(volume_info->UNCip),
2732 volume_info->port);
2733 if (!rc)
2734 goto out;
2735
2736 if (!match_server(tcp_srv, (struct sockaddr *)&addr, volume_info) ||
2737 !match_session(ses, volume_info) || 2714 !match_session(ses, volume_info) ||
2738 !match_tcon(tcon, volume_info->UNC)) { 2715 !match_tcon(tcon, volume_info->UNC)) {
2739 rc = 0; 2716 rc = 0;
@@ -3248,8 +3225,6 @@ cleanup_volume_info_contents(struct smb_vol *volume_info)
3248{ 3225{
3249 kfree(volume_info->username); 3226 kfree(volume_info->username);
3250 kzfree(volume_info->password); 3227 kzfree(volume_info->password);
3251 if (volume_info->UNCip != volume_info->UNC + 2)
3252 kfree(volume_info->UNCip);
3253 kfree(volume_info->UNC); 3228 kfree(volume_info->UNC);
3254 kfree(volume_info->domainname); 3229 kfree(volume_info->domainname);
3255 kfree(volume_info->iocharset); 3230 kfree(volume_info->iocharset);
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index d5ce9e26696c..a82bc51fdc82 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -204,7 +204,7 @@ cifs_convert_address(struct sockaddr *dst, const char *src, int len)
204 return rc; 204 return rc;
205} 205}
206 206
207int 207void
208cifs_set_port(struct sockaddr *addr, const unsigned short int port) 208cifs_set_port(struct sockaddr *addr, const unsigned short int port)
209{ 209{
210 switch (addr->sa_family) { 210 switch (addr->sa_family) {
@@ -214,19 +214,7 @@ cifs_set_port(struct sockaddr *addr, const unsigned short int port)
214 case AF_INET6: 214 case AF_INET6:
215 ((struct sockaddr_in6 *)addr)->sin6_port = htons(port); 215 ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
216 break; 216 break;
217 default:
218 return 0;
219 } 217 }
220 return 1;
221}
222
223int
224cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
225 const unsigned short int port)
226{
227 if (!cifs_convert_address(dst, src, len))
228 return 0;
229 return cifs_set_port(dst, port);
230} 218}
231 219
232/***************************************************************************** 220/*****************************************************************************