[RFC PATCH 5/7] sunrpc: Create a per-rpc_clnt file for managing the IP address

schumaker.anna
2021-01-11T21:43:33Z

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@Netapp.com>
---
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@Netapp.com>
*/
#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