diff options
author | Jeff Layton <jlayton@redhat.com> | 2012-11-26 11:09:55 -0500 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-12-05 14:27:30 -0500 |
commit | b979aaa1777259330435c47f900833dabe9189e8 (patch) | |
tree | 45db63a100144fd74e5997ab329f855bed520ed1 /fs | |
parent | ccb5c001b3035ca470fe21424e439530ba838510 (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.h | 3 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 4 | ||||
-rw-r--r-- | fs/cifs/connect.c | 91 | ||||
-rw-r--r-- | fs/cifs/netmisc.c | 14 |
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); | |||
110 | extern int decode_negTokenInit(unsigned char *security_blob, int length, | 110 | extern int decode_negTokenInit(unsigned char *security_blob, int length, |
111 | struct TCP_Server_Info *server); | 111 | struct TCP_Server_Info *server); |
112 | extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); | 112 | extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); |
113 | extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); | 113 | extern void cifs_set_port(struct sockaddr *addr, const unsigned short int port); |
114 | extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, | ||
115 | const unsigned short int port); | ||
116 | extern int map_smb_to_linux_error(char *buf, bool logErr); | 114 | extern int map_smb_to_linux_error(char *buf, bool logErr); |
117 | extern void header_assemble(struct smb_hdr *, char /* command */ , | 115 | extern 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 * | |||
2062 | cifs_get_tcp_session(struct smb_vol *volume_info) | 2071 | cifs_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 | ||
207 | int | 207 | void |
208 | cifs_set_port(struct sockaddr *addr, const unsigned short int port) | 208 | cifs_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 | |||
223 | int | ||
224 | cifs_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 | /***************************************************************************** |