From 2e13456fb3d3e5f462dc1e59efc04eb62df35566 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 21 Jul 2017 10:48:13 -0400 Subject: nbd: allow multiple disconnects to be sent There's no reason to limit ourselves to one disconnect message per socket. Sometimes networks do strange things, might as well let sysadmins hit the panic button as much as they want. Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/block/nbd.c') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 87a0a29f6e7e..f91e7ac3fa32 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -991,9 +991,8 @@ static int nbd_disconnect(struct nbd_device *nbd) struct nbd_config *config = nbd->config; dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n"); - if (!test_and_set_bit(NBD_DISCONNECT_REQUESTED, - &config->runtime_flags)) - send_disconnects(nbd); + set_bit(NBD_DISCONNECT_REQUESTED, &config->runtime_flags); + send_disconnects(nbd); return 0; } -- cgit v1.2.3 From b4b2aeccf0f0fa1fd356cc72eeda7a2c66c39904 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 21 Jul 2017 10:48:14 -0400 Subject: nbd: take tx_lock before disconnecting We need to take the tx_lock so we don't interleave our disconnect request between real data going down the wire. Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/block/nbd.c') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index f91e7ac3fa32..6aefe9fca6ce 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -978,11 +978,15 @@ static void send_disconnects(struct nbd_device *nbd) int i, ret; for (i = 0; i < config->num_connections; i++) { + struct nbd_sock *nsock = config->socks[i]; + iov_iter_kvec(&from, WRITE | ITER_KVEC, &iov, 1, sizeof(request)); + mutex_lock(&nsock->tx_lock); ret = sock_xmit(nbd, i, 1, &from, 0, NULL); if (ret <= 0) dev_err(disk_to_dev(nbd->disk), "Send disconnect failed %d\n", ret); + mutex_unlock(&nsock->tx_lock); } } -- cgit v1.2.3 From a7ee8cf190ecc8f118f0b7839912564117524d85 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 21 Jul 2017 10:48:15 -0400 Subject: nbd: only set sndtimeo if we have a timeout set A user reported that he was getting immediate disconnects with my sndtimeo patch applied. This is because by default the OSS nbd client doesn't set a timeout, so we end up setting the sndtimeo to 0, which of course means we have send errors a lot. Instead only set our sndtimeo if the user specified a timeout, otherwise we'll just wait forever like we did previously. Fixes: dc88e34d69d8 ("nbd: set sk->sk_sndtimeo for our sockets") Reported-by: Adam Borowski Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/block/nbd.c') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 6aefe9fca6ce..64b19b10b739 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -908,7 +908,8 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) continue; } sk_set_memalloc(sock->sk); - sock->sk->sk_sndtimeo = nbd->tag_set.timeout; + if (nbd->tag_set.timeout) + sock->sk->sk_sndtimeo = nbd->tag_set.timeout; atomic_inc(&config->recv_threads); refcount_inc(&nbd->config_refs); old = nsock->sock; @@ -1077,7 +1078,9 @@ static int nbd_start_device(struct nbd_device *nbd) return -ENOMEM; } sk_set_memalloc(config->socks[i]->sock->sk); - config->socks[i]->sock->sk->sk_sndtimeo = nbd->tag_set.timeout; + if (nbd->tag_set.timeout) + config->socks[i]->sock->sk->sk_sndtimeo = + nbd->tag_set.timeout; atomic_inc(&config->recv_threads); refcount_inc(&nbd->config_refs); INIT_WORK(&args->work, recv_work); -- cgit v1.2.3 From 7a362ea96d0df873397be04f4556e92f7e37c5ec Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Tue, 25 Jul 2017 13:31:19 -0400 Subject: nbd: clear disconnected on reconnect If our device loses its connection for longer than the dead timeout we will set NBD_DISCONNECTED in order to quickly fail any pending IO's that flood in after the IO's that were waiting during the dead timer. However if we re-connect at some point in the future we'll still see this DISCONNECTED flag set if we then lose our connection again after that, which means we won't get notifications for our newly lost connections. Fix this by just clearing the DISCONNECTED flag on reconnect in order to make sure everything works as it's supposed to. Reported-by: Dan Melnic Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/block/nbd.c') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 64b19b10b739..5bdf923294a5 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -923,6 +923,8 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) mutex_unlock(&nsock->tx_lock); sockfd_put(old); + clear_bit(NBD_DISCONNECTED, &config->runtime_flags); + /* We take the tx_mutex in an error path in the recv_work, so we * need to queue_work outside of the tx_mutex. */ -- cgit v1.2.3