summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Robra2019-11-08 13:33:30 +0100
committerFrederic Robra2019-11-08 13:33:30 +0100
commit6a3d9860253eb74817d98192156378e1edff618c (patch)
tree1994ce71f4a8c5a78ce463832bb9bdb847bde701
parentremoved bug when sending and at the same time socket closes down (diff)
downloaddnbd3-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.c46
-rw-r--r--src/kernel/net-txrx.c9
-rw-r--r--src/kernel/net.c14
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;
}