nbd: enable replace socket if only one connection is configured

Nbd server with multiple connections could be upgraded since
560bc4b (nbd: handle dead connections). But if only one conncection
is configured, after we take down nbd server, all inflight IO
would finally timeout and return error. We could requeue them
like what we do with multiple connections and wait for new socket
in submit path.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Hou Pu <houpu@bytedance.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Hou Pu 2020-02-28 01:40:29 -05:00 коммит произвёл Jens Axboe
Родитель 91dfa2dd81
Коммит d970958b2d
1 изменённых файлов: 9 добавлений и 8 удалений

Просмотреть файл

@ -395,16 +395,19 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
} }
config = nbd->config; config = nbd->config;
if (config->num_connections > 1) { if (config->num_connections > 1 ||
(config->num_connections == 1 && nbd->tag_set.timeout)) {
dev_err_ratelimited(nbd_to_dev(nbd), dev_err_ratelimited(nbd_to_dev(nbd),
"Connection timed out, retrying (%d/%d alive)\n", "Connection timed out, retrying (%d/%d alive)\n",
atomic_read(&config->live_connections), atomic_read(&config->live_connections),
config->num_connections); config->num_connections);
/* /*
* Hooray we have more connections, requeue this IO, the submit * Hooray we have more connections, requeue this IO, the submit
* path will put it on a real connection. * path will put it on a real connection. Or if only one
* connection is configured, the submit path will wait util
* a new connection is reconfigured or util dead timeout.
*/ */
if (config->socks && config->num_connections > 1) { if (config->socks) {
if (cmd->index < config->num_connections) { if (cmd->index < config->num_connections) {
struct nbd_sock *nsock = struct nbd_sock *nsock =
config->socks[cmd->index]; config->socks[cmd->index];
@ -741,14 +744,12 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n", dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n",
result); result);
/* /*
* If we've disconnected or we only have 1 * If we've disconnected, we need to make sure we
* connection then we need to make sure we
* complete this request, otherwise error out * complete this request, otherwise error out
* and let the timeout stuff handle resubmitting * and let the timeout stuff handle resubmitting
* this request onto another connection. * this request onto another connection.
*/ */
if (nbd_disconnected(config) || if (nbd_disconnected(config)) {
config->num_connections <= 1) {
cmd->status = BLK_STS_IOERR; cmd->status = BLK_STS_IOERR;
goto out; goto out;
} }
@ -825,7 +826,7 @@ static int find_fallback(struct nbd_device *nbd, int index)
if (config->num_connections <= 1) { if (config->num_connections <= 1) {
dev_err_ratelimited(disk_to_dev(nbd->disk), dev_err_ratelimited(disk_to_dev(nbd->disk),
"Attempted send on invalid socket\n"); "Dead connection, failed to find a fallback\n");
return new_index; return new_index;
} }