mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
nbd: factor out a nbd_genl_foreach_sock
The NBD_ATTR_SOCKETS walk is duplicated in nbd_genl_connect (add sockets) and nbd_genl_reconfigure (reconnect). Factor out a single helper that walks the list and calls a callback per fd; with a NULL callback it is a pure counter, used by a later patch to learn nr_hw_queues before the device exists. Returns the number of fds walked (>= 0) or a negative errno; a callback >0 will stops early. Reviewed-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Yang Erkun <yangerkun@huawei.com> Link: https://patch.msgid.link/20260805122930.57647-7-yangerkun@huawei.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
db285268df
commit
f8d21c590e
|
|
@ -1344,7 +1344,7 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
|
||||
static int nbd_genl_reconnect_sock_cb(struct nbd_device *nbd, unsigned long arg)
|
||||
{
|
||||
struct nbd_config *config = nbd->config;
|
||||
struct socket *sock, *old;
|
||||
|
|
@ -1399,11 +1399,12 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
|
|||
|
||||
atomic_inc(&config->live_connections);
|
||||
wake_up(&config->conn_wait);
|
||||
dev_info(nbd_to_dev(nbd), "reconnected socket\n");
|
||||
return 0;
|
||||
}
|
||||
sockfd_put(sock);
|
||||
kfree(args);
|
||||
return -ENOSPC;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void nbd_bdev_reset(struct nbd_device *nbd)
|
||||
|
|
@ -2109,6 +2110,58 @@ 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, unsigned long 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, unsigned long 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;
|
||||
|
|
@ -2228,36 +2281,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],
|
||||
|
|
@ -2442,40 +2468,10 @@ 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);
|
||||
/* foreach_sock returns a positive count on success; doit must return 0 */
|
||||
if (ret >= 0)
|
||||
ret = 0;
|
||||
out:
|
||||
mutex_unlock(&nbd->config_lock);
|
||||
nbd_config_put(nbd);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user