diff options
| author | Jeff Layton <jlayton@redhat.com> | 2010-04-24 07:57:44 -0400 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2010-04-26 14:55:31 -0400 |
| commit | d00c28de55a69d13cf2c6a99efc3e81a5d95af74 (patch) | |
| tree | a74daa468a4e9a4c2b6d2d8491beffbab489bbc5 | |
| parent | 36988c76f007738cad5fe1c873a5fb0cda7eb2f6 (diff) | |
cifs: move tcon find/create into separate function
...and out of cifs_mount.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
| -rw-r--r-- | fs/cifs/connect.c | 156 |
1 files changed, 86 insertions, 70 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 74c222ed83dd..c104f54cadfe 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -1749,6 +1749,7 @@ cifs_put_tcon(struct cifsTconInfo *tcon) | |||
| 1749 | int xid; | 1749 | int xid; |
| 1750 | struct cifsSesInfo *ses = tcon->ses; | 1750 | struct cifsSesInfo *ses = tcon->ses; |
| 1751 | 1751 | ||
| 1752 | cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count); | ||
| 1752 | write_lock(&cifs_tcp_ses_lock); | 1753 | write_lock(&cifs_tcp_ses_lock); |
| 1753 | if (--tcon->tc_count > 0) { | 1754 | if (--tcon->tc_count > 0) { |
| 1754 | write_unlock(&cifs_tcp_ses_lock); | 1755 | write_unlock(&cifs_tcp_ses_lock); |
| @@ -1766,6 +1767,80 @@ cifs_put_tcon(struct cifsTconInfo *tcon) | |||
| 1766 | cifs_put_smb_ses(ses); | 1767 | cifs_put_smb_ses(ses); |
| 1767 | } | 1768 | } |
| 1768 | 1769 | ||
| 1770 | static struct cifsTconInfo * | ||
| 1771 | cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info) | ||
| 1772 | { | ||
| 1773 | int rc, xid; | ||
| 1774 | struct cifsTconInfo *tcon; | ||
| 1775 | |||
| 1776 | tcon = cifs_find_tcon(ses, volume_info->UNC); | ||
| 1777 | if (tcon) { | ||
| 1778 | cFYI(1, "Found match on UNC path"); | ||
| 1779 | /* existing tcon already has a reference */ | ||
| 1780 | cifs_put_smb_ses(ses); | ||
| 1781 | if (tcon->seal != volume_info->seal) | ||
| 1782 | cERROR(1, "transport encryption setting " | ||
| 1783 | "conflicts with existing tid"); | ||
| 1784 | return tcon; | ||
| 1785 | } | ||
| 1786 | |||
| 1787 | tcon = tconInfoAlloc(); | ||
| 1788 | if (tcon == NULL) { | ||
| 1789 | rc = -ENOMEM; | ||
| 1790 | goto out_fail; | ||
| 1791 | } | ||
| 1792 | |||
| 1793 | tcon->ses = ses; | ||
| 1794 | if (volume_info->password) { | ||
| 1795 | tcon->password = kstrdup(volume_info->password, GFP_KERNEL); | ||
| 1796 | if (!tcon->password) { | ||
| 1797 | rc = -ENOMEM; | ||
| 1798 | goto out_fail; | ||
| 1799 | } | ||
| 1800 | } | ||
| 1801 | |||
| 1802 | if (strchr(volume_info->UNC + 3, '\\') == NULL | ||
| 1803 | && strchr(volume_info->UNC + 3, '/') == NULL) { | ||
| 1804 | cERROR(1, "Missing share name"); | ||
| 1805 | rc = -ENODEV; | ||
| 1806 | goto out_fail; | ||
| 1807 | } | ||
| 1808 | |||
| 1809 | /* BB Do we need to wrap session_mutex around | ||
| 1810 | * this TCon call and Unix SetFS as | ||
| 1811 | * we do on SessSetup and reconnect? */ | ||
| 1812 | xid = GetXid(); | ||
| 1813 | rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls); | ||
| 1814 | FreeXid(xid); | ||
| 1815 | cFYI(1, "CIFS Tcon rc = %d", rc); | ||
| 1816 | if (rc) | ||
| 1817 | goto out_fail; | ||
| 1818 | |||
| 1819 | if (volume_info->nodfs) { | ||
| 1820 | tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; | ||
| 1821 | cFYI(1, "DFS disabled (%d)", tcon->Flags); | ||
| 1822 | } | ||
| 1823 | tcon->seal = volume_info->seal; | ||
| 1824 | /* we can have only one retry value for a connection | ||
| 1825 | to a share so for resources mounted more than once | ||
| 1826 | to the same server share the last value passed in | ||
| 1827 | for the retry flag is used */ | ||
| 1828 | tcon->retry = volume_info->retry; | ||
| 1829 | tcon->nocase = volume_info->nocase; | ||
| 1830 | tcon->local_lease = volume_info->local_lease; | ||
| 1831 | |||
| 1832 | write_lock(&cifs_tcp_ses_lock); | ||
| 1833 | list_add(&tcon->tcon_list, &ses->tcon_list); | ||
| 1834 | write_unlock(&cifs_tcp_ses_lock); | ||
| 1835 | |||
| 1836 | return tcon; | ||
| 1837 | |||
| 1838 | out_fail: | ||
| 1839 | tconInfoFree(tcon); | ||
| 1840 | return ERR_PTR(rc); | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | |||
| 1769 | int | 1844 | int |
| 1770 | get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, | 1845 | get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, |
| 1771 | const struct nls_table *nls_codepage, unsigned int *pnum_referrals, | 1846 | const struct nls_table *nls_codepage, unsigned int *pnum_referrals, |
| @@ -2471,81 +2546,22 @@ try_mount_again: | |||
| 2471 | goto mount_fail_check; | 2546 | goto mount_fail_check; |
| 2472 | } | 2547 | } |
| 2473 | 2548 | ||
| 2474 | /* search for existing tcon to this server share */ | 2549 | setup_cifs_sb(volume_info, cifs_sb); |
| 2475 | if (!rc) { | 2550 | if (pSesInfo->capabilities & CAP_LARGE_FILES) |
| 2476 | setup_cifs_sb(volume_info, cifs_sb); | 2551 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
| 2477 | 2552 | else | |
| 2478 | tcon = cifs_find_tcon(pSesInfo, volume_info->UNC); | 2553 | sb->s_maxbytes = MAX_NON_LFS; |
| 2479 | if (tcon) { | ||
| 2480 | cFYI(1, "Found match on UNC path"); | ||
| 2481 | /* existing tcon already has a reference */ | ||
| 2482 | cifs_put_smb_ses(pSesInfo); | ||
| 2483 | if (tcon->seal != volume_info->seal) | ||
| 2484 | cERROR(1, "transport encryption setting " | ||
| 2485 | "conflicts with existing tid"); | ||
| 2486 | } else { | ||
| 2487 | tcon = tconInfoAlloc(); | ||
| 2488 | if (tcon == NULL) { | ||
| 2489 | rc = -ENOMEM; | ||
| 2490 | goto mount_fail_check; | ||
| 2491 | } | ||
| 2492 | |||
| 2493 | tcon->ses = pSesInfo; | ||
| 2494 | if (volume_info->password) { | ||
| 2495 | tcon->password = kstrdup(volume_info->password, | ||
| 2496 | GFP_KERNEL); | ||
| 2497 | if (!tcon->password) { | ||
| 2498 | rc = -ENOMEM; | ||
| 2499 | goto mount_fail_check; | ||
| 2500 | } | ||
| 2501 | } | ||
| 2502 | |||
| 2503 | if ((strchr(volume_info->UNC + 3, '\\') == NULL) | ||
| 2504 | && (strchr(volume_info->UNC + 3, '/') == NULL)) { | ||
| 2505 | cERROR(1, "Missing share name"); | ||
| 2506 | rc = -ENODEV; | ||
| 2507 | goto mount_fail_check; | ||
| 2508 | } else { | ||
| 2509 | /* BB Do we need to wrap sesSem around | ||
| 2510 | * this TCon call and Unix SetFS as | ||
| 2511 | * we do on SessSetup and reconnect? */ | ||
| 2512 | rc = CIFSTCon(xid, pSesInfo, volume_info->UNC, | ||
| 2513 | tcon, cifs_sb->local_nls); | ||
| 2514 | cFYI(1, "CIFS Tcon rc = %d", rc); | ||
| 2515 | if (volume_info->nodfs) { | ||
| 2516 | tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; | ||
| 2517 | cFYI(1, "DFS disabled (%d)", | ||
| 2518 | tcon->Flags); | ||
| 2519 | } | ||
| 2520 | } | ||
| 2521 | if (rc) | ||
| 2522 | goto remote_path_check; | ||
| 2523 | tcon->seal = volume_info->seal; | ||
| 2524 | write_lock(&cifs_tcp_ses_lock); | ||
| 2525 | list_add(&tcon->tcon_list, &pSesInfo->tcon_list); | ||
| 2526 | write_unlock(&cifs_tcp_ses_lock); | ||
| 2527 | } | ||
| 2528 | |||
| 2529 | /* we can have only one retry value for a connection | ||
| 2530 | to a share so for resources mounted more than once | ||
| 2531 | to the same server share the last value passed in | ||
| 2532 | for the retry flag is used */ | ||
| 2533 | tcon->retry = volume_info->retry; | ||
| 2534 | tcon->nocase = volume_info->nocase; | ||
| 2535 | tcon->local_lease = volume_info->local_lease; | ||
| 2536 | } | ||
| 2537 | if (pSesInfo) { | ||
| 2538 | if (pSesInfo->capabilities & CAP_LARGE_FILES) | ||
| 2539 | sb->s_maxbytes = MAX_LFS_FILESIZE; | ||
| 2540 | else | ||
| 2541 | sb->s_maxbytes = MAX_NON_LFS; | ||
| 2542 | } | ||
| 2543 | 2554 | ||
| 2544 | /* BB FIXME fix time_gran to be larger for LANMAN sessions */ | 2555 | /* BB FIXME fix time_gran to be larger for LANMAN sessions */ |
| 2545 | sb->s_time_gran = 100; | 2556 | sb->s_time_gran = 100; |
| 2546 | 2557 | ||
| 2547 | if (rc) | 2558 | /* search for existing tcon to this server share */ |
| 2559 | tcon = cifs_get_tcon(pSesInfo, volume_info); | ||
| 2560 | if (IS_ERR(tcon)) { | ||
| 2561 | rc = PTR_ERR(tcon); | ||
| 2562 | tcon = NULL; | ||
| 2548 | goto remote_path_check; | 2563 | goto remote_path_check; |
| 2564 | } | ||
| 2549 | 2565 | ||
| 2550 | cifs_sb->tcon = tcon; | 2566 | cifs_sb->tcon = tcon; |
| 2551 | 2567 | ||
