cifs: Avoid umount hangs with smb2 when server is unresponsive

Do not send SMB2 Logoff command when reconnecting, the way smb1
code base works.

Also, no need to wait for a credit for an echo command when one is already
in flight.

Without these changes, umount command hangs if the server is unresponsive
e.g. hibernating.

Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@us.ibm.com>
This commit is contained in:
Shirish Pargaonkar 2013-10-03 05:44:45 -05:00 committed by Steve French
parent c31f330719
commit eb4c7df6c2
2 changed files with 13 additions and 2 deletions

View File

@ -687,6 +687,10 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
else else
return -EIO; return -EIO;
/* no need to send SMB logoff if uid already closed due to reconnect */
if (ses->need_reconnect)
goto smb2_session_already_dead;
rc = small_smb2_init(SMB2_LOGOFF, NULL, (void **) &req); rc = small_smb2_init(SMB2_LOGOFF, NULL, (void **) &req);
if (rc) if (rc)
return rc; return rc;
@ -701,6 +705,8 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
* No tcon so can't do * No tcon so can't do
* cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]); * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]);
*/ */
smb2_session_already_dead:
return rc; return rc;
} }

View File

@ -410,8 +410,13 @@ static int
wait_for_free_request(struct TCP_Server_Info *server, const int timeout, wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
const int optype) const int optype)
{ {
return wait_for_free_credits(server, timeout, int *val;
server->ops->get_credits_field(server, optype));
val = server->ops->get_credits_field(server, optype);
/* Since an echo is already inflight, no need to wait to send another */
if (*val <= 0 && optype == CIFS_ECHO_OP)
return -EAGAIN;
return wait_for_free_credits(server, timeout, val);
} }
static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf, static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,