From: Anna Schumaker <Anna.Schumaker@xxxxxxxxxx> And since we're using IP here, restrict to only creating sysfs files for TCP and RDMA connections. Signed-off-by: Anna Schumaker <Anna.Schumaker@xxxxxxxxxx> --- net/sunrpc/sysfs.c | 32 ++++++++++++++++++++++++++++++++ net/sunrpc/sysfs.h | 1 + 2 files changed, 33 insertions(+) diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c index dd298b9c13e8..537d83635670 100644 --- a/net/sunrpc/sysfs.c +++ b/net/sunrpc/sysfs.c @@ -3,6 +3,7 @@ * Copyright (c) 2020 Anna Schumaker <Anna.Schumaker@xxxxxxxxxx> */ #include <linux/sunrpc/clnt.h> +#include <linux/sunrpc/addr.h> #include <net/sock.h> #include "sysfs.h" @@ -55,6 +56,23 @@ int rpc_sysfs_init(void) return 0; } +static ssize_t rpc_netns_address_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct rpc_netns_client *c = container_of(kobj, + struct rpc_netns_client, kobject); + struct rpc_clnt *clnt = c->clnt; + struct rpc_xprt *xprt = rcu_dereference(clnt->cl_xprt); + + return rpc_ntop((struct sockaddr *)&xprt->addr, buf, PAGE_SIZE); +} + +static ssize_t rpc_netns_address_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + return count; +} + static void rpc_netns_client_release(struct kobject *kobj) { struct rpc_netns_client *c; @@ -68,8 +86,17 @@ static const void *rpc_netns_client_namespace(struct kobject *kobj) return container_of(kobj, struct rpc_netns_client, kobject)->net; } +static struct kobj_attribute rpc_netns_client_address = __ATTR(address, + 0644, rpc_netns_address_show, rpc_netns_address_store); + +static struct attribute *rpc_netns_client_attrs[] = { + &rpc_netns_client_address.attr, + NULL, +}; + static struct kobj_type rpc_netns_client_type = { .release = rpc_netns_client_release, + .default_attrs = rpc_netns_client_attrs, .sysfs_ops = &kobj_sysfs_ops, .namespace = rpc_netns_client_namespace, }; @@ -100,10 +127,15 @@ static struct rpc_netns_client *rpc_netns_client_alloc(struct kobject *parent, void rpc_netns_sysfs_setup(struct rpc_clnt *clnt, struct net *net) { struct rpc_netns_client *rpc_client; + struct rpc_xprt *xprt = rcu_dereference(clnt->cl_xprt); + + if (!(xprt->prot & (IPPROTO_TCP | XPRT_TRANSPORT_RDMA))) + return; rpc_client = rpc_netns_client_alloc(rpc_client_kobj, net, clnt->cl_clid); if (rpc_client) { clnt->cl_sysfs = rpc_client; + rpc_client->clnt = clnt; kobject_uevent(&rpc_client->kobject, KOBJ_ADD); } } diff --git a/net/sunrpc/sysfs.h b/net/sunrpc/sysfs.h index 279a836594e7..137a12c87954 100644 --- a/net/sunrpc/sysfs.h +++ b/net/sunrpc/sysfs.h @@ -8,6 +8,7 @@ struct rpc_netns_client { struct kobject kobject; struct net *net; + struct rpc_clnt *clnt; }; extern struct kobject *rpc_client_kobj; -- 2.29.2