sunrpc: Add a sysfs file for adding a new xprt

Writing to this file will clone the 'main' xprt of an xprt_switch and
add it to be used as an additional connection.

--

Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
v3: Replace call to xprt_iter_get_xprt() with xprt_iter_get_next()
Link: https://lore.kernel.org/r/20250207204225.594002-5-anna@kernel.org
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
Anna Schumaker 2025-02-07 15:42:24 -05:00 committed by Trond Myklebust
parent 88efd79c3f
commit df210d9b09
3 changed files with 76 additions and 0 deletions

View File

@ -56,6 +56,7 @@ extern void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps,
struct rpc_xprt *xprt);
extern void rpc_xprt_switch_remove_xprt(struct rpc_xprt_switch *xps,
struct rpc_xprt *xprt, bool offline);
extern struct rpc_xprt *rpc_xprt_switch_get_main_xprt(struct rpc_xprt_switch *xps);
extern void xprt_iter_init(struct rpc_xprt_iter *xpi,
struct rpc_xprt_switch *xps);

View File

@ -305,6 +305,55 @@ static ssize_t rpc_sysfs_xprt_switch_info_show(struct kobject *kobj,
return ret;
}
static ssize_t rpc_sysfs_xprt_switch_add_xprt_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
return sprintf(buf, "# add one xprt to this xprt_switch\n");
}
static ssize_t rpc_sysfs_xprt_switch_add_xprt_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
struct rpc_xprt_switch *xprt_switch =
rpc_sysfs_xprt_switch_kobj_get_xprt(kobj);
struct xprt_create xprt_create_args;
struct rpc_xprt *xprt, *new;
if (!xprt_switch)
return 0;
xprt = rpc_xprt_switch_get_main_xprt(xprt_switch);
if (!xprt)
goto out;
xprt_create_args.ident = xprt->xprt_class->ident;
xprt_create_args.net = xprt->xprt_net;
xprt_create_args.dstaddr = (struct sockaddr *)&xprt->addr;
xprt_create_args.addrlen = xprt->addrlen;
xprt_create_args.servername = xprt->servername;
xprt_create_args.bc_xprt = xprt->bc_xprt;
xprt_create_args.xprtsec = xprt->xprtsec;
xprt_create_args.connect_timeout = xprt->connect_timeout;
xprt_create_args.reconnect_timeout = xprt->max_reconnect_timeout;
new = xprt_create_transport(&xprt_create_args);
if (IS_ERR_OR_NULL(new)) {
count = PTR_ERR(new);
goto out_put_xprt;
}
rpc_xprt_switch_add_xprt(xprt_switch, new);
xprt_put(new);
out_put_xprt:
xprt_put(xprt);
out:
xprt_switch_put(xprt_switch);
return count;
}
static ssize_t rpc_sysfs_xprt_dstaddr_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
@ -523,8 +572,13 @@ ATTRIBUTE_GROUPS(rpc_sysfs_xprt);
static struct kobj_attribute rpc_sysfs_xprt_switch_info =
__ATTR(xprt_switch_info, 0444, rpc_sysfs_xprt_switch_info_show, NULL);
static struct kobj_attribute rpc_sysfs_xprt_switch_add_xprt =
__ATTR(add_xprt, 0644, rpc_sysfs_xprt_switch_add_xprt_show,
rpc_sysfs_xprt_switch_add_xprt_store);
static struct attribute *rpc_sysfs_xprt_switch_attrs[] = {
&rpc_sysfs_xprt_switch_info.attr,
&rpc_sysfs_xprt_switch_add_xprt.attr,
NULL,
};
ATTRIBUTE_GROUPS(rpc_sysfs_xprt_switch);

View File

@ -92,6 +92,27 @@ void rpc_xprt_switch_remove_xprt(struct rpc_xprt_switch *xps,
xprt_put(xprt);
}
/**
* rpc_xprt_switch_get_main_xprt - Get the 'main' xprt for an xprt switch.
* @xps: pointer to struct rpc_xprt_switch.
*/
struct rpc_xprt *rpc_xprt_switch_get_main_xprt(struct rpc_xprt_switch *xps)
{
struct rpc_xprt_iter xpi;
struct rpc_xprt *xprt;
xprt_iter_init_listall(&xpi, xps);
xprt = xprt_iter_get_next(&xpi);
while (xprt && !xprt->main) {
xprt_put(xprt);
xprt = xprt_iter_get_next(&xpi);
}
xprt_iter_destroy(&xpi);
return xprt;
}
static DEFINE_IDA(rpc_xprtswitch_ids);
void xprt_multipath_cleanup_ids(void)