[PATCH] nbd: Consistently use request pointer in debug messages.

2018-06-04 Thread kvigor
From: Kevin Vigor 

Existing dev_dbg messages sometimes identify request using request
pointer, sometimes using nbd_cmd pointer. This makes it hard to
follow request flow. Consistently use request pointer instead.
---
 drivers/block/nbd.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 3ed1ef8..b5afa11 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -275,7 +275,7 @@ static void nbd_complete_rq(struct request *req)
 {
struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
 
-   dev_dbg(nbd_to_dev(cmd->nbd), "request %p: %s\n", cmd,
+   dev_dbg(nbd_to_dev(cmd->nbd), "request %p: %s\n", req,
cmd->status ? "failed" : "done");
 
blk_mq_end_request(req, cmd->status);
@@ -482,7 +482,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct 
nbd_cmd *cmd, int index)
memcpy(request.handle, , sizeof(tag));
 
dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n",
-   cmd, nbdcmd_to_ascii(type),
+   req, nbdcmd_to_ascii(type),
(unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req));
result = sock_xmit(nbd, index, 1, ,
(type == NBD_CMD_WRITE) ? MSG_MORE : 0, );
@@ -518,7 +518,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct 
nbd_cmd *cmd, int index)
int flags = is_last ? 0 : MSG_MORE;
 
dev_dbg(nbd_to_dev(nbd), "request %p: sending %d bytes 
data\n",
-   cmd, bvec.bv_len);
+   req, bvec.bv_len);
iov_iter_bvec(, ITER_BVEC | WRITE,
  , 1, bvec.bv_len);
if (skip) {
@@ -610,7 +610,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device 
*nbd, int index)
return cmd;
}
 
