aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/connect.c158
1 files changed, 93 insertions, 65 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index eb85dd8d510e..74c222ed83dd 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1616,6 +1616,7 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
1616 int xid; 1616 int xid;
1617 struct TCP_Server_Info *server = ses->server; 1617 struct TCP_Server_Info *server = ses->server;
1618 1618
1619 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
1619 write_lock(&cifs_tcp_ses_lock); 1620 write_lock(&cifs_tcp_ses_lock);
1620 if (--ses->ses_count > 0) { 1621 if (--ses->ses_count > 0) {
1621 write_unlock(&cifs_tcp_ses_lock); 1622 write_unlock(&cifs_tcp_ses_lock);
@@ -1634,6 +1635,92 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
1634 cifs_put_tcp_session(server); 1635 cifs_put_tcp_session(server);
1635} 1636}
1636 1637
1638static struct cifsSesInfo *
1639cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1640{
1641 int rc = -ENOMEM, xid;
1642 struct cifsSesInfo *ses;
1643
1644 xid = GetXid();
1645
1646 ses = cifs_find_smb_ses(server, volume_info->username);
1647 if (ses) {
1648 cFYI(1, "Existing smb sess found (status=%d)", ses->status);
1649
1650 /* existing SMB ses has a server reference already */
1651 cifs_put_tcp_session(server);
1652
1653 mutex_lock(&ses->session_mutex);
1654 if (ses->need_reconnect) {
1655 cFYI(1, "Session needs reconnect");
1656 rc = cifs_setup_session(xid, ses,
1657 volume_info->local_nls);
1658 if (rc) {
1659 mutex_unlock(&ses->session_mutex);
1660 /* problem -- put our reference */
1661 cifs_put_smb_ses(ses);
1662 FreeXid(xid);
1663 return ERR_PTR(rc);
1664 }
1665 }
1666 mutex_unlock(&ses->session_mutex);
1667 FreeXid(xid);
1668 return ses;
1669 }
1670
1671 cFYI(1, "Existing smb sess not found");
1672 ses = sesInfoAlloc();
1673 if (ses == NULL)
1674 goto get_ses_fail;
1675
1676 /* new SMB session uses our server ref */
1677 ses->server = server;
1678 if (server->addr.sockAddr6.sin6_family == AF_INET6)
1679 sprintf(ses->serverName, "%pI6",
1680 &server->addr.sockAddr6.sin6_addr);
1681 else
1682 sprintf(ses->serverName, "%pI4",
1683 &server->addr.sockAddr.sin_addr.s_addr);
1684
1685 if (volume_info->username)
1686 strncpy(ses->userName, volume_info->username,
1687 MAX_USERNAME_SIZE);
1688
1689 /* volume_info->password freed at unmount */
1690 if (volume_info->password) {
1691 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
1692 if (!ses->password)
1693 goto get_ses_fail;
1694 }
1695 if (volume_info->domainname) {
1696 int len = strlen(volume_info->domainname);
1697 ses->domainName = kmalloc(len + 1, GFP_KERNEL);
1698 if (ses->domainName)
1699 strcpy(ses->domainName, volume_info->domainname);
1700 }
1701 ses->linux_uid = volume_info->linux_uid;
1702 ses->overrideSecFlg = volume_info->secFlg;
1703
1704 mutex_lock(&ses->session_mutex);
1705 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1706 mutex_unlock(&ses->session_mutex);
1707 if (rc)
1708 goto get_ses_fail;
1709
1710 /* success, put it on the list */
1711 write_lock(&cifs_tcp_ses_lock);
1712 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1713 write_unlock(&cifs_tcp_ses_lock);
1714
1715 FreeXid(xid);
1716 return ses;
1717
1718get_ses_fail:
1719 sesInfoFree(ses);
1720 FreeXid(xid);
1721 return ERR_PTR(rc);
1722}
1723
1637static struct cifsTconInfo * 1724static struct cifsTconInfo *
1638cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) 1725cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1639{ 1726{
@@ -2376,71 +2463,12 @@ try_mount_again:
2376 goto out; 2463 goto out;
2377 } 2464 }
2378 2465
2379 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username); 2466 /* get a reference to a SMB session */
2380 if (pSesInfo) { 2467 pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
2381 cFYI(1, "Existing smb sess found (status=%d)", 2468 if (IS_ERR(pSesInfo)) {
2382 pSesInfo->status); 2469 rc = PTR_ERR(pSesInfo);
2383 /* 2470 pSesInfo = NULL;
2384 * The existing SMB session already has a reference to srvTcp, 2471 goto mount_fail_check;
2385 * so we can put back the extra one we got before
2386 */
2387 cifs_put_tcp_session(srvTcp);
2388
2389 mutex_lock(&pSesInfo->session_mutex);
2390 if (pSesInfo->need_reconnect) {
2391 cFYI(1, "Session needs reconnect");
2392 rc = cifs_setup_session(xid, pSesInfo,
2393 cifs_sb->local_nls);
2394 }
2395 mutex_unlock(&pSesInfo->session_mutex);
2396 } else if (!rc) {
2397 cFYI(1, "Existing smb sess not found");
2398 pSesInfo = sesInfoAlloc();
2399 if (pSesInfo == NULL) {
2400 rc = -ENOMEM;
2401 goto mount_fail_check;
2402 }
2403
2404 /* new SMB session uses our srvTcp ref */
2405 pSesInfo->server = srvTcp;
2406 if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6)
2407 sprintf(pSesInfo->serverName, "%pI6",
2408 &srvTcp->addr.sockAddr6.sin6_addr);
2409 else
2410 sprintf(pSesInfo->serverName, "%pI4",
2411 &srvTcp->addr.sockAddr.sin_addr.s_addr);
2412
2413 write_lock(&cifs_tcp_ses_lock);
2414 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
2415 write_unlock(&cifs_tcp_ses_lock);
2416
2417 /* volume_info->password freed at unmount */
2418 if (volume_info->password) {
2419 pSesInfo->password = kstrdup(volume_info->password,
2420 GFP_KERNEL);
2421 if (!pSesInfo->password) {
2422 rc = -ENOMEM;
2423 goto mount_fail_check;
2424 }
2425 }
2426 if (volume_info->username)
2427 strncpy(pSesInfo->userName, volume_info->username,
2428 MAX_USERNAME_SIZE);
2429 if (volume_info->domainname) {
2430 int len = strlen(volume_info->domainname);
2431 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
2432 if (pSesInfo->domainName)
2433 strcpy(pSesInfo->domainName,
2434 volume_info->domainname);
2435 }
2436 pSesInfo->linux_uid = volume_info->linux_uid;
2437 pSesInfo->overrideSecFlg = volume_info->secFlg;
2438 mutex_lock(&pSesInfo->session_mutex);
2439
2440 /* BB FIXME need to pass vol->secFlgs BB */
2441 rc = cifs_setup_session(xid, pSesInfo,
2442 cifs_sb->local_nls);
2443 mutex_unlock(&pSesInfo->session_mutex);
2444 } 2472 }
2445 2473
2446 /* search for existing tcon to this server share */ 2474 /* search for existing tcon to this server share */