Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 190945
b: refs/heads/master
c: 36988c7
h: refs/heads/master
i:
  190943: 3ccd928
v: v3
  • Loading branch information
Jeff Layton authored and Steve French committed Apr 26, 2010
1 parent 3c3647d commit b97218b
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 66 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a5fc4ce01867842f6a9cc317035df3081302bffc
refs/heads/master: 36988c76f007738cad5fe1c873a5fb0cda7eb2f6
158 changes: 93 additions & 65 deletions trunk/fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
{
Expand Down Expand Up @@ -2376,71 +2463,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
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 */
Expand Down

0 comments on commit b97218b

Please sign in to comment.