forked from Minki/linux
cifs: move SMB session creation code into separate function
...it's mostly part of cifs_mount. Break it out into a separate function. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
a5fc4ce018
commit
36988c76f0
@ -1616,6 +1616,7 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
|
||||
int xid;
|
||||
struct TCP_Server_Info *server = ses->server;
|
||||
|
||||
cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
|
||||
write_lock(&cifs_tcp_ses_lock);
|
||||
if (--ses->ses_count > 0) {
|
||||
write_unlock(&cifs_tcp_ses_lock);
|
||||
@ -1634,6 +1635,92 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
|
||||
cifs_put_tcp_session(server);
|
||||
}
|
||||
|
||||
static struct cifsSesInfo *
|
||||
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
|
||||
{
|
||||
int rc = -ENOMEM, xid;
|
||||
struct cifsSesInfo *ses;
|
||||
|
||||
xid = GetXid();
|
||||
|
||||
ses = cifs_find_smb_ses(server, volume_info->username);
|
||||
if (ses) {
|
||||
cFYI(1, "Existing smb sess found (status=%d)", ses->status);
|
||||
|
||||
/* existing SMB ses has a server reference already */
|
||||
cifs_put_tcp_session(server);
|
||||
|
||||
mutex_lock(&ses->session_mutex);
|
||||
if (ses->need_reconnect) {
|
||||
cFYI(1, "Session needs reconnect");
|
||||
rc = cifs_setup_session(xid, ses,
|
||||
volume_info->local_nls);
|
||||
if (rc) {
|
||||
mutex_unlock(&ses->session_mutex);
|
||||
/* problem -- put our reference */
|
||||
cifs_put_smb_ses(ses);
|
||||
FreeXid(xid);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ses->session_mutex);
|
||||
FreeXid(xid);
|
||||
return ses;
|
||||
}
|
||||
|
||||
cFYI(1, "Existing smb sess not found");
|
||||
ses = sesInfoAlloc();
|
||||
if (ses == NULL)
|
||||
goto get_ses_fail;
|
||||
|
||||
/* new SMB session uses our server ref */
|
||||
ses->server = server;
|
||||
if (server->addr.sockAddr6.sin6_family == AF_INET6)
|
||||
sprintf(ses->serverName, "%pI6",
|
||||
&server->addr.sockAddr6.sin6_addr);
|
||||
else
|
||||
sprintf(ses->serverName, "%pI4",
|
||||
&server->addr.sockAddr.sin_addr.s_addr);
|
||||
|
||||
if (volume_info->username)
|
||||
strncpy(ses->userName, volume_info->username,
|
||||
MAX_USERNAME_SIZE);
|
||||
|
||||
/* volume_info->password freed at unmount */
|
||||
if (volume_info->password) {
|
||||
ses->password = kstrdup(volume_info->password, GFP_KERNEL);
|
||||
if (!ses->password)
|
||||
goto get_ses_fail;
|
||||
}
|
||||
if (volume_info->domainname) {
|
||||
int len = strlen(volume_info->domainname);
|
||||
ses->domainName = kmalloc(len + 1, GFP_KERNEL);
|
||||
if (ses->domainName)
|
||||
strcpy(ses->domainName, volume_info->domainname);
|
||||
}
|
||||
ses->linux_uid = volume_info->linux_uid;
|
||||
ses->overrideSecFlg = volume_info->secFlg;
|
||||
|
||||
mutex_lock(&ses->session_mutex);
|
||||
rc = cifs_setup_session(xid, ses, volume_info->local_nls);
|
||||
mutex_unlock(&ses->session_mutex);
|
||||
if (rc)
|
||||
goto get_ses_fail;
|
||||
|
||||
/* success, put it on the list */
|
||||
write_lock(&cifs_tcp_ses_lock);
|
||||
list_add(&ses->smb_ses_list, &server->smb_ses_list);
|
||||
write_unlock(&cifs_tcp_ses_lock);
|
||||
|
||||
FreeXid(xid);
|
||||
return ses;
|
||||
|
||||
get_ses_fail:
|
||||
sesInfoFree(ses);
|
||||
FreeXid(xid);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
static struct cifsTconInfo *
|
||||
cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
|
||||
{
|
||||
@ -2376,71 +2463,12 @@ try_mount_again:
|
||||
goto out;
|
||||
}
|
||||
|
||||
pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username);
|
||||
if (pSesInfo) {
|
||||
cFYI(1, "Existing smb sess found (status=%d)",
|
||||
pSesInfo->status);
|
||||
/*
|
||||
* The existing SMB session already has a reference to srvTcp,
|
||||
* so we can put back the extra one we got before
|
||||
*/
|
||||
cifs_put_tcp_session(srvTcp);
|
||||
|
||||
mutex_lock(&pSesInfo->session_mutex);
|
||||
if (pSesInfo->need_reconnect) {
|
||||
cFYI(1, "Session needs reconnect");
|
||||
rc = cifs_setup_session(xid, pSesInfo,
|
||||
cifs_sb->local_nls);
|
||||
}
|
||||
mutex_unlock(&pSesInfo->session_mutex);
|
||||
} else if (!rc) {
|
||||
cFYI(1, "Existing smb sess not found");
|
||||
pSesInfo = sesInfoAlloc();
|
||||
if (pSesInfo == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto mount_fail_check;
|
||||
}
|
||||
|
||||
/* new SMB session uses our srvTcp ref */
|
||||
pSesInfo->server = srvTcp;
|
||||
if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6)
|
||||
sprintf(pSesInfo->serverName, "%pI6",
|
||||
&srvTcp->addr.sockAddr6.sin6_addr);
|
||||
else
|
||||
sprintf(pSesInfo->serverName, "%pI4",
|
||||
&srvTcp->addr.sockAddr.sin_addr.s_addr);
|
||||
|
||||
write_lock(&cifs_tcp_ses_lock);
|
||||
list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
|
||||
write_unlock(&cifs_tcp_ses_lock);
|
||||
|
||||
/* volume_info->password freed at unmount */
|
||||
if (volume_info->password) {
|
||||
pSesInfo->password = kstrdup(volume_info->password,
|
||||
GFP_KERNEL);
|
||||
if (!pSesInfo->password) {
|
||||
rc = -ENOMEM;
|
||||
goto mount_fail_check;
|
||||
}
|
||||
}
|
||||
if (volume_info->username)
|
||||
strncpy(pSesInfo->userName, volume_info->username,
|
||||
MAX_USERNAME_SIZE);
|
||||
if (volume_info->domainname) {
|
||||
int len = strlen(volume_info->domainname);
|
||||
pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
|
||||
if (pSesInfo->domainName)
|
||||
strcpy(pSesInfo->domainName,
|
||||
volume_info->domainname);
|
||||
}
|
||||
pSesInfo->linux_uid = volume_info->linux_uid;
|
||||
pSesInfo->overrideSecFlg = volume_info->secFlg;
|
||||
mutex_lock(&pSesInfo->session_mutex);
|
||||
|
||||
/* BB FIXME need to pass vol->secFlgs BB */
|
||||
rc = cifs_setup_session(xid, pSesInfo,
|
||||
cifs_sb->local_nls);
|
||||
mutex_unlock(&pSesInfo->session_mutex);
|
||||
/* get a reference to a SMB session */
|
||||
pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
|
||||
if (IS_ERR(pSesInfo)) {
|
||||
rc = PTR_ERR(pSesInfo);
|
||||
pSesInfo = NULL;
|
||||
goto mount_fail_check;
|
||||
}
|
||||
|
||||
/* search for existing tcon to this server share */
|
||||
|
Loading…
Reference in New Issue
Block a user