Commit df210d9b authored by Anna Schumaker's avatar Anna Schumaker Committed by Trond Myklebust
Browse files

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: default avatarBenjamin Coddington <bcodding@redhat.com>
Signed-off-by: default avatarAnna 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: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 88efd79c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+54 −0
Original line number Diff line number Diff line
@@ -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);
+21 −0
Original line number Diff line number Diff line
@@ -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)