Skip to content

Commit

Permalink
cifs: break negotiate protocol calls out of cifs_setup_session
Browse files Browse the repository at this point in the history
So that we can reasonably set up the secType based on both the
NegotiateProtocol response and the parsed mount options.

Signed-off-by: Jeff Layton <[email protected]>
Signed-off-by: Steve French <[email protected]>
  • Loading branch information
jtlayton authored and Steve French committed May 5, 2010
1 parent ebe6aa5 commit 198b568
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 33 deletions.
4 changes: 3 additions & 1 deletion fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ extern void cifs_dfs_release_automount_timer(void);
void cifs_proc_init(void);
void cifs_proc_clean(void);

extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
extern int cifs_negotiate_protocol(unsigned int xid,
struct cifsSesInfo *ses);
extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
struct nls_table *nls_info);
extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);

Expand Down
3 changes: 2 additions & 1 deletion fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
* reconnect the same SMB session
*/
mutex_lock(&ses->session_mutex);
if (ses->need_reconnect)
rc = cifs_negotiate_protocol(0, ses);
if (rc == 0 && ses->need_reconnect)
rc = cifs_setup_session(0, ses, nls_codepage);

/* do we need to reconnect tcon? */
Expand Down
78 changes: 47 additions & 31 deletions fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1651,6 +1651,14 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
cifs_put_tcp_session(server);

mutex_lock(&ses->session_mutex);
rc = cifs_negotiate_protocol(xid, ses);
if (rc) {
mutex_unlock(&ses->session_mutex);
/* problem -- put our ses reference */
cifs_put_smb_ses(ses);
FreeXid(xid);
return ERR_PTR(rc);
}
if (ses->need_reconnect) {
cFYI(1, "Session needs reconnect");
rc = cifs_setup_session(xid, ses,
Expand Down Expand Up @@ -1702,7 +1710,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
ses->overrideSecFlg = volume_info->secFlg;

mutex_lock(&ses->session_mutex);
rc = cifs_setup_session(xid, ses, volume_info->local_nls);
rc = cifs_negotiate_protocol(xid, ses);
if (!rc)
rc = cifs_setup_session(xid, ses, volume_info->local_nls);
mutex_unlock(&ses->session_mutex);
if (rc)
goto get_ses_fail;
Expand Down Expand Up @@ -2874,55 +2884,61 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
return rc;
}

int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
struct nls_table *nls_info)
int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
{
int rc = 0;
struct TCP_Server_Info *server = pSesInfo->server;

/* what if server changes its buffer size after dropping the session? */
if (server->maxBuf == 0) /* no need to send on reconnect */ {
rc = CIFSSMBNegotiate(xid, pSesInfo);
if (rc == -EAGAIN) {
/* retry only once on 1st time connection */
rc = CIFSSMBNegotiate(xid, pSesInfo);
if (rc == -EAGAIN)
rc = -EHOSTDOWN;
}
if (rc == 0) {
spin_lock(&GlobalMid_Lock);
if (server->tcpStatus != CifsExiting)
server->tcpStatus = CifsGood;
else
rc = -EHOSTDOWN;
spin_unlock(&GlobalMid_Lock);
struct TCP_Server_Info *server = ses->server;

}
/* only send once per connect */
if (server->maxBuf != 0)
return 0;

rc = CIFSSMBNegotiate(xid, ses);
if (rc == -EAGAIN) {
/* retry only once on 1st time connection */
rc = CIFSSMBNegotiate(xid, ses);
if (rc == -EAGAIN)
rc = -EHOSTDOWN;
}
if (rc == 0) {
spin_lock(&GlobalMid_Lock);
if (server->tcpStatus != CifsExiting)
server->tcpStatus = CifsGood;
else
rc = -EHOSTDOWN;
spin_unlock(&GlobalMid_Lock);

if (rc)
goto ss_err_exit;
}

return rc;
}


int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
struct nls_table *nls_info)
{
int rc = 0;
struct TCP_Server_Info *server = ses->server;

pSesInfo->flags = 0;
pSesInfo->capabilities = server->capabilities;
ses->flags = 0;
ses->capabilities = server->capabilities;
if (linuxExtEnabled == 0)
pSesInfo->capabilities &= (~CAP_UNIX);
ses->capabilities &= (~CAP_UNIX);

cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
server->secMode, server->capabilities, server->timeAdj);

rc = CIFS_SessSetup(xid, pSesInfo, nls_info);
rc = CIFS_SessSetup(xid, ses, nls_info);
if (rc) {
cERROR(1, "Send error in SessSetup = %d", rc);
} else {
cFYI(1, "CIFS Session Established successfully");
spin_lock(&GlobalMid_Lock);
pSesInfo->status = CifsGood;
pSesInfo->need_reconnect = false;
ses->status = CifsGood;
ses->need_reconnect = false;
spin_unlock(&GlobalMid_Lock);
}

ss_err_exit:
return rc;
}

0 comments on commit 198b568

Please sign in to comment.