aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c572
1 files changed, 509 insertions, 63 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 88c84a38bccb..251a17c03545 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -47,7 +47,6 @@
47#include "ntlmssp.h" 47#include "ntlmssp.h"
48#include "nterr.h" 48#include "nterr.h"
49#include "rfc1002pdu.h" 49#include "rfc1002pdu.h"
50#include "cn_cifs.h"
51#include "fscache.h" 50#include "fscache.h"
52 51
53#define CIFS_PORT 445 52#define CIFS_PORT 445
@@ -100,16 +99,25 @@ struct smb_vol {
100 bool noautotune:1; 99 bool noautotune:1;
101 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ 100 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
102 bool fsc:1; /* enable fscache */ 101 bool fsc:1; /* enable fscache */
102 bool mfsymlinks:1; /* use Minshall+French Symlinks */
103 bool multiuser:1;
103 unsigned int rsize; 104 unsigned int rsize;
104 unsigned int wsize; 105 unsigned int wsize;
105 bool sockopt_tcp_nodelay:1; 106 bool sockopt_tcp_nodelay:1;
106 unsigned short int port; 107 unsigned short int port;
107 char *prepath; 108 char *prepath;
109 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
108 struct nls_table *local_nls; 110 struct nls_table *local_nls;
109}; 111};
110 112
113/* FIXME: should these be tunable? */
114#define TLINK_ERROR_EXPIRE (1 * HZ)
115#define TLINK_IDLE_EXPIRE (600 * HZ)
116
111static int ipv4_connect(struct TCP_Server_Info *server); 117static int ipv4_connect(struct TCP_Server_Info *server);
112static int ipv6_connect(struct TCP_Server_Info *server); 118static int ipv6_connect(struct TCP_Server_Info *server);
119static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
120static void cifs_prune_tlinks(struct work_struct *work);
113 121
114/* 122/*
115 * cifs tcp session reconnection 123 * cifs tcp session reconnection
@@ -143,7 +151,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
143 151
144 /* before reconnecting the tcp session, mark the smb session (uid) 152 /* before reconnecting the tcp session, mark the smb session (uid)
145 and the tid bad so they are not used until reconnected */ 153 and the tid bad so they are not used until reconnected */
146 read_lock(&cifs_tcp_ses_lock); 154 spin_lock(&cifs_tcp_ses_lock);
147 list_for_each(tmp, &server->smb_ses_list) { 155 list_for_each(tmp, &server->smb_ses_list) {
148 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); 156 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
149 ses->need_reconnect = true; 157 ses->need_reconnect = true;
@@ -153,7 +161,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
153 tcon->need_reconnect = true; 161 tcon->need_reconnect = true;
154 } 162 }
155 } 163 }
156 read_unlock(&cifs_tcp_ses_lock); 164 spin_unlock(&cifs_tcp_ses_lock);
157 /* do not want to be sending data on a socket we are freeing */ 165 /* do not want to be sending data on a socket we are freeing */
158 mutex_lock(&server->srv_mutex); 166 mutex_lock(&server->srv_mutex);
159 if (server->ssocket) { 167 if (server->ssocket) {
@@ -166,6 +174,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
166 sock_release(server->ssocket); 174 sock_release(server->ssocket);
167 server->ssocket = NULL; 175 server->ssocket = NULL;
168 } 176 }
177 server->sequence_number = 0;
178 server->session_estab = false;
179 kfree(server->session_key.response);
180 server->session_key.response = NULL;
181 server->session_key.len = 0;
169 182
170 spin_lock(&GlobalMid_Lock); 183 spin_lock(&GlobalMid_Lock);
171 list_for_each(tmp, &server->pending_mid_q) { 184 list_for_each(tmp, &server->pending_mid_q) {
@@ -198,7 +211,6 @@ cifs_reconnect(struct TCP_Server_Info *server)
198 spin_lock(&GlobalMid_Lock); 211 spin_lock(&GlobalMid_Lock);
199 if (server->tcpStatus != CifsExiting) 212 if (server->tcpStatus != CifsExiting)
200 server->tcpStatus = CifsGood; 213 server->tcpStatus = CifsGood;
201 server->sequence_number = 0;
202 spin_unlock(&GlobalMid_Lock); 214 spin_unlock(&GlobalMid_Lock);
203 /* atomic_set(&server->inFlight,0);*/ 215 /* atomic_set(&server->inFlight,0);*/
204 wake_up(&server->response_q); 216 wake_up(&server->response_q);
@@ -629,9 +641,9 @@ multi_t2_fnd:
629 } /* end while !EXITING */ 641 } /* end while !EXITING */
630 642
631 /* take it off the list, if it's not already */ 643 /* take it off the list, if it's not already */
632 write_lock(&cifs_tcp_ses_lock); 644 spin_lock(&cifs_tcp_ses_lock);
633 list_del_init(&server->tcp_ses_list); 645 list_del_init(&server->tcp_ses_list);
634 write_unlock(&cifs_tcp_ses_lock); 646 spin_unlock(&cifs_tcp_ses_lock);
635 647
636 spin_lock(&GlobalMid_Lock); 648 spin_lock(&GlobalMid_Lock);
637 server->tcpStatus = CifsExiting; 649 server->tcpStatus = CifsExiting;
@@ -669,7 +681,7 @@ multi_t2_fnd:
669 * BB: we shouldn't have to do any of this. It shouldn't be 681 * BB: we shouldn't have to do any of this. It shouldn't be
670 * possible to exit from the thread with active SMB sessions 682 * possible to exit from the thread with active SMB sessions
671 */ 683 */
672 read_lock(&cifs_tcp_ses_lock); 684 spin_lock(&cifs_tcp_ses_lock);
673 if (list_empty(&server->pending_mid_q)) { 685 if (list_empty(&server->pending_mid_q)) {
674 /* loop through server session structures attached to this and 686 /* loop through server session structures attached to this and
675 mark them dead */ 687 mark them dead */
@@ -679,7 +691,7 @@ multi_t2_fnd:
679 ses->status = CifsExiting; 691 ses->status = CifsExiting;
680 ses->server = NULL; 692 ses->server = NULL;
681 } 693 }
682 read_unlock(&cifs_tcp_ses_lock); 694 spin_unlock(&cifs_tcp_ses_lock);
683 } else { 695 } else {
684 /* although we can not zero the server struct pointer yet, 696 /* although we can not zero the server struct pointer yet,
685 since there are active requests which may depnd on them, 697 since there are active requests which may depnd on them,
@@ -702,7 +714,7 @@ multi_t2_fnd:
702 } 714 }
703 } 715 }
704 spin_unlock(&GlobalMid_Lock); 716 spin_unlock(&GlobalMid_Lock);
705 read_unlock(&cifs_tcp_ses_lock); 717 spin_unlock(&cifs_tcp_ses_lock);
706 /* 1/8th of sec is more than enough time for them to exit */ 718 /* 1/8th of sec is more than enough time for them to exit */
707 msleep(125); 719 msleep(125);
708 } 720 }
@@ -725,12 +737,12 @@ multi_t2_fnd:
725 if a crazy root user tried to kill cifsd 737 if a crazy root user tried to kill cifsd
726 kernel thread explicitly this might happen) */ 738 kernel thread explicitly this might happen) */
727 /* BB: This shouldn't be necessary, see above */ 739 /* BB: This shouldn't be necessary, see above */
728 read_lock(&cifs_tcp_ses_lock); 740 spin_lock(&cifs_tcp_ses_lock);
729 list_for_each(tmp, &server->smb_ses_list) { 741 list_for_each(tmp, &server->smb_ses_list) {
730 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); 742 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
731 ses->server = NULL; 743 ses->server = NULL;
732 } 744 }
733 read_unlock(&cifs_tcp_ses_lock); 745 spin_unlock(&cifs_tcp_ses_lock);
734 746
735 kfree(server->hostname); 747 kfree(server->hostname);
736 task_to_wake = xchg(&server->tsk, NULL); 748 task_to_wake = xchg(&server->tsk, NULL);
@@ -1046,6 +1058,22 @@ cifs_parse_mount_options(char *options, const char *devname,
1046 "long\n"); 1058 "long\n");
1047 return 1; 1059 return 1;
1048 } 1060 }
1061 } else if (strnicmp(data, "srcaddr", 7) == 0) {
1062 vol->srcaddr.ss_family = AF_UNSPEC;
1063
1064 if (!value || !*value) {
1065 printk(KERN_WARNING "CIFS: srcaddr value"
1066 " not specified.\n");
1067 return 1; /* needs_arg; */
1068 }
1069 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1070 value, strlen(value));
1071 if (i == 0) {
1072 printk(KERN_WARNING "CIFS: Could not parse"
1073 " srcaddr: %s\n",
1074 value);
1075 return 1;
1076 }
1049 } else if (strnicmp(data, "prefixpath", 10) == 0) { 1077 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1050 if (!value || !*value) { 1078 if (!value || !*value) {
1051 printk(KERN_WARNING 1079 printk(KERN_WARNING
@@ -1325,6 +1353,10 @@ cifs_parse_mount_options(char *options, const char *devname,
1325 "/proc/fs/cifs/LookupCacheEnabled to 0\n"); 1353 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1326 } else if (strnicmp(data, "fsc", 3) == 0) { 1354 } else if (strnicmp(data, "fsc", 3) == 0) {
1327 vol->fsc = true; 1355 vol->fsc = true;
1356 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1357 vol->mfsymlinks = true;
1358 } else if (strnicmp(data, "multiuser", 8) == 0) {
1359 vol->multiuser = true;
1328 } else 1360 } else
1329 printk(KERN_WARNING "CIFS: Unknown mount option %s\n", 1361 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1330 data); 1362 data);
@@ -1356,6 +1388,13 @@ cifs_parse_mount_options(char *options, const char *devname,
1356 return 1; 1388 return 1;
1357 } 1389 }
1358 } 1390 }
1391
1392 if (vol->multiuser && !(vol->secFlg & CIFSSEC_MAY_KRB5)) {
1393 cERROR(1, "Multiuser mounts currently require krb5 "
1394 "authentication!");
1395 return 1;
1396 }
1397
1359 if (vol->UNCip == NULL) 1398 if (vol->UNCip == NULL)
1360 vol->UNCip = &vol->UNC[2]; 1399 vol->UNCip = &vol->UNC[2];
1361 1400
@@ -1374,8 +1413,36 @@ cifs_parse_mount_options(char *options, const char *devname,
1374 return 0; 1413 return 0;
1375} 1414}
1376 1415
1416/** Returns true if srcaddr isn't specified and rhs isn't
1417 * specified, or if srcaddr is specified and
1418 * matches the IP address of the rhs argument.
1419 */
1420static bool
1421srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1422{
1423 switch (srcaddr->sa_family) {
1424 case AF_UNSPEC:
1425 return (rhs->sa_family == AF_UNSPEC);
1426 case AF_INET: {
1427 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1428 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1429 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1430 }
1431 case AF_INET6: {
1432 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1433 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
1434 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1435 }
1436 default:
1437 WARN_ON(1);
1438 return false; /* don't expect to be here */
1439 }
1440}
1441
1442
1377static bool 1443static bool
1378match_address(struct TCP_Server_Info *server, struct sockaddr *addr) 1444match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1445 struct sockaddr *srcaddr)
1379{ 1446{
1380 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; 1447 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1381 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; 1448 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
@@ -1402,6 +1469,9 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr)
1402 break; 1469 break;
1403 } 1470 }
1404 1471
1472 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1473 return false;
1474
1405 return true; 1475 return true;
1406} 1476}
1407 1477
@@ -1458,29 +1528,21 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1458{ 1528{
1459 struct TCP_Server_Info *server; 1529 struct TCP_Server_Info *server;
1460 1530
1461 write_lock(&cifs_tcp_ses_lock); 1531 spin_lock(&cifs_tcp_ses_lock);
1462 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 1532 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1463 /* 1533 if (!match_address(server, addr,
1464 * the demux thread can exit on its own while still in CifsNew 1534 (struct sockaddr *)&vol->srcaddr))
1465 * so don't accept any sockets in that state. Since the
1466 * tcpStatus never changes back to CifsNew it's safe to check
1467 * for this without a lock.
1468 */
1469 if (server->tcpStatus == CifsNew)
1470 continue;
1471
1472 if (!match_address(server, addr))
1473 continue; 1535 continue;
1474 1536
1475 if (!match_security(server, vol)) 1537 if (!match_security(server, vol))
1476 continue; 1538 continue;
1477 1539
1478 ++server->srv_count; 1540 ++server->srv_count;
1479 write_unlock(&cifs_tcp_ses_lock); 1541 spin_unlock(&cifs_tcp_ses_lock);
1480 cFYI(1, "Existing tcp session with server found"); 1542 cFYI(1, "Existing tcp session with server found");
1481 return server; 1543 return server;
1482 } 1544 }
1483 write_unlock(&cifs_tcp_ses_lock); 1545 spin_unlock(&cifs_tcp_ses_lock);
1484 return NULL; 1546 return NULL;
1485} 1547}
1486 1548
@@ -1489,21 +1551,26 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
1489{ 1551{
1490 struct task_struct *task; 1552 struct task_struct *task;
1491 1553
1492 write_lock(&cifs_tcp_ses_lock); 1554 spin_lock(&cifs_tcp_ses_lock);
1493 if (--server->srv_count > 0) { 1555 if (--server->srv_count > 0) {
1494 write_unlock(&cifs_tcp_ses_lock); 1556 spin_unlock(&cifs_tcp_ses_lock);
1495 return; 1557 return;
1496 } 1558 }
1497 1559
1498 list_del_init(&server->tcp_ses_list); 1560 list_del_init(&server->tcp_ses_list);
1499 write_unlock(&cifs_tcp_ses_lock); 1561 spin_unlock(&cifs_tcp_ses_lock);
1500 1562
1501 spin_lock(&GlobalMid_Lock); 1563 spin_lock(&GlobalMid_Lock);
1502 server->tcpStatus = CifsExiting; 1564 server->tcpStatus = CifsExiting;
1503 spin_unlock(&GlobalMid_Lock); 1565 spin_unlock(&GlobalMid_Lock);
1504 1566
1567 cifs_crypto_shash_release(server);
1505 cifs_fscache_release_client_cookie(server); 1568 cifs_fscache_release_client_cookie(server);
1506 1569
1570 kfree(server->session_key.response);
1571 server->session_key.response = NULL;
1572 server->session_key.len = 0;
1573
1507 task = xchg(&server->tsk, NULL); 1574 task = xchg(&server->tsk, NULL);
1508 if (task) 1575 if (task)
1509 force_sig(SIGKILL, task); 1576 force_sig(SIGKILL, task);
@@ -1556,10 +1623,16 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1556 goto out_err; 1623 goto out_err;
1557 } 1624 }
1558 1625
1626 rc = cifs_crypto_shash_allocate(tcp_ses);
1627 if (rc) {
1628 cERROR(1, "could not setup hash structures rc %d", rc);
1629 goto out_err;
1630 }
1631
1559 tcp_ses->hostname = extract_hostname(volume_info->UNC); 1632 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1560 if (IS_ERR(tcp_ses->hostname)) { 1633 if (IS_ERR(tcp_ses->hostname)) {
1561 rc = PTR_ERR(tcp_ses->hostname); 1634 rc = PTR_ERR(tcp_ses->hostname);
1562 goto out_err; 1635 goto out_err_crypto_release;
1563 } 1636 }
1564 1637
1565 tcp_ses->noblocksnd = volume_info->noblocksnd; 1638 tcp_ses->noblocksnd = volume_info->noblocksnd;
@@ -1574,6 +1647,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1574 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); 1647 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1575 memcpy(tcp_ses->server_RFC1001_name, 1648 memcpy(tcp_ses->server_RFC1001_name,
1576 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); 1649 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1650 tcp_ses->session_estab = false;
1577 tcp_ses->sequence_number = 0; 1651 tcp_ses->sequence_number = 0;
1578 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); 1652 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1579 INIT_LIST_HEAD(&tcp_ses->smb_ses_list); 1653 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
@@ -1584,6 +1658,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1584 * no need to spinlock this init of tcpStatus or srv_count 1658 * no need to spinlock this init of tcpStatus or srv_count
1585 */ 1659 */
1586 tcp_ses->tcpStatus = CifsNew; 1660 tcp_ses->tcpStatus = CifsNew;
1661 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
1662 sizeof(tcp_ses->srcaddr));
1587 ++tcp_ses->srv_count; 1663 ++tcp_ses->srv_count;
1588 1664
1589 if (addr.ss_family == AF_INET6) { 1665 if (addr.ss_family == AF_INET6) {
@@ -1600,7 +1676,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1600 } 1676 }
1601 if (rc < 0) { 1677 if (rc < 0) {
1602 cERROR(1, "Error connecting to socket. Aborting operation"); 1678 cERROR(1, "Error connecting to socket. Aborting operation");
1603 goto out_err; 1679 goto out_err_crypto_release;
1604 } 1680 }
1605 1681
1606 /* 1682 /*
@@ -1614,18 +1690,21 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1614 rc = PTR_ERR(tcp_ses->tsk); 1690 rc = PTR_ERR(tcp_ses->tsk);
1615 cERROR(1, "error %d create cifsd thread", rc); 1691 cERROR(1, "error %d create cifsd thread", rc);
1616 module_put(THIS_MODULE); 1692 module_put(THIS_MODULE);
1617 goto out_err; 1693 goto out_err_crypto_release;
1618 } 1694 }
1619 1695
1620 /* thread spawned, put it on the list */ 1696 /* thread spawned, put it on the list */
1621 write_lock(&cifs_tcp_ses_lock); 1697 spin_lock(&cifs_tcp_ses_lock);
1622 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); 1698 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1623 write_unlock(&cifs_tcp_ses_lock); 1699 spin_unlock(&cifs_tcp_ses_lock);
1624 1700
1625 cifs_fscache_get_client_cookie(tcp_ses); 1701 cifs_fscache_get_client_cookie(tcp_ses);
1626 1702
1627 return tcp_ses; 1703 return tcp_ses;
1628 1704
1705out_err_crypto_release:
1706 cifs_crypto_shash_release(tcp_ses);
1707
1629out_err: 1708out_err:
1630 if (tcp_ses) { 1709 if (tcp_ses) {
1631 if (!IS_ERR(tcp_ses->hostname)) 1710 if (!IS_ERR(tcp_ses->hostname))
@@ -1642,7 +1721,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1642{ 1721{
1643 struct cifsSesInfo *ses; 1722 struct cifsSesInfo *ses;
1644 1723
1645 write_lock(&cifs_tcp_ses_lock); 1724 spin_lock(&cifs_tcp_ses_lock);
1646 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { 1725 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1647 switch (server->secType) { 1726 switch (server->secType) {
1648 case Kerberos: 1727 case Kerberos:
@@ -1662,10 +1741,10 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1662 continue; 1741 continue;
1663 } 1742 }
1664 ++ses->ses_count; 1743 ++ses->ses_count;
1665 write_unlock(&cifs_tcp_ses_lock); 1744 spin_unlock(&cifs_tcp_ses_lock);
1666 return ses; 1745 return ses;
1667 } 1746 }
1668 write_unlock(&cifs_tcp_ses_lock); 1747 spin_unlock(&cifs_tcp_ses_lock);
1669 return NULL; 1748 return NULL;
1670} 1749}
1671 1750
@@ -1676,14 +1755,14 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
1676 struct TCP_Server_Info *server = ses->server; 1755 struct TCP_Server_Info *server = ses->server;
1677 1756
1678 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count); 1757 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
1679 write_lock(&cifs_tcp_ses_lock); 1758 spin_lock(&cifs_tcp_ses_lock);
1680 if (--ses->ses_count > 0) { 1759 if (--ses->ses_count > 0) {
1681 write_unlock(&cifs_tcp_ses_lock); 1760 spin_unlock(&cifs_tcp_ses_lock);
1682 return; 1761 return;
1683 } 1762 }
1684 1763
1685 list_del_init(&ses->smb_ses_list); 1764 list_del_init(&ses->smb_ses_list);
1686 write_unlock(&cifs_tcp_ses_lock); 1765 spin_unlock(&cifs_tcp_ses_lock);
1687 1766
1688 if (ses->status == CifsGood) { 1767 if (ses->status == CifsGood) {
1689 xid = GetXid(); 1768 xid = GetXid();
@@ -1760,10 +1839,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1760 goto get_ses_fail; 1839 goto get_ses_fail;
1761 } 1840 }
1762 if (volume_info->domainname) { 1841 if (volume_info->domainname) {
1763 int len = strlen(volume_info->domainname); 1842 ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
1764 ses->domainName = kmalloc(len + 1, GFP_KERNEL); 1843 if (!ses->domainName)
1765 if (ses->domainName) 1844 goto get_ses_fail;
1766 strcpy(ses->domainName, volume_info->domainname);
1767 } 1845 }
1768 ses->cred_uid = volume_info->cred_uid; 1846 ses->cred_uid = volume_info->cred_uid;
1769 ses->linux_uid = volume_info->linux_uid; 1847 ses->linux_uid = volume_info->linux_uid;
@@ -1778,9 +1856,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1778 goto get_ses_fail; 1856 goto get_ses_fail;
1779 1857
1780 /* success, put it on the list */ 1858 /* success, put it on the list */
1781 write_lock(&cifs_tcp_ses_lock); 1859 spin_lock(&cifs_tcp_ses_lock);
1782 list_add(&ses->smb_ses_list, &server->smb_ses_list); 1860 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1783 write_unlock(&cifs_tcp_ses_lock); 1861 spin_unlock(&cifs_tcp_ses_lock);
1784 1862
1785 FreeXid(xid); 1863 FreeXid(xid);
1786 return ses; 1864 return ses;
@@ -1797,7 +1875,7 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1797 struct list_head *tmp; 1875 struct list_head *tmp;
1798 struct cifsTconInfo *tcon; 1876 struct cifsTconInfo *tcon;
1799 1877
1800 write_lock(&cifs_tcp_ses_lock); 1878 spin_lock(&cifs_tcp_ses_lock);
1801 list_for_each(tmp, &ses->tcon_list) { 1879 list_for_each(tmp, &ses->tcon_list) {
1802 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list); 1880 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1803 if (tcon->tidStatus == CifsExiting) 1881 if (tcon->tidStatus == CifsExiting)
@@ -1806,10 +1884,10 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1806 continue; 1884 continue;
1807 1885
1808 ++tcon->tc_count; 1886 ++tcon->tc_count;
1809 write_unlock(&cifs_tcp_ses_lock); 1887 spin_unlock(&cifs_tcp_ses_lock);
1810 return tcon; 1888 return tcon;
1811 } 1889 }
1812 write_unlock(&cifs_tcp_ses_lock); 1890 spin_unlock(&cifs_tcp_ses_lock);
1813 return NULL; 1891 return NULL;
1814} 1892}
1815 1893
@@ -1820,14 +1898,14 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
1820 struct cifsSesInfo *ses = tcon->ses; 1898 struct cifsSesInfo *ses = tcon->ses;
1821 1899
1822 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count); 1900 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
1823 write_lock(&cifs_tcp_ses_lock); 1901 spin_lock(&cifs_tcp_ses_lock);
1824 if (--tcon->tc_count > 0) { 1902 if (--tcon->tc_count > 0) {
1825 write_unlock(&cifs_tcp_ses_lock); 1903 spin_unlock(&cifs_tcp_ses_lock);
1826 return; 1904 return;
1827 } 1905 }
1828 1906
1829 list_del_init(&tcon->tcon_list); 1907 list_del_init(&tcon->tcon_list);
1830 write_unlock(&cifs_tcp_ses_lock); 1908 spin_unlock(&cifs_tcp_ses_lock);
1831 1909
1832 xid = GetXid(); 1910 xid = GetXid();
1833 CIFSSMBTDis(xid, tcon); 1911 CIFSSMBTDis(xid, tcon);
@@ -1900,9 +1978,9 @@ cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1900 tcon->nocase = volume_info->nocase; 1978 tcon->nocase = volume_info->nocase;
1901 tcon->local_lease = volume_info->local_lease; 1979 tcon->local_lease = volume_info->local_lease;
1902 1980
1903 write_lock(&cifs_tcp_ses_lock); 1981 spin_lock(&cifs_tcp_ses_lock);
1904 list_add(&tcon->tcon_list, &ses->tcon_list); 1982 list_add(&tcon->tcon_list, &ses->tcon_list);
1905 write_unlock(&cifs_tcp_ses_lock); 1983 spin_unlock(&cifs_tcp_ses_lock);
1906 1984
1907 cifs_fscache_get_super_cookie(tcon); 1985 cifs_fscache_get_super_cookie(tcon);
1908 1986
@@ -1913,6 +1991,23 @@ out_fail:
1913 return ERR_PTR(rc); 1991 return ERR_PTR(rc);
1914} 1992}
1915 1993
1994void
1995cifs_put_tlink(struct tcon_link *tlink)
1996{
1997 if (!tlink || IS_ERR(tlink))
1998 return;
1999
2000 if (!atomic_dec_and_test(&tlink->tl_count) ||
2001 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
2002 tlink->tl_time = jiffies;
2003 return;
2004 }
2005
2006 if (!IS_ERR(tlink_tcon(tlink)))
2007 cifs_put_tcon(tlink_tcon(tlink));
2008 kfree(tlink);
2009 return;
2010}
1916 2011
1917int 2012int
1918get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, 2013get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
@@ -1997,6 +2092,33 @@ static void rfc1002mangle(char *target, char *source, unsigned int length)
1997 2092
1998} 2093}
1999 2094
2095static int
2096bind_socket(struct TCP_Server_Info *server)
2097{
2098 int rc = 0;
2099 if (server->srcaddr.ss_family != AF_UNSPEC) {
2100 /* Bind to the specified local IP address */
2101 struct socket *socket = server->ssocket;
2102 rc = socket->ops->bind(socket,
2103 (struct sockaddr *) &server->srcaddr,
2104 sizeof(server->srcaddr));
2105 if (rc < 0) {
2106 struct sockaddr_in *saddr4;
2107 struct sockaddr_in6 *saddr6;
2108 saddr4 = (struct sockaddr_in *)&server->srcaddr;
2109 saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2110 if (saddr6->sin6_family == AF_INET6)
2111 cERROR(1, "cifs: "
2112 "Failed to bind to: %pI6c, error: %d\n",
2113 &saddr6->sin6_addr, rc);
2114 else
2115 cERROR(1, "cifs: "
2116 "Failed to bind to: %pI4, error: %d\n",
2117 &saddr4->sin_addr.s_addr, rc);
2118 }
2119 }
2120 return rc;
2121}
2000 2122
2001static int 2123static int
2002ipv4_connect(struct TCP_Server_Info *server) 2124ipv4_connect(struct TCP_Server_Info *server)
@@ -2022,6 +2144,10 @@ ipv4_connect(struct TCP_Server_Info *server)
2022 cifs_reclassify_socket4(socket); 2144 cifs_reclassify_socket4(socket);
2023 } 2145 }
2024 2146
2147 rc = bind_socket(server);
2148 if (rc < 0)
2149 return rc;
2150
2025 /* user overrode default port */ 2151 /* user overrode default port */
2026 if (server->addr.sockAddr.sin_port) { 2152 if (server->addr.sockAddr.sin_port) {
2027 rc = socket->ops->connect(socket, (struct sockaddr *) 2153 rc = socket->ops->connect(socket, (struct sockaddr *)
@@ -2184,6 +2310,10 @@ ipv6_connect(struct TCP_Server_Info *server)
2184 cifs_reclassify_socket6(socket); 2310 cifs_reclassify_socket6(socket);
2185 } 2311 }
2186 2312
2313 rc = bind_socket(server);
2314 if (rc < 0)
2315 return rc;
2316
2187 /* user overrode default port */ 2317 /* user overrode default port */
2188 if (server->addr.sockAddr6.sin6_port) { 2318 if (server->addr.sockAddr6.sin6_port) {
2189 rc = socket->ops->connect(socket, 2319 rc = socket->ops->connect(socket,
@@ -2383,6 +2513,8 @@ convert_delimiter(char *path, char delim)
2383static void setup_cifs_sb(struct smb_vol *pvolume_info, 2513static void setup_cifs_sb(struct smb_vol *pvolume_info,
2384 struct cifs_sb_info *cifs_sb) 2514 struct cifs_sb_info *cifs_sb)
2385{ 2515{
2516 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
2517
2386 if (pvolume_info->rsize > CIFSMaxBufSize) { 2518 if (pvolume_info->rsize > CIFSMaxBufSize) {
2387 cERROR(1, "rsize %d too large, using MaxBufSize", 2519 cERROR(1, "rsize %d too large, using MaxBufSize",
2388 pvolume_info->rsize); 2520 pvolume_info->rsize);
@@ -2462,10 +2594,21 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2462 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; 2594 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2463 if (pvolume_info->fsc) 2595 if (pvolume_info->fsc)
2464 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE; 2596 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
2597 if (pvolume_info->multiuser)
2598 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
2599 CIFS_MOUNT_NO_PERM);
2465 if (pvolume_info->direct_io) { 2600 if (pvolume_info->direct_io) {
2466 cFYI(1, "mounting share using direct i/o"); 2601 cFYI(1, "mounting share using direct i/o");
2467 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2602 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2468 } 2603 }
2604 if (pvolume_info->mfsymlinks) {
2605 if (pvolume_info->sfu_emul) {
2606 cERROR(1, "mount option mfsymlinks ignored if sfu "
2607 "mount option is used");
2608 } else {
2609 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
2610 }
2611 }
2469 2612
2470 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) 2613 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2471 cERROR(1, "mount option dynperm ignored if cifsacl " 2614 cERROR(1, "mount option dynperm ignored if cifsacl "
@@ -2552,6 +2695,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2552 struct TCP_Server_Info *srvTcp; 2695 struct TCP_Server_Info *srvTcp;
2553 char *full_path; 2696 char *full_path;
2554 char *mount_data = mount_data_global; 2697 char *mount_data = mount_data_global;
2698 struct tcon_link *tlink;
2555#ifdef CONFIG_CIFS_DFS_UPCALL 2699#ifdef CONFIG_CIFS_DFS_UPCALL
2556 struct dfs_info3_param *referrals = NULL; 2700 struct dfs_info3_param *referrals = NULL;
2557 unsigned int num_referrals = 0; 2701 unsigned int num_referrals = 0;
@@ -2563,6 +2707,7 @@ try_mount_again:
2563 pSesInfo = NULL; 2707 pSesInfo = NULL;
2564 srvTcp = NULL; 2708 srvTcp = NULL;
2565 full_path = NULL; 2709 full_path = NULL;
2710 tlink = NULL;
2566 2711
2567 xid = GetXid(); 2712 xid = GetXid();
2568 2713
@@ -2638,8 +2783,6 @@ try_mount_again:
2638 goto remote_path_check; 2783 goto remote_path_check;
2639 } 2784 }
2640 2785
2641 cifs_sb->tcon = tcon;
2642
2643 /* do not care if following two calls succeed - informational */ 2786 /* do not care if following two calls succeed - informational */
2644 if (!tcon->ipc) { 2787 if (!tcon->ipc) {
2645 CIFSSMBQFSDeviceInfo(xid, tcon); 2788 CIFSSMBQFSDeviceInfo(xid, tcon);
@@ -2748,6 +2891,30 @@ remote_path_check:
2748#endif 2891#endif
2749 } 2892 }
2750 2893
2894 if (rc)
2895 goto mount_fail_check;
2896
2897 /* now, hang the tcon off of the superblock */
2898 tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
2899 if (tlink == NULL) {
2900 rc = -ENOMEM;
2901 goto mount_fail_check;
2902 }
2903
2904 tlink->tl_uid = pSesInfo->linux_uid;
2905 tlink->tl_tcon = tcon;
2906 tlink->tl_time = jiffies;
2907 set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
2908 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
2909
2910 cifs_sb->master_tlink = tlink;
2911 spin_lock(&cifs_sb->tlink_tree_lock);
2912 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
2913 spin_unlock(&cifs_sb->tlink_tree_lock);
2914
2915 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
2916 TLINK_IDLE_EXPIRE);
2917
2751mount_fail_check: 2918mount_fail_check:
2752 /* on error free sesinfo and tcon struct if needed */ 2919 /* on error free sesinfo and tcon struct if needed */
2753 if (rc) { 2920 if (rc) {
@@ -2825,14 +2992,13 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2825#ifdef CONFIG_CIFS_WEAK_PW_HASH 2992#ifdef CONFIG_CIFS_WEAK_PW_HASH
2826 if ((global_secflags & CIFSSEC_MAY_LANMAN) && 2993 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
2827 (ses->server->secType == LANMAN)) 2994 (ses->server->secType == LANMAN))
2828 calc_lanman_hash(tcon->password, ses->server->cryptKey, 2995 calc_lanman_hash(tcon->password, ses->server->cryptkey,
2829 ses->server->secMode & 2996 ses->server->secMode &
2830 SECMODE_PW_ENCRYPT ? true : false, 2997 SECMODE_PW_ENCRYPT ? true : false,
2831 bcc_ptr); 2998 bcc_ptr);
2832 else 2999 else
2833#endif /* CIFS_WEAK_PW_HASH */ 3000#endif /* CIFS_WEAK_PW_HASH */
2834 SMBNTencrypt(tcon->password, ses->server->cryptKey, 3001 SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr);
2835 bcc_ptr);
2836 3002
2837 bcc_ptr += CIFS_SESS_KEY_SIZE; 3003 bcc_ptr += CIFS_SESS_KEY_SIZE;
2838 if (ses->capabilities & CAP_UNICODE) { 3004 if (ses->capabilities & CAP_UNICODE) {
@@ -2934,19 +3100,32 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2934int 3100int
2935cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) 3101cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
2936{ 3102{
2937 int rc = 0; 3103 struct rb_root *root = &cifs_sb->tlink_tree;
3104 struct rb_node *node;
3105 struct tcon_link *tlink;
2938 char *tmp; 3106 char *tmp;
2939 3107
2940 if (cifs_sb->tcon) 3108 cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
2941 cifs_put_tcon(cifs_sb->tcon); 3109
3110 spin_lock(&cifs_sb->tlink_tree_lock);
3111 while ((node = rb_first(root))) {
3112 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
3113 cifs_get_tlink(tlink);
3114 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3115 rb_erase(node, root);
3116
3117 spin_unlock(&cifs_sb->tlink_tree_lock);
3118 cifs_put_tlink(tlink);
3119 spin_lock(&cifs_sb->tlink_tree_lock);
3120 }
3121 spin_unlock(&cifs_sb->tlink_tree_lock);
2942 3122
2943 cifs_sb->tcon = NULL;
2944 tmp = cifs_sb->prepath; 3123 tmp = cifs_sb->prepath;
2945 cifs_sb->prepathlen = 0; 3124 cifs_sb->prepathlen = 0;
2946 cifs_sb->prepath = NULL; 3125 cifs_sb->prepath = NULL;
2947 kfree(tmp); 3126 kfree(tmp);
2948 3127
2949 return rc; 3128 return 0;
2950} 3129}
2951 3130
2952int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses) 3131int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
@@ -2997,6 +3176,16 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
2997 if (rc) { 3176 if (rc) {
2998 cERROR(1, "Send error in SessSetup = %d", rc); 3177 cERROR(1, "Send error in SessSetup = %d", rc);
2999 } else { 3178 } else {
3179 mutex_lock(&ses->server->srv_mutex);
3180 if (!server->session_estab) {
3181 server->session_key.response = ses->auth_key.response;
3182 server->session_key.len = ses->auth_key.len;
3183 server->sequence_number = 0x2;
3184 server->session_estab = true;
3185 ses->auth_key.response = NULL;
3186 }
3187 mutex_unlock(&server->srv_mutex);
3188
3000 cFYI(1, "CIFS Session Established successfully"); 3189 cFYI(1, "CIFS Session Established successfully");
3001 spin_lock(&GlobalMid_Lock); 3190 spin_lock(&GlobalMid_Lock);
3002 ses->status = CifsGood; 3191 ses->status = CifsGood;
@@ -3004,6 +3193,263 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3004 spin_unlock(&GlobalMid_Lock); 3193 spin_unlock(&GlobalMid_Lock);
3005 } 3194 }
3006 3195
3196 kfree(ses->auth_key.response);
3197 ses->auth_key.response = NULL;
3198 ses->auth_key.len = 0;
3199 kfree(ses->ntlmssp);
3200 ses->ntlmssp = NULL;
3201
3007 return rc; 3202 return rc;
3008} 3203}
3009 3204
3205static struct cifsTconInfo *
3206cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3207{
3208 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb);
3209 struct cifsSesInfo *ses;
3210 struct cifsTconInfo *tcon = NULL;
3211 struct smb_vol *vol_info;
3212 char username[MAX_USERNAME_SIZE + 1];
3213
3214 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
3215 if (vol_info == NULL) {
3216 tcon = ERR_PTR(-ENOMEM);
3217 goto out;
3218 }
3219
3220 snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid);
3221 vol_info->username = username;
3222 vol_info->local_nls = cifs_sb->local_nls;
3223 vol_info->linux_uid = fsuid;
3224 vol_info->cred_uid = fsuid;
3225 vol_info->UNC = master_tcon->treeName;
3226 vol_info->retry = master_tcon->retry;
3227 vol_info->nocase = master_tcon->nocase;
3228 vol_info->local_lease = master_tcon->local_lease;
3229 vol_info->no_linux_ext = !master_tcon->unix_ext;
3230
3231 /* FIXME: allow for other secFlg settings */
3232 vol_info->secFlg = CIFSSEC_MUST_KRB5;
3233
3234 /* get a reference for the same TCP session */
3235 spin_lock(&cifs_tcp_ses_lock);
3236 ++master_tcon->ses->server->srv_count;
3237 spin_unlock(&cifs_tcp_ses_lock);
3238
3239 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
3240 if (IS_ERR(ses)) {
3241 tcon = (struct cifsTconInfo *)ses;
3242 cifs_put_tcp_session(master_tcon->ses->server);
3243 goto out;
3244 }
3245
3246 tcon = cifs_get_tcon(ses, vol_info);
3247 if (IS_ERR(tcon)) {
3248 cifs_put_smb_ses(ses);
3249 goto out;
3250 }
3251
3252 if (ses->capabilities & CAP_UNIX)
3253 reset_cifs_unix_caps(0, tcon, NULL, vol_info);
3254out:
3255 kfree(vol_info);
3256
3257 return tcon;
3258}
3259
3260static inline struct tcon_link *
3261cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
3262{
3263 return cifs_sb->master_tlink;
3264}
3265
3266struct cifsTconInfo *
3267cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3268{
3269 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
3270}
3271
3272static int
3273cifs_sb_tcon_pending_wait(void *unused)
3274{
3275 schedule();
3276 return signal_pending(current) ? -ERESTARTSYS : 0;
3277}
3278
3279/* find and return a tlink with given uid */
3280static struct tcon_link *
3281tlink_rb_search(struct rb_root *root, uid_t uid)
3282{
3283 struct rb_node *node = root->rb_node;
3284 struct tcon_link *tlink;
3285
3286 while (node) {
3287 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
3288
3289 if (tlink->tl_uid > uid)
3290 node = node->rb_left;
3291 else if (tlink->tl_uid < uid)
3292 node = node->rb_right;
3293 else
3294 return tlink;
3295 }
3296 return NULL;
3297}
3298
3299/* insert a tcon_link into the tree */
3300static void
3301tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
3302{
3303 struct rb_node **new = &(root->rb_node), *parent = NULL;
3304 struct tcon_link *tlink;
3305
3306 while (*new) {
3307 tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
3308 parent = *new;
3309
3310 if (tlink->tl_uid > new_tlink->tl_uid)
3311 new = &((*new)->rb_left);
3312 else
3313 new = &((*new)->rb_right);
3314 }
3315
3316 rb_link_node(&new_tlink->tl_rbnode, parent, new);
3317 rb_insert_color(&new_tlink->tl_rbnode, root);
3318}
3319
3320/*
3321 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
3322 * current task.
3323 *
3324 * If the superblock doesn't refer to a multiuser mount, then just return
3325 * the master tcon for the mount.
3326 *
3327 * First, search the rbtree for an existing tcon for this fsuid. If one
3328 * exists, then check to see if it's pending construction. If it is then wait
3329 * for construction to complete. Once it's no longer pending, check to see if
3330 * it failed and either return an error or retry construction, depending on
3331 * the timeout.
3332 *
3333 * If one doesn't exist then insert a new tcon_link struct into the tree and
3334 * try to construct a new one.
3335 */
3336struct tcon_link *
3337cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
3338{
3339 int ret;
3340 uid_t fsuid = current_fsuid();
3341 struct tcon_link *tlink, *newtlink;
3342
3343 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
3344 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
3345
3346 spin_lock(&cifs_sb->tlink_tree_lock);
3347 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3348 if (tlink)
3349 cifs_get_tlink(tlink);
3350 spin_unlock(&cifs_sb->tlink_tree_lock);
3351
3352 if (tlink == NULL) {
3353 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
3354 if (newtlink == NULL)
3355 return ERR_PTR(-ENOMEM);
3356 newtlink->tl_uid = fsuid;
3357 newtlink->tl_tcon = ERR_PTR(-EACCES);
3358 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
3359 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
3360 cifs_get_tlink(newtlink);
3361
3362 spin_lock(&cifs_sb->tlink_tree_lock);
3363 /* was one inserted after previous search? */
3364 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3365 if (tlink) {
3366 cifs_get_tlink(tlink);
3367 spin_unlock(&cifs_sb->tlink_tree_lock);
3368 kfree(newtlink);
3369 goto wait_for_construction;
3370 }
3371 tlink = newtlink;
3372 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
3373 spin_unlock(&cifs_sb->tlink_tree_lock);
3374 } else {
3375wait_for_construction:
3376 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
3377 cifs_sb_tcon_pending_wait,
3378 TASK_INTERRUPTIBLE);
3379 if (ret) {
3380 cifs_put_tlink(tlink);
3381 return ERR_PTR(ret);
3382 }
3383
3384 /* if it's good, return it */
3385 if (!IS_ERR(tlink->tl_tcon))
3386 return tlink;
3387
3388 /* return error if we tried this already recently */
3389 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
3390 cifs_put_tlink(tlink);
3391 return ERR_PTR(-EACCES);
3392 }
3393
3394 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
3395 goto wait_for_construction;
3396 }
3397
3398 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
3399 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
3400 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
3401
3402 if (IS_ERR(tlink->tl_tcon)) {
3403 cifs_put_tlink(tlink);
3404 return ERR_PTR(-EACCES);
3405 }
3406
3407 return tlink;
3408}
3409
3410/*
3411 * periodic workqueue job that scans tcon_tree for a superblock and closes
3412 * out tcons.
3413 */
3414static void
3415cifs_prune_tlinks(struct work_struct *work)
3416{
3417 struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
3418 prune_tlinks.work);
3419 struct rb_root *root = &cifs_sb->tlink_tree;
3420 struct rb_node *node = rb_first(root);
3421 struct rb_node *tmp;
3422 struct tcon_link *tlink;
3423
3424 /*
3425 * Because we drop the spinlock in the loop in order to put the tlink
3426 * it's not guarded against removal of links from the tree. The only
3427 * places that remove entries from the tree are this function and
3428 * umounts. Because this function is non-reentrant and is canceled
3429 * before umount can proceed, this is safe.
3430 */
3431 spin_lock(&cifs_sb->tlink_tree_lock);
3432 node = rb_first(root);
3433 while (node != NULL) {
3434 tmp = node;
3435 node = rb_next(tmp);
3436 tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);
3437
3438 if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
3439 atomic_read(&tlink->tl_count) != 0 ||
3440 time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
3441 continue;
3442
3443 cifs_get_tlink(tlink);
3444 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3445 rb_erase(tmp, root);
3446
3447 spin_unlock(&cifs_sb->tlink_tree_lock);
3448 cifs_put_tlink(tlink);
3449 spin_lock(&cifs_sb->tlink_tree_lock);
3450 }
3451 spin_unlock(&cifs_sb->tlink_tree_lock);
3452
3453 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
3454 TLINK_IDLE_EXPIRE);
3455}