[PATCH v3 2/2] nbd: introduce a client flag to do zero timeout handling
Introduce a dedicated client flag NBD_RT_WAIT_ON_TIMEOUT to reset
timer in nbd_xmit_timer instead of depending on tag_set.timeout == 0.
So that the timeout value could be configured by the user to
whatever they like instead of the default 30s. A smaller timeout
value allow us to detect if a new socket is reconfigured in a
shorter time. Thus the io could be requeued more quickly.
In multiple sockets configuration, the user could also disable
dropping the socket in timeout by setting this flag.
The tag_set.timeout == 0 setting still works like before.
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Hou Pu <houpu@bytedance.com>
---
drivers/block/nbd.c | 27 ++++++++++++++++++++++-----
include/uapi/linux/nbd.h | 4 ++++
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 538e9dcf5bf2..2d32e31b7b96 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -80,6 +80,7 @@ struct link_dead_args {
#define NBD_RT_BOUND 5
#define NBD_RT_DESTROY_ON_DISCONNECT 6
#define NBD_RT_DISCONNECT_ON_CLOSE 7
+#define NBD_RT_WAIT_ON_TIMEOUT 8
#define NBD_DESTROY_ON_DISCONNECT 0
#define NBD_DISCONNECT_REQUESTED 1
@@ -378,6 +379,16 @@ static u32 req_to_nbd_cmd_type(struct request *req)
}
}
+static inline bool wait_on_timeout(struct nbd_device *nbd,
+ struct nbd_config *config)
+{
+ if (test_bit(NBD_RT_WAIT_ON_TIMEOUT, &config->runtime_flags) ||
+ (config->num_connections == 1 && nbd->tag_set.timeout == 0))
+ return true;
+ else
+ return false;
+}
+
static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
bool reserved)
{
@@ -400,8 +411,7 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
nbd->tag_set.timeout)
goto error_out;
- if (config->num_connections > 1 ||
- (config->num_connections == 1 && nbd->tag_set.timeout)) {
+ if (!wait_on_timeout(nbd, config)) {
dev_err_ratelimited(nbd_to_dev(nbd),
"Connection timed out, retrying (%d/%d alive)\n",
atomic_read(&config->live_connections),
@@ -432,9 +442,7 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
nbd_config_put(nbd);
return BLK_EH_DONE;
}
- }
-
- if (!nbd->tag_set.timeout) {
+ } else {
/*
* Userspace sets timeout=0 to disable socket disconnection,
* so just warn and reset the timer.
@@ -1956,6 +1964,9 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
set_bit(NBD_RT_DISCONNECT_ON_CLOSE,
&config->runtime_flags);
}
+ if (flags & NBD_CFLAG_WAIT_ON_TIMEOUT)
+ set_bit(NBD_RT_WAIT_ON_TIMEOUT,
+ &config->runtime_flags);
}
if (info->attrs[NBD_ATTR_SOCKETS]) {
@@ -2139,6 +2150,12 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
clear_bit(NBD_RT_DISCONNECT_ON_CLOSE,
&config->runtime_flags);
}
+ if (flags & NBD_CFLAG_WAIT_ON_TIMEOUT)
+ set_bit(NBD_RT_WAIT_ON_TIMEOUT,
+ &config->runtime_flags);
+ else
+ clear_bit(NBD_RT_WAIT_ON_TIMEOUT,
+ &config->runtime_flags);
}
if (info->attrs[NBD_ATTR_SOCKETS]) {
diff --git a/include/uapi/linux/nbd.h b/include/uapi/linux/nbd.h
index 20d6cc91435d..cc3abfb92de5 100644
--- a/include/uapi/linux/nbd.h
+++ b/include/uapi/linux/nbd.h
@@ -56,6 +56,10 @@ enum {
#define NBD_CFLAG_DISCONNECT_ON_CLOSE (1 << 1) /* disconnect the nbd device on
* close by last opener.
*/
+#define NBD_CFLAG_WAIT_ON_TIMEOUT (1 << 2) /* do not fallback to other sockets
+ * in io timeout, instead just reset
+ * timer and wait.
+ */
/* userspace doesn't need the nbd_device structure */
--
2.11.0
Reply to: