mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 09:31:50 +00:00
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>
This commit is contained in:
parent
36988c76f0
commit
d00c28de55
@ -1749,6 +1749,7 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
|
||||
int xid;
|
||||
struct cifsSesInfo *ses = tcon->ses;
|
||||
|
||||
cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
|
||||
write_lock(&cifs_tcp_ses_lock);
|
||||
if (--tcon->tc_count > 0) {
|
||||
write_unlock(&cifs_tcp_ses_lock);
|
||||
@ -1766,6 +1767,80 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
|
||||
cifs_put_smb_ses(ses);
|
||||
}
|
||||
|
||||
static struct cifsTconInfo *
|
||||
cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
|
||||
{
|
||||
int rc, xid;
|
||||
struct cifsTconInfo *tcon;
|
||||
|
||||
tcon = cifs_find_tcon(ses, volume_info->UNC);
|
||||
if (tcon) {
|
||||
cFYI(1, "Found match on UNC path");
|
||||
/* existing tcon already has a reference */
|
||||
cifs_put_smb_ses(ses);
|
||||
if (tcon->seal != volume_info->seal)
|
||||
cERROR(1, "transport encryption setting "
|
||||
"conflicts with existing tid");
|
||||
return tcon;
|
||||
}
|
||||
|
||||
tcon = tconInfoAlloc();
|
||||
if (tcon == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
tcon->ses = ses;
|
||||
if (volume_info->password) {
|
||||
tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
|
||||
if (!tcon->password) {
|
||||
rc = -ENOMEM;
|
||||
goto out_fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr(volume_info->UNC + 3, '\\') == NULL
|
||||
&& strchr(volume_info->UNC + 3, '/') == NULL) {
|
||||
cERROR(1, "Missing share name");
|
||||
rc = -ENODEV;
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
/* BB Do we need to wrap session_mutex around
|
||||
* this TCon call and Unix SetFS as
|
||||
* we do on SessSetup and reconnect? */
|
||||
xid = GetXid();
|
||||
rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
|
||||
FreeXid(xid);
|
||||
cFYI(1, "CIFS Tcon rc = %d", rc);
|
||||
if (rc)
|
||||
goto out_fail;
|
||||
|
||||
if (volume_info->nodfs) {
|
||||
tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
|
||||
cFYI(1, "DFS disabled (%d)", tcon->Flags);
|
||||
}
|
||||
tcon->seal = volume_info->seal;
|
||||
/* we can have only one retry value for a connection
|
||||
to a share so for resources mounted more than once
|
||||
to the same server share the last value passed in
|
||||
for the retry flag is used */
|
||||
tcon->retry = volume_info->retry;
|
||||
tcon->nocase = volume_info->nocase;
|
||||
tcon->local_lease = volume_info->local_lease;
|
||||
|
||||
write_lock(&cifs_tcp_ses_lock);
|
||||
list_add(&tcon->tcon_list, &ses->tcon_list);
|
||||
write_unlock(&cifs_tcp_ses_lock);
|
||||
|
||||
return tcon;
|
||||
|
||||
out_fail:
|
||||
tconInfoFree(tcon);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
|
||||
const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
|
||||
@ -2471,81 +2546,22 @@ try_mount_again:
|
||||
goto mount_fail_check;
|
||||
}
|
||||
|
||||
/* search for existing tcon to this server share */
|
||||
if (!rc) {
|
||||
setup_cifs_sb(volume_info, cifs_sb);
|
||||
|
||||
tcon = cifs_find_tcon(pSesInfo, volume_info->UNC);
|
||||
if (tcon) {
|
||||
cFYI(1, "Found match on UNC path");
|
||||
/* existing tcon already has a reference */
|
||||
cifs_put_smb_ses(pSesInfo);
|
||||
if (tcon->seal != volume_info->seal)
|
||||
cERROR(1, "transport encryption setting "
|
||||
"conflicts with existing tid");
|
||||
} else {
|
||||
tcon = tconInfoAlloc();
|
||||
if (tcon == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto mount_fail_check;
|
||||
}
|
||||
|
||||
tcon->ses = pSesInfo;
|
||||
if (volume_info->password) {
|
||||
tcon->password = kstrdup(volume_info->password,
|
||||
GFP_KERNEL);
|
||||
if (!tcon->password) {
|
||||
rc = -ENOMEM;
|
||||
goto mount_fail_check;
|
||||
}
|
||||
}
|
||||
|
||||
if ((strchr(volume_info->UNC + 3, '\\') == NULL)
|
||||
&& (strchr(volume_info->UNC + 3, '/') == NULL)) {
|
||||
cERROR(1, "Missing share name");
|
||||
rc = -ENODEV;
|
||||
goto mount_fail_check;
|
||||
} else {
|
||||
/* BB Do we need to wrap sesSem around
|
||||
* this TCon call and Unix SetFS as
|
||||
* we do on SessSetup and reconnect? */
|
||||
rc = CIFSTCon(xid, pSesInfo, volume_info->UNC,
|
||||
tcon, cifs_sb->local_nls);
|
||||
cFYI(1, "CIFS Tcon rc = %d", rc);
|
||||
if (volume_info->nodfs) {
|
||||
tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
|
||||
cFYI(1, "DFS disabled (%d)",
|
||||
tcon->Flags);
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
goto remote_path_check;
|
||||
tcon->seal = volume_info->seal;
|
||||
write_lock(&cifs_tcp_ses_lock);
|
||||
list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
|
||||
write_unlock(&cifs_tcp_ses_lock);
|
||||
}
|
||||
|
||||
/* we can have only one retry value for a connection
|
||||
to a share so for resources mounted more than once
|
||||
to the same server share the last value passed in
|
||||
for the retry flag is used */
|
||||
tcon->retry = volume_info->retry;
|
||||
tcon->nocase = volume_info->nocase;
|
||||
tcon->local_lease = volume_info->local_lease;
|
||||
}
|
||||
if (pSesInfo) {
|
||||
if (pSesInfo->capabilities & CAP_LARGE_FILES)
|
||||
sb->s_maxbytes = MAX_LFS_FILESIZE;
|
||||
else
|
||||
sb->s_maxbytes = MAX_NON_LFS;
|
||||
}
|
||||
setup_cifs_sb(volume_info, cifs_sb);
|
||||
if (pSesInfo->capabilities & CAP_LARGE_FILES)
|
||||
sb->s_maxbytes = MAX_LFS_FILESIZE;
|
||||
else
|
||||
sb->s_maxbytes = MAX_NON_LFS;
|
||||
|
||||
/* BB FIXME fix time_gran to be larger for LANMAN sessions */
|
||||
sb->s_time_gran = 100;
|
||||
|
||||
if (rc)
|
||||
/* search for existing tcon to this server share */
|
||||
tcon = cifs_get_tcon(pSesInfo, volume_info);
|
||||
if (IS_ERR(tcon)) {
|
||||
rc = PTR_ERR(tcon);
|
||||
tcon = NULL;
|
||||
goto remote_path_check;
|
||||
}
|
||||
|
||||
cifs_sb->tcon = tcon;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user