-   dev_dbg(nbd_to_dev(nbd), "request %p: got reply\n", cmd);
+   dev_dbg(nbd_to_dev(nbd), "request %p: got reply\n", req);
if (rq_data_dir(req) != WRITE) {
struct req_iterator iter;
struct bio_vec bvec;
@@ -637,7 +637,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device 
*nbd, int index)
return ERR_PTR(-EIO);
}
dev_dbg(nbd_to_dev(nbd), "request %p: got %d bytes 
data\n",
-   cmd, bvec.bv_len);
+   req, bvec.bv_len);
}
} else {
/* See the comment in nbd_queue_rq. */
-- 
2.7.4



[PATCH] nbd: clear DISCONNECT_REQUESTED flag once disconnection occurs.

2018-05-30 Thread kvigor
From: Kevin Vigor 

When a userspace client requests a NBD device be disconnected, the
DISCONNECT_REQUESTED flag is set. While this flag is set, the driver
will not inform userspace when a connection is closed.

Unfortunately the flag was never cleared, so once a disconnect was
requested the driver would thereafter never tell userspace about a
closed connection. Thus when connections failed due to timeout, no
attempt to reconnect was made and eventually the device would fail.

Fix by clearing the DISCONNECT_REQUESTED flag (and setting the
DISCONNECTED flag) once all connections are closed.

Changes relative to v1 (https://marc.info/?l=linux-block=152763540418902):

* remove pointless wake_up() -> wake_up_all() change.

Signed-off-by: Kevin Vigor 
---
 drivers/block/nbd.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index afbc202..1cd041b 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -213,7 +213,15 @@ static void nbd_mark_nsock_dead(struct nbd_device *nbd, 
struct nbd_sock *nsock,
}
if (!nsock->dead) {
kernel_sock_shutdown(nsock->sock, SHUT_RDWR);
-   atomic_dec(>config->live_connections);
+   if (atomic_dec_return(>config->live_connections) == 0) {
+   if (test_and_clear_bit(NBD_DISCONNECT_REQUESTED,
+  >config->runtime_flags)) {
+   set_bit(NBD_DISCONNECTED,
+   >config->runtime_flags);
+   dev_info(nbd_to_dev(nbd),
+   "Disconnected due to user request.\n");
+   }
+   }
}
nsock->dead = true;
nsock->pending = NULL;
@@ -292,7 +300,9 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct 
request *req,
 
if (config->num_connections > 1) {
dev_err_ratelimited(nbd_to_dev(nbd),
-   "Connection timed out, retrying\n");
+   "Connection timed out, retrying (%d/%d 
alive)\n",
+   atomic_read(>live_connections),
+   config->num_connections);
/*
 * Hooray we have more connections, requeue this IO, the submit
 * path will put it on a real connection.
@@ -714,10 +724,9 @@ static int wait_for_reconnect(struct nbd_device *nbd)
return 0;
if (test_bit(NBD_DISCONNECTED, >runtime_flags))
return 0;
-   wait_event_timeout(config->conn_wait,
-  atomic_read(>live_connections),
-  config->dead_conn_timeout);
-   return atomic_read(>live_connections);
+   return wait_event_timeout(config->conn_wait,
+ atomic_read(>live_connections) > 0,
+ config->dead_conn_timeout) > 0;
 }
 
 static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
-- 
2.7.4



[PATCH] nbd: clear DISCONNECT_REQUESTED flag once disconnection occurs.

2018-05-29 Thread kvigor
From: Kevin Vigor 

When a userspace client requests a NBD device be disconnected, the
DISCONNECT_REQUESTED flag is set. While this flag is set, the driver
will not inform userspace when a connection is closed.

Unfortunately the flag was never cleared, so once a disconnect was
requested the driver would thereafter never tell userspace about a
closed connection. Thus when connections failed due to timeout, no
attempt to reconnect was made and eventually the device would fail.

Fix by clearing the DISCONNECT_REQUESTED flag (and setting the
DISCONNECTED flag) once all connections are closed.

Additionally wake all tasks waiting in wait_for_reconnect() when a
connection is established instead of only waking one and letting the
rest timeout.

Signed-off-by: Kevin Vigor 
---
 drivers/block/nbd.c | 23 ---
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index afbc202..11956d4 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -213,7 +213,15 @@ static void nbd_mark_nsock_dead(struct nbd_device *nbd, 
struct nbd_sock *nsock,
}
if (!nsock->dead) {
kernel_sock_shutdown(nsock->sock, SHUT_RDWR);
-   atomic_dec(>config->live_connections);
+   if (atomic_dec_return(>config->live_connections) == 0) {
+   if (test_and_clear_bit(NBD_DISCONNECT_REQUESTED,
+  >config->runtime_flags)) {
+   set_bit(NBD_DISCONNECTED,
+   >config->runtime_flags);
+   dev_info(nbd_to_dev(nbd),
+   "Disconnected due to user request.\n");
+   }
+   }
}
nsock->dead = true;
nsock->pending = NULL;
@@ -292,7 +300,9 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct 
request *req,
 
if (config->num_connections > 1) {
dev_err_ratelimited(nbd_to_dev(nbd),
-   "Connection timed out, retrying\n");
+   "Connection timed out, retrying (%d/%d 
alive)\n",
+   atomic_read(>live_connections),
+   config->num_connections);
/*
 * Hooray we have more connections, requeue this IO, the submit
 * path will put it on a real connection.
@@ -714,10 +724,9 @@ static int wait_for_reconnect(struct nbd_device *nbd)
return 0;
if (test_bit(NBD_DISCONNECTED, >runtime_flags))
return 0;
-   wait_event_timeout(config->conn_wait,
-  atomic_read(>live_connections),
-  config->dead_conn_timeout);
-   return atomic_read(>live_connections);
+   return wait_event_timeout(config->conn_wait,
+ atomic_read(>live_connections) > 0,
+ config->dead_conn_timeout) > 0;
 }
 
 static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
@@ -937,7 +946,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, 
unsigned long arg)
queue_work(recv_workqueue, >work);
 
atomic_inc(>live_connections);
-   wake_up(>conn_wait);
+   wake_up_all(>conn_wait);
return 0;
}
sockfd_put(sock);
-- 
2.7.4