summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/core.c5
-rw-r--r--src/kernel/mq.c24
-rw-r--r--src/kernel/mq.h2
-rw-r--r--src/kernel/net-txrx.c8
-rw-r--r--src/kernel/net.c28
5 files changed, 53 insertions, 14 deletions
diff --git a/src/kernel/core.c b/src/kernel/core.c
index 6e5b82b..8582b5c 100644
--- a/src/kernel/core.c
+++ b/src/kernel/core.c
@@ -250,6 +250,7 @@ int dnbd3_add_device(struct dnbd3_device *dev, int minor)
for (i = 0; i < NUMBER_CONNECTIONS; i++) {
dev->socks[i].device = dev;
dev->socks[i].sock_nr = i;
+ mutex_init(&dev->socks[i]->tx_lock);
}
disk = alloc_disk(1);
@@ -403,6 +404,7 @@ static void dnbd3_dev_remove(struct dnbd3_device *dev)
{
struct gendisk *disk = dev->disk;
struct request_queue *q;
+ int i;
dnbd3_net_disconnect(dev);
@@ -419,6 +421,9 @@ static void dnbd3_dev_remove(struct dnbd3_device *dev)
dev->imgname = NULL;
}
mutex_destroy(&dev->device_lock);
+ for (i = 0; i < NUMBER_CONNECTIONS; i++) {
+ mutex_destroy(&dev->socks[i]->tx_lock);
+ }
}
/**
diff --git a/src/kernel/mq.c b/src/kernel/mq.c
index 94f06f2..60673b0 100644
--- a/src/kernel/mq.c
+++ b/src/kernel/mq.c
@@ -28,9 +28,9 @@
* dnbd3_busy_iter - iterator for blk_mq_tagset_busy_iter
* @req: the request
* @priv: the passed argument from blk_mq_tagset_busy_iter
- * @arg2: unknown
+ * @arg: unknown
*/
-static void dnbd3_busy_iter(struct request *req, void *priv, bool arg2)
+static void dnbd3_busy_iter(struct request *req, void *priv, bool arg)
{
struct dnbd3_cmd *cmd = blk_mq_rq_to_pdu(req);
unsigned long *busy = (unsigned long *) priv;
@@ -70,6 +70,26 @@ unsigned long dnbd3_is_mq_busy(struct dnbd3_device *dev)
return busy;
}
+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 (!mutex_trylock(&cmd->lock)) {
+ /* request is in sending, so we will not requeue */
+ return;
+ }
+ debug_sock(sock, "requeue busy request %p", req);
+ dnbd3_requeue_cmd(cmd);
+ mutex_unlock(&cmd->lock);
+}
+
+void dndb3_reque_busy_requests(struct dnbd3_sock *sock)
+{
+ struct blk_mq_tag_set *set = &sock->device->tag_set;
+ blk_mq_tagset_busy_iter(set, dnbd3_busy_iter_requeue, sock);
+}
+
+
/**
* dnbd3_requeue_cmd - requeue a command once
diff --git a/src/kernel/mq.h b/src/kernel/mq.h
index 821fd91..94b09f9 100644
--- a/src/kernel/mq.h
+++ b/src/kernel/mq.h
@@ -31,6 +31,8 @@
*/
unsigned long dnbd3_is_mq_busy(struct dnbd3_device *dev);
+void dndb3_reque_busy_requests(struct dnbd3_sock *sock);
+
/**
* dnbd3_requeue_cmd - requeue a command once
* @cmd: the command to requeue
diff --git a/src/kernel/net-txrx.c b/src/kernel/net-txrx.c
index d905ce9..7226a3e 100644
--- a/src/kernel/net-txrx.c
+++ b/src/kernel/net-txrx.c
@@ -183,6 +183,8 @@ error:
* dnbd3_send_request_cmd - send a dndb3 cmd
* @sock: the socket where the request is send
* @dnbd3_cmd: the dnbd3 cmd to send
+ *
+ * the tx_lock of the socket must be held
*/
int dnbd3_send_request_cmd(struct dnbd3_sock *sock, uint16_t dnbd3_cmd)
{
@@ -211,10 +213,12 @@ int dnbd3_send_request_cmd(struct dnbd3_sock *sock, uint16_t dnbd3_cmd)
goto error;
}
- mutex_lock(&sock->tx_lock);
+ if (unlikely(!sock->sock)) {
+ result = -EIO;
+ goto error;
+ }
sock->pending = req;
result = dnbd3_send_request(sock, req, NULL);
- mutex_unlock(&sock->tx_lock);
error:
if (req) {
diff --git a/src/kernel/net.c b/src/kernel/net.c
index cb4e76c..67f9c74 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -75,14 +75,11 @@ static void dnbd3_timer(struct timer_list *arg)
}
}
- if (!busy) {
- /* start after 4 seconds */
- if (dev->timer_count % TIMER_INTERVAL_PROBE_NORMAL == 4) {
- queue_work(dnbd3_wq, &dev->discovery_worker);
- }
-
-
+ /* start after 2 seconds */
+ if (dev->timer_count % TIMER_INTERVAL_PROBE_NORMAL == 2) {
+ queue_work(dnbd3_wq, &dev->discovery_worker);
}
+
dev->timer_count++;
dev->timer.expires = jiffies + HZ;
add_timer(&dev->timer);
@@ -185,7 +182,9 @@ static void dnbd3_keepalive_worker(struct work_struct *work)
sock = container_of(work, struct dnbd3_sock, keepalive_worker);
if (sock->server != NULL && !sock->panic) {
debug_sock(sock, "starting keepalive worker");
+ mutex_lock(&sock->tx_lock);
dnbd3_send_request_cmd(sock, CMD_KEEPALIVE);
+ mutex_unlock(&sock->tx_lock);
}
}
@@ -237,6 +236,7 @@ static int dnbd3_panic_connect(struct dnbd3_device *dev)
{
struct dnbd3_server *working = NULL;
int i;
+ debug_dev(dev, "panic connect");
for (i = 0; i < NUMBER_CONNECTIONS; i++) {
if (dnbd3_is_sock_alive(dev->socks[i])) {
working = dev->socks[i].server;
@@ -273,7 +273,7 @@ static int dnbd3_adjust_connections(struct dnbd3_device *dev) {
int i, j, fallback;
struct dnbd3_server *plan[NUMBER_CONNECTIONS];
struct dnbd3_server **servers = dnbd3_sort_server(dev);
-//TODO don't connect to anyting bader then rtt unknown
+
if (servers && servers[0]->host.type != 0) {
plan[0] = servers[0];
fallback = 0;
@@ -300,6 +300,8 @@ static int dnbd3_adjust_connections(struct dnbd3_device *dev) {
i, plan[i]->avg_rtt);
}
kfree(servers);
+ //TODO connection plan sortieren
+
for (i = 0; i < NUMBER_CONNECTIONS; i++) {
if (plan[i] != dev->socks[i].server) {
if (dnbd3_is_sock_alive(dev->socks[i])) {
@@ -677,13 +679,13 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock,
result = -EIO;
goto error;
}
- mutex_unlock(&sock->tx_lock);
sock->panic = false;
if (!sock->sock) {
error_sock(sock, "socket is not connected");
server->failures++;
+ mutex_unlock(&sock->tx_lock);
result = -EIO;
goto error;
}
@@ -691,15 +693,17 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock,
result = dnbd3_send_request_cmd(sock, CMD_SELECT_IMAGE);
if (result <= 0) {
-
error_sock(sock, "connection to image %s failed", dev->imgname);
+ mutex_unlock(&sock->tx_lock);
result = -EIO;
goto error;
}
+
result = dnbd3_receive_cmd(sock, &reply);
if (result <= 0) {
error_sock(sock, "receive cmd to image %s failed",
dev->imgname);
+ mutex_unlock(&sock->tx_lock);
result = -EIO;
goto error;
}
@@ -707,6 +711,7 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock,
|| reply.size < 4) {
error_sock(sock, "receive select image wrong header %s",
dev->imgname);
+ mutex_unlock(&sock->tx_lock);
result = -EIO;
goto error;
}
@@ -714,6 +719,7 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock,
if (result <= 0) {
error_sock(sock, "receive cmd select image %s failed",
dev->imgname);
+ mutex_unlock(&sock->tx_lock);
result = -EIO;
goto error;
}
@@ -730,6 +736,7 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock,
if (dnbd3_send_request_cmd(sock, CMD_GET_SERVERS) <= 0) {
error_sock(sock, "failed to get servers in discovery");
}
+ mutex_unlock(&sock->tx_lock);
return 0;
error:
@@ -770,6 +777,7 @@ static int dnbd3_socket_disconnect(struct dnbd3_sock *sock)
*/
if (sock->sock) {
kernel_sock_shutdown(sock->sock, SHUT_RDWR);
+ dndb3_reque_busy_requests(sock);
}
mutex_unlock(&sock->tx_lock);
mutex_destroy(&sock->tx_lock);