[PATCH v4 5/7] nbd: factor out a nbd_genl_foreach_sock
- To: josef@toxicpanda.com, axboe@kernel.dk, hch@lst.de, yukuai@kernel.org
- Cc: yi.zhang@huawei.com, chengzhihao1@huawei.com, echo.chenlin@huawei.com, leo.lilong@huaweicloud.com, wangkefeng.wang@huawei.com, huawei.libin@huawei.com, leijitang@huawei.com, linux-block@vger.kernel.org, nbd@other.debian.org
- Subject: [PATCH v4 5/7] nbd: factor out a nbd_genl_foreach_sock
- From: Yang Erkun <yangerkun@huawei.com>
- Date: Mon, 27 Jul 2026 15:47:16 +0800
- Message-id: <[🔎] 20260727074718.414868-6-yangerkun@huawei.com>
- In-reply-to: <[🔎] 20260727074718.414868-1-yangerkun@huawei.com>
- References: <[🔎] 20260727074718.414868-1-yangerkun@huawei.com>
The walk for NBD_ATTR_SOCKETS in nbd_genl_connect and
nbd_genl_disconnect seems duplicated, factor out nbd_genl_foreach_sock,
and this will be use in latter patch.
Signed-off-by: Yang Erkun <yangerkun@huawei.com>
---
drivers/block/nbd.c | 135 +++++++++++++++++++++++---------------------
1 file changed, 71 insertions(+), 64 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index e2fb787248c8..4b9f0349877e 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -2103,6 +2103,59 @@ static int nbd_genl_size_set(struct genl_info *info, struct nbd_device *nbd)
return 0;
}
+/*
+ * Walk the NBD_ATTR_SOCKETS nested list can call @cb for each socket fd.
+ *
+ * Return the number of fds walked, or a negative errno.
+ */
+static int nbd_genl_foreach_sock(struct genl_info *info,
+ int (*cb)(struct nbd_device *nbd, int fd),
+ struct nbd_device *nbd)
+{
+ struct nlattr *attr;
+ int rem, count = 0;
+
+ if (!info->attrs[NBD_ATTR_SOCKETS])
+ return 0;
+
+ nla_for_each_nested(attr, info->attrs[NBD_ATTR_SOCKETS], rem) {
+ struct nlattr *socks[NBD_SOCK_MAX + 1];
+ int ret;
+
+ if (nla_type(attr) != NBD_SOCK_ITEM) {
+ pr_err("socks must be embedded in a SOCK_ITEM attr\n");
+ return -EINVAL;
+ }
+
+ if (nla_parse_nested_deprecated(socks, NBD_SOCK_MAX,
+ attr,
+ nbd_sock_policy,
+ info->extack)) {
+ pr_err("error processing sock list\n");
+ return -EINVAL;
+ }
+
+ if (!socks[NBD_SOCK_FD])
+ continue;
+
+ count++;
+ if (cb) {
+ ret = cb(nbd, (int)nla_get_u32(socks[NBD_SOCK_FD]));
+ if (ret > 0)
+ return count;
+ if (ret < 0)
+ return ret;
+
+ }
+ }
+ return count;
+}
+
+static int nbd_genl_connect_sock_cb(struct nbd_device *nbd, int fd)
+{
+ return nbd_add_socket(nbd, fd, true);
+}
+
static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
{
struct nbd_device *nbd;
@@ -2222,36 +2275,9 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
}
}
- if (info->attrs[NBD_ATTR_SOCKETS]) {
- struct nlattr *attr;
- int rem, fd;
-
- nla_for_each_nested(attr, info->attrs[NBD_ATTR_SOCKETS],
- rem) {
- struct nlattr *socks[NBD_SOCK_MAX+1];
-
- if (nla_type(attr) != NBD_SOCK_ITEM) {
- pr_err("socks must be embedded in a SOCK_ITEM attr\n");
- ret = -EINVAL;
- goto out;
- }
- ret = nla_parse_nested_deprecated(socks, NBD_SOCK_MAX,
- attr,
- nbd_sock_policy,
- info->extack);
- if (ret != 0) {
- pr_err("error processing sock list\n");
- ret = -EINVAL;
- goto out;
- }
- if (!socks[NBD_SOCK_FD])
- continue;
- fd = (int)nla_get_u32(socks[NBD_SOCK_FD]);
- ret = nbd_add_socket(nbd, fd, true);
- if (ret)
- goto out;
- }
- }
+ ret = nbd_genl_foreach_sock(info, nbd_genl_connect_sock_cb, nbd);
+ if (ret < 0)
+ goto out;
if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
nbd->backend = nla_strdup(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
@@ -2340,6 +2366,20 @@ static int nbd_genl_disconnect(struct sk_buff *skb, struct genl_info *info)
return 0;
}
+static int nbd_genl_reconnect_sock_cb(struct nbd_device *nbd, int fd)
+{
+ int ret = nbd_reconnect_socket(nbd, fd);
+
+ if (!ret) {
+ dev_info(nbd_to_dev(nbd), "reconnected socket\n");
+ return 0;
+ }
+
+ if (ret == -ENOSPC)
+ return 1;
+ return ret;
+}
+
static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
{
struct nbd_device *nbd = NULL;
@@ -2436,40 +2476,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
}
}
- if (info->attrs[NBD_ATTR_SOCKETS]) {
- struct nlattr *attr;
- int rem, fd;
-
- nla_for_each_nested(attr, info->attrs[NBD_ATTR_SOCKETS],
- rem) {
- struct nlattr *socks[NBD_SOCK_MAX+1];
-
- if (nla_type(attr) != NBD_SOCK_ITEM) {
- pr_err("socks must be embedded in a SOCK_ITEM attr\n");
- ret = -EINVAL;
- goto out;
- }
- ret = nla_parse_nested_deprecated(socks, NBD_SOCK_MAX,
- attr,
- nbd_sock_policy,
- info->extack);
- if (ret != 0) {
- pr_err("error processing sock list\n");
- ret = -EINVAL;
- goto out;
- }
- if (!socks[NBD_SOCK_FD])
- continue;
- fd = (int)nla_get_u32(socks[NBD_SOCK_FD]);
- ret = nbd_reconnect_socket(nbd, fd);
- if (ret) {
- if (ret == -ENOSPC)
- ret = 0;
- goto out;
- }
- dev_info(nbd_to_dev(nbd), "reconnected socket\n");
- }
- }
+ ret = nbd_genl_foreach_sock(info, nbd_genl_reconnect_sock_cb, nbd);
out:
mutex_unlock(&nbd->config_lock);
nbd_config_put(nbd);
--
2.52.0
Reply to: