diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 61 |
1 files changed, 37 insertions, 24 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 1f3345d7fa79..63ea83ff687f 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1377,7 +1377,7 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1377 | } | 1377 | } |
1378 | 1378 | ||
1379 | static struct TCP_Server_Info * | 1379 | static struct TCP_Server_Info * |
1380 | cifs_find_tcp_session(struct sockaddr_storage *addr) | 1380 | cifs_find_tcp_session(struct sockaddr_storage *addr, unsigned short int port) |
1381 | { | 1381 | { |
1382 | struct list_head *tmp; | 1382 | struct list_head *tmp; |
1383 | struct TCP_Server_Info *server; | 1383 | struct TCP_Server_Info *server; |
@@ -1397,16 +1397,37 @@ cifs_find_tcp_session(struct sockaddr_storage *addr) | |||
1397 | if (server->tcpStatus == CifsNew) | 1397 | if (server->tcpStatus == CifsNew) |
1398 | continue; | 1398 | continue; |
1399 | 1399 | ||
1400 | if (addr->ss_family == AF_INET && | 1400 | switch (addr->ss_family) { |
1401 | (addr4->sin_addr.s_addr != | 1401 | case AF_INET: |
1402 | server->addr.sockAddr.sin_addr.s_addr)) | 1402 | if (addr4->sin_addr.s_addr == |
1403 | continue; | 1403 | server->addr.sockAddr.sin_addr.s_addr) { |
1404 | else if (addr->ss_family == AF_INET6 && | 1404 | addr4->sin_port = htons(port); |
1405 | (!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr, | 1405 | /* user overrode default port? */ |
1406 | &addr6->sin6_addr) || | 1406 | if (addr4->sin_port) { |
1407 | server->addr.sockAddr6.sin6_scope_id != | 1407 | if (addr4->sin_port != |
1408 | addr6->sin6_scope_id)) | 1408 | server->addr.sockAddr.sin_port) |
1409 | continue; | 1409 | continue; |
1410 | } | ||
1411 | break; | ||
1412 | } else | ||
1413 | continue; | ||
1414 | |||
1415 | case AF_INET6: | ||
1416 | if (ipv6_addr_equal(&addr6->sin6_addr, | ||
1417 | &server->addr.sockAddr6.sin6_addr) && | ||
1418 | (addr6->sin6_scope_id == | ||
1419 | server->addr.sockAddr6.sin6_scope_id)) { | ||
1420 | addr6->sin6_port = htons(port); | ||
1421 | /* user overrode default port? */ | ||
1422 | if (addr6->sin6_port) { | ||
1423 | if (addr6->sin6_port != | ||
1424 | server->addr.sockAddr6.sin6_port) | ||
1425 | continue; | ||
1426 | } | ||
1427 | break; | ||
1428 | } else | ||
1429 | continue; | ||
1430 | } | ||
1410 | 1431 | ||
1411 | ++server->srv_count; | 1432 | ++server->srv_count; |
1412 | write_unlock(&cifs_tcp_ses_lock); | 1433 | write_unlock(&cifs_tcp_ses_lock); |
@@ -1475,7 +1496,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
1475 | } | 1496 | } |
1476 | 1497 | ||
1477 | /* see if we already have a matching tcp_ses */ | 1498 | /* see if we already have a matching tcp_ses */ |
1478 | tcp_ses = cifs_find_tcp_session(&addr); | 1499 | tcp_ses = cifs_find_tcp_session(&addr, volume_info->port); |
1479 | if (tcp_ses) | 1500 | if (tcp_ses) |
1480 | return tcp_ses; | 1501 | return tcp_ses; |
1481 | 1502 | ||
@@ -1556,7 +1577,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
1556 | 1577 | ||
1557 | out_err: | 1578 | out_err: |
1558 | if (tcp_ses) { | 1579 | if (tcp_ses) { |
1559 | kfree(tcp_ses->hostname); | 1580 | if (!IS_ERR(tcp_ses->hostname)) |
1581 | kfree(tcp_ses->hostname); | ||
1560 | if (tcp_ses->ssocket) | 1582 | if (tcp_ses->ssocket) |
1561 | sock_release(tcp_ses->ssocket); | 1583 | sock_release(tcp_ses->ssocket); |
1562 | kfree(tcp_ses); | 1584 | kfree(tcp_ses); |
@@ -1649,7 +1671,6 @@ cifs_put_tcon(struct cifsTconInfo *tcon) | |||
1649 | CIFSSMBTDis(xid, tcon); | 1671 | CIFSSMBTDis(xid, tcon); |
1650 | _FreeXid(xid); | 1672 | _FreeXid(xid); |
1651 | 1673 | ||
1652 | DeleteTconOplockQEntries(tcon); | ||
1653 | tconInfoFree(tcon); | 1674 | tconInfoFree(tcon); |
1654 | cifs_put_smb_ses(ses); | 1675 | cifs_put_smb_ses(ses); |
1655 | } | 1676 | } |
@@ -2199,16 +2220,8 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon, | |||
2199 | struct cifs_sb_info *cifs_sb, const char *full_path) | 2220 | struct cifs_sb_info *cifs_sb, const char *full_path) |
2200 | { | 2221 | { |
2201 | int rc; | 2222 | int rc; |
2202 | __u64 inode_num; | ||
2203 | FILE_ALL_INFO *pfile_info; | 2223 | FILE_ALL_INFO *pfile_info; |
2204 | 2224 | ||
2205 | rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num, | ||
2206 | cifs_sb->local_nls, | ||
2207 | cifs_sb->mnt_cifs_flags & | ||
2208 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
2209 | if (rc != -EOPNOTSUPP) | ||
2210 | return rc; | ||
2211 | |||
2212 | pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 2225 | pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
2213 | if (pfile_info == NULL) | 2226 | if (pfile_info == NULL) |
2214 | return -ENOMEM; | 2227 | return -ENOMEM; |
@@ -2636,9 +2649,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
2636 | return -EIO; | 2649 | return -EIO; |
2637 | 2650 | ||
2638 | smb_buffer = cifs_buf_get(); | 2651 | smb_buffer = cifs_buf_get(); |
2639 | if (smb_buffer == NULL) { | 2652 | if (smb_buffer == NULL) |
2640 | return -ENOMEM; | 2653 | return -ENOMEM; |
2641 | } | 2654 | |
2642 | smb_buffer_response = smb_buffer; | 2655 | smb_buffer_response = smb_buffer; |
2643 | 2656 | ||
2644 | header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, | 2657 | header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, |