nbd: set sk->sk_sndtimeo for our sockets

If the nbd server stops receiving packets altogether we will get stuck
waiting for them to receive indefinitely as the tcp buffer will never
empty, which looks like a deadlock.  Fix this by setting the sk send
timeout to our configured timeout, that way if the server really
misbehaves we'll disconnect cleanly instead of waiting forever.

Reported-by: Dan Melnic <dmm@fb.com>
Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
Josef Bacik 2017-06-08 15:39:30 -04:00 committed by Jens Axboe
parent b040ad9cf6
commit dc88e34d69
1 changed files with 2 additions and 0 deletions

View File

@ -914,6 +914,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
continue; continue;
} }
sk_set_memalloc(sock->sk); sk_set_memalloc(sock->sk);
sock->sk->sk_sndtimeo = nbd->tag_set.timeout;
atomic_inc(&config->recv_threads); atomic_inc(&config->recv_threads);
refcount_inc(&nbd->config_refs); refcount_inc(&nbd->config_refs);
old = nsock->sock; old = nsock->sock;
@ -1083,6 +1084,7 @@ static int nbd_start_device(struct nbd_device *nbd)
return -ENOMEM; return -ENOMEM;
} }
sk_set_memalloc(config->socks[i]->sock->sk); sk_set_memalloc(config->socks[i]->sock->sk);
config->socks[i]->sock->sk->sk_sndtimeo = nbd->tag_set.timeout;
atomic_inc(&config->recv_threads); atomic_inc(&config->recv_threads);
refcount_inc(&nbd->config_refs); refcount_inc(&nbd->config_refs);
INIT_WORK(&args->work, recv_work); INIT_WORK(&args->work, recv_work);