diff options
author | Frederic Robra | 2019-11-08 13:33:30 +0100 |
---|---|---|
committer | Frederic Robra | 2019-11-08 13:33:30 +0100 |
commit | 6a3d9860253eb74817d98192156378e1edff618c (patch) | |
tree | 1994ce71f4a8c5a78ce463832bb9bdb847bde701 | |
parent | removed bug when sending and at the same time socket closes down (diff) | |
download | dnbd3-ng-6a3d9860253eb74817d98192156378e1edff618c.tar.gz dnbd3-ng-6a3d9860253eb74817d98192156378e1edff618c.tar.xz dnbd3-ng-6a3d9860253eb74817d98192156378e1edff618c.zip |
if connection is lost while connected modul now waits for new connection
-rw-r--r-- | src/kernel/mq.c | 46 | ||||
-rw-r--r-- | src/kernel/net-txrx.c | 9 | ||||
-rw-r--r-- | src/kernel/net.c | 14 |
3 files changed, 47 insertions, 22 deletions
diff --git a/src/kernel/mq.c b/src/kernel/mq.c index 5b480de..f859c0f 100644 --- a/src/kernel/mq.c +++ b/src/kernel/mq.c @@ -23,6 +23,7 @@ #include <linux/wait.h> #include <linux/blk-mq.h> +#include <linux/delay.h> /** * dnbd3_busy_iter - iterator to set a bit for busy reqeust @@ -81,10 +82,18 @@ static void dnbd3_busy_iter_requeue(struct request *req, void *priv, bool arg) { struct dnbd3_sock *sock = priv; struct dnbd3_cmd *cmd = blk_mq_rq_to_pdu(req); + if (&cmd->dnbd3->socks[cmd->index] != sock) { + return; + } if (!mutex_trylock(&cmd->lock)) { /* request is in sending, so we will not requeue */ return; } + if (!cmd->dnbd3->connected) { + dnbd3_end_cmd(cmd, BLK_STS_IOERR); + mutex_unlock(&cmd->lock); + return; + } debug_sock(sock, "requeue busy request %p", req); dnbd3_requeue_cmd(cmd); mutex_unlock(&cmd->lock); @@ -100,7 +109,21 @@ void dndb3_reque_busy_requests(struct dnbd3_sock *sock) blk_mq_tagset_busy_iter(set,(busy_tag_iter_fn *) dnbd3_busy_iter_requeue, sock); } - +static void dnbd3_wait_for_sockets(struct dnbd3_cmd * cmd) { + int i; + bool wait = true; + while (wait && cmd->dnbd3->connected) { + for (i = 0; i < cmd->dnbd3->number_connections; i++) { + if (dnbd3_is_sock_alive(cmd->dnbd3->socks[cmd->index])) { + wait = false; + } + if (wait && cmd->dnbd3->connected) { + debug("no socket alive sleeping"); + msleep(100); + } + } + } +} /** * dnbd3_requeue_cmd - requeue a command once @@ -109,7 +132,9 @@ void dndb3_reque_busy_requests(struct dnbd3_sock *sock) void dnbd3_requeue_cmd(struct dnbd3_cmd *cmd) { struct request *req = blk_mq_rq_from_pdu(cmd); - if (!cmd->requed && blk_queued_rq(req)) { + dnbd3_wait_for_sockets(cmd); + + if (!cmd->requed/* && blk_queued_rq(req)*/) { cmd->requed = true; blk_mq_requeue_request(req, true); } @@ -127,6 +152,11 @@ void dnbd3_end_cmd(struct dnbd3_cmd *cmd, blk_status_t error) } +void dnbd3_end_all_rq(struct dnbd3_device *dev) +{ + struct request_queue *q = dev->disk->queue; +} + /** * dnbd3_handle_cmd - handles a mq command * @cmd: the cmd to send @@ -143,20 +173,16 @@ static int dnbd3_handle_cmd(struct dnbd3_cmd *cmd, int index) // blk_rq_pos(req), blk_rq_bytes(req), index); - if (!dnbd3_is_sock_alive(*sock)) { -// warn_dev(dev, "attempted send on invalid socket %d", index); -// msleep(SOCKET_TIMEOUT_CLIENT_DATA * 1000); + if (!dev->socks || !dnbd3_is_sock_alive(*sock)) { if (dev->connected) { -// info_dev(dev, "reset request to new socket"); + info_dev(dev, "reset request to new socket"); dnbd3_requeue_cmd(cmd); - ret = 0; - goto out; + return 0; } else { error_dev(dev, "ending request device not connected"); dnbd3_end_cmd(cmd, BLK_STS_IOERR); - ret = -EIO; - goto out; + return -EIO; } } diff --git a/src/kernel/net-txrx.c b/src/kernel/net-txrx.c index 4ca3fa5..87a9169 100644 --- a/src/kernel/net-txrx.c +++ b/src/kernel/net-txrx.c @@ -163,6 +163,10 @@ int dnbd3_send_request(struct dnbd3_sock *sock, struct request *req, iov[0].iov_base = &request; iov[0].iov_len = sizeof(request); lng = iov_num == 1 ? iov[0].iov_len : iov[0].iov_len + iov[1].iov_len; + if (unlikely(!sock->sock)) { + warn_sock(sock, "socket was shutdown while sending"); + goto error; + } result = kernel_sendmsg(sock->sock, &msg, iov, iov_num, lng); if (result != lng) { error_sock(sock, "connection to server lost"); @@ -336,8 +340,11 @@ int dnbd3_receive_cmd_get_block_mq(struct dnbd3_sock *sock, if (!req || !blk_mq_request_started(req)) { error_sock(sock, "unexpected reply (%d) %p", tag, req); if (req) { + cmd = blk_mq_rq_to_pdu(req); + mutex_lock(&cmd->lock); debug_sock(sock, "requeue request"); - dnbd3_requeue_cmd(blk_mq_rq_to_pdu(req)); + dnbd3_requeue_cmd(cmd); + mutex_unlock(&cmd->lock); } dnbd3_clear_socket(sock, reply, remaining); return -EIO; diff --git a/src/kernel/net.c b/src/kernel/net.c index 801c15c..5f9846a 100644 --- a/src/kernel/net.c +++ b/src/kernel/net.c @@ -384,7 +384,7 @@ static void dnbd3_panic_worker(struct work_struct *work) mutex_lock(&dev->device_lock); if (dnbd3_adjust_connections(dev)) { error_dev(dev, "failed to connect to any server"); - dev->connected = false; +// dev->connected = false; } mutex_unlock(&dev->device_lock); @@ -584,7 +584,7 @@ static void dnbd3_discovery_worker(struct work_struct *work) mutex_lock(&dev->device_lock); if (dnbd3_adjust_connections(dev)) { error_dev(dev, "failed to connect to any server"); - dev->connected = false; +// dev->connected = false; } mutex_unlock(&dev->device_lock); @@ -836,14 +836,6 @@ int dnbd3_net_connect(struct dnbd3_device *dev) dev->timer.expires = jiffies + HZ; add_timer(&dev->timer); - // alt_server[0] is the initial server -// result = dnbd3_server_connect(dev, &dev->alt_servers[0]); -// if (result) { -// error_dev(dev, "failed to connect to initial server"); -// result = -ENOENT; -// dev->imgname = NULL; -// dev->socks[0].server = NULL; -// } return result; } @@ -860,6 +852,7 @@ int dnbd3_net_disconnect(struct dnbd3_device *dev) info_dev(dev, "not connected"); } + dev->connected = false; del_timer_sync(&dev->timer); /* be sure it does not recover while disconnecting */ cancel_work_sync(&dev->discovery_worker); @@ -876,7 +869,6 @@ int dnbd3_net_disconnect(struct dnbd3_device *dev) } kfree(dev->socks); dev->socks = NULL; - dev->connected = false; return result; } |