mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
smb: client: fix hang in wait_for_response() for negproto
Call cifs_reconnect() to wake up processes waiting on negotiate protocol to handle the case where server abruptly shut down and had no chance to properly close the socket. Simple reproducer: ssh 192.168.2.100 pkill -STOP smbd mount.cifs //192.168.2.100/test /mnt -o ... [never returns] Cc: Rickard Andersson <rickaran@axis.com> Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
431c1646e1
commit
7ccc146546
@ -656,6 +656,19 @@ allocate_buffers(struct TCP_Server_Info *server)
|
|||||||
static bool
|
static bool
|
||||||
server_unresponsive(struct TCP_Server_Info *server)
|
server_unresponsive(struct TCP_Server_Info *server)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* If we're in the process of mounting a share or reconnecting a session
|
||||||
|
* and the server abruptly shut down (e.g. socket wasn't closed, packet
|
||||||
|
* had been ACK'ed but no SMB response), don't wait longer than 20s to
|
||||||
|
* negotiate protocol.
|
||||||
|
*/
|
||||||
|
spin_lock(&server->srv_lock);
|
||||||
|
if (server->tcpStatus == CifsInNegotiate &&
|
||||||
|
time_after(jiffies, server->lstrp + 20 * HZ)) {
|
||||||
|
spin_unlock(&server->srv_lock);
|
||||||
|
cifs_reconnect(server, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* We need to wait 3 echo intervals to make sure we handle such
|
* We need to wait 3 echo intervals to make sure we handle such
|
||||||
* situations right:
|
* situations right:
|
||||||
@ -667,7 +680,6 @@ server_unresponsive(struct TCP_Server_Info *server)
|
|||||||
* 65s kernel_recvmsg times out, and we see that we haven't gotten
|
* 65s kernel_recvmsg times out, and we see that we haven't gotten
|
||||||
* a response in >60s.
|
* a response in >60s.
|
||||||
*/
|
*/
|
||||||
spin_lock(&server->srv_lock);
|
|
||||||
if ((server->tcpStatus == CifsGood ||
|
if ((server->tcpStatus == CifsGood ||
|
||||||
server->tcpStatus == CifsNeedNegotiate) &&
|
server->tcpStatus == CifsNeedNegotiate) &&
|
||||||
(!server->ops->can_echo || server->ops->can_echo(server)) &&
|
(!server->ops->can_echo || server->ops->can_echo(server)) &&
|
||||||
|
Loading…
Reference in New Issue
Block a user