From: Dan Aloni <dan@kernelim.com>
To: linux-nfs@vger.kernel.org, Anna Schumaker <anna.schumaker@netapp.com>
Cc: Trond Myklebust <trond.myklebust@hammerspace.com>
Subject: [PATCH v1 3/8] sunrpc: add a directory per sunrpc xprt
Date: Mon, 15 Feb 2021 19:39:57 +0200 [thread overview]
Message-ID: <20210215174002.2376333-4-dan@kernelim.com> (raw)
In-Reply-To: <20210215174002.2376333-1-dan@kernelim.com>
This uses much of the code from the per-client directory, except that
now we have direct access to the transport struct. The per-client
direct is adjusted in a subsequent commit.
Signed-off-by: Dan Aloni <dan@kernelim.com>
---
include/linux/sunrpc/xprt.h | 1 +
net/sunrpc/sysfs.c | 131 ++++++++++++++++++++++++++++++++++--
net/sunrpc/sysfs.h | 9 +++
net/sunrpc/xprt.c | 3 +
4 files changed, 139 insertions(+), 5 deletions(-)
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index fbf57a87dc47..df0252de58f4 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -260,6 +260,7 @@ struct rpc_xprt {
* items */
struct list_head bc_pa_list; /* List of preallocated
* backchannel rpc_rqst's */
+ void *sysfs; /* /sys/kernel/sunrpc/xprt/<id> */
#endif /* CONFIG_SUNRPC_BACKCHANNEL */
struct rb_root recv_queue; /* Receive queue */
diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c
index 3fe814795ed9..687d4470b90d 100644
--- a/net/sunrpc/sysfs.c
+++ b/net/sunrpc/sysfs.c
@@ -9,6 +9,7 @@
#include "sysfs.h"
struct kobject *rpc_client_kobj;
+struct kobject *rpc_xprt_kobj;
static struct kset *rpc_sunrpc_kset;
static void rpc_netns_object_release(struct kobject *kobj)
@@ -48,13 +49,24 @@ int rpc_sysfs_init(void)
rpc_sunrpc_kset = kset_create_and_add("sunrpc", NULL, kernel_kobj);
if (!rpc_sunrpc_kset)
return -ENOMEM;
+
rpc_client_kobj = rpc_netns_object_alloc("client", rpc_sunrpc_kset, NULL);
- if (!rpc_client_kobj) {
- kset_unregister(rpc_sunrpc_kset);
- rpc_sunrpc_kset = NULL;
- return -ENOMEM;
- }
+ if (!rpc_client_kobj)
+ goto err_kset;
+
+ rpc_xprt_kobj = rpc_netns_object_alloc("transport", rpc_sunrpc_kset, NULL);
+ if (!rpc_xprt_kobj)
+ goto err_client;
+
return 0;
+
+err_client:
+ kobject_put(rpc_client_kobj);
+ rpc_client_kobj = NULL;
+err_kset:
+ kset_unregister(rpc_sunrpc_kset);
+ rpc_sunrpc_kset = NULL;
+ return -ENOMEM;
}
static ssize_t rpc_netns_dstaddr_show(struct kobject *kobj,
@@ -118,6 +130,7 @@ static struct kobj_type rpc_netns_client_type = {
void rpc_sysfs_exit(void)
{
+ kobject_put(rpc_xprt_kobj);
kobject_put(rpc_client_kobj);
kset_unregister(rpc_sunrpc_kset);
}
@@ -166,3 +179,111 @@ void rpc_netns_client_sysfs_destroy(struct rpc_clnt *clnt)
clnt->cl_sysfs = NULL;
}
}
+
+static ssize_t rpc_netns_xprt_dstaddr_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct rpc_netns_xprt *c = container_of(kobj,
+ struct rpc_netns_xprt, kobject);
+ struct rpc_xprt *xprt = c->xprt;
+
+ if (!(xprt->prot & (IPPROTO_TCP | XPRT_TRANSPORT_RDMA))) {
+ sprintf(buf, "N/A");
+ return 0;
+ }
+
+ return rpc_ntop((struct sockaddr *)&xprt->addr, buf, PAGE_SIZE);
+}
+
+static ssize_t rpc_netns_xprt_dstaddr_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct rpc_netns_xprt *c = container_of(kobj,
+ struct rpc_netns_xprt, kobject);
+ struct rpc_xprt *xprt = c->xprt;
+ struct sockaddr *saddr = (struct sockaddr *)&xprt->addr;
+ int port;
+
+ if (!(xprt->prot & (IPPROTO_TCP | XPRT_TRANSPORT_RDMA)))
+ return -EINVAL;
+
+ port = rpc_get_port(saddr);
+
+ xprt->addrlen = rpc_pton(xprt->xprt_net, buf, count - 1, saddr, sizeof(*saddr));
+ rpc_set_port(saddr, port);
+
+ kfree(xprt->address_strings[RPC_DISPLAY_ADDR]);
+ xprt->address_strings[RPC_DISPLAY_ADDR] = kstrndup(buf, count - 1, GFP_KERNEL);
+
+ xprt->ops->connect(xprt, NULL);
+ return count;
+}
+
+static void rpc_netns_xprt_release(struct kobject *kobj)
+{
+ struct rpc_netns_xprt *c;
+
+ c = container_of(kobj, struct rpc_netns_xprt, kobject);
+ kfree(c);
+}
+
+static const void *rpc_netns_xprt_namespace(struct kobject *kobj)
+{
+ return container_of(kobj, struct rpc_netns_xprt, kobject)->net;
+}
+
+static struct kobj_attribute rpc_netns_xprt_dstaddr = __ATTR(dstaddr,
+ 0644, rpc_netns_xprt_dstaddr_show, rpc_netns_xprt_dstaddr_store);
+
+static struct attribute *rpc_netns_xprt_attrs[] = {
+ &rpc_netns_xprt_dstaddr.attr,
+ NULL,
+};
+
+static struct kobj_type rpc_netns_xprt_type = {
+ .release = rpc_netns_xprt_release,
+ .default_attrs = rpc_netns_xprt_attrs,
+ .sysfs_ops = &kobj_sysfs_ops,
+ .namespace = rpc_netns_xprt_namespace,
+};
+
+static struct rpc_netns_xprt *rpc_netns_xprt_alloc(struct kobject *parent,
+ struct net *net, int id)
+{
+ struct rpc_netns_xprt *p;
+
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (p) {
+ p->net = net;
+ p->kobject.kset = rpc_sunrpc_kset;
+ if (kobject_init_and_add(&p->kobject, &rpc_netns_xprt_type,
+ parent, "%d", id) == 0)
+ return p;
+ kobject_put(&p->kobject);
+ }
+ return NULL;
+}
+
+void rpc_netns_xprt_sysfs_setup(struct rpc_xprt *xprt, struct net *net)
+{
+ struct rpc_netns_xprt *rpc_xprt;
+
+ rpc_xprt = rpc_netns_xprt_alloc(rpc_xprt_kobj, net, xprt->id);
+ if (rpc_xprt) {
+ xprt->sysfs = rpc_xprt;
+ rpc_xprt->xprt = xprt;
+ kobject_uevent(&rpc_xprt->kobject, KOBJ_ADD);
+ }
+}
+
+void rpc_netns_xprt_sysfs_destroy(struct rpc_xprt *xprt)
+{
+ struct rpc_netns_xprt *rpc_xprt = xprt->sysfs;
+
+ if (rpc_xprt) {
+ kobject_uevent(&rpc_xprt->kobject, KOBJ_REMOVE);
+ kobject_del(&rpc_xprt->kobject);
+ kobject_put(&rpc_xprt->kobject);
+ xprt->sysfs = NULL;
+ }
+}
diff --git a/net/sunrpc/sysfs.h b/net/sunrpc/sysfs.h
index ab75c3cc91b6..e08dd7f6a1ec 100644
--- a/net/sunrpc/sysfs.h
+++ b/net/sunrpc/sysfs.h
@@ -11,12 +11,21 @@ struct rpc_netns_client {
struct rpc_clnt *clnt;
};
+struct rpc_netns_xprt {
+ struct kobject kobject;
+ struct net *net;
+ struct rpc_xprt *xprt;
+};
+
extern struct kobject *rpc_client_kobj;
+extern struct kobject *rpc_xprt_kobj;
extern int rpc_sysfs_init(void);
extern void rpc_sysfs_exit(void);
void rpc_netns_client_sysfs_setup(struct rpc_clnt *clnt, struct net *net);
void rpc_netns_client_sysfs_destroy(struct rpc_clnt *clnt);
+void rpc_netns_xprt_sysfs_setup(struct rpc_xprt *xprt, struct net *net);
+void rpc_netns_xprt_sysfs_destroy(struct rpc_xprt *xprt);
#endif
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index e30acd1f0e31..4098cb6b1453 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -55,6 +55,7 @@
#include <trace/events/sunrpc.h>
#include "sunrpc.h"
+#include "sysfs.h"
/*
* Local variables
@@ -1768,6 +1769,7 @@ struct rpc_xprt *xprt_alloc(struct net *net, size_t size,
xprt->max_reqs = num_prealloc;
xprt->min_reqs = num_prealloc;
xprt->num_reqs = num_prealloc;
+ rpc_netns_xprt_sysfs_setup(xprt, net);
return xprt;
@@ -1780,6 +1782,7 @@ EXPORT_SYMBOL_GPL(xprt_alloc);
void xprt_free(struct rpc_xprt *xprt)
{
+ rpc_netns_xprt_sysfs_destroy(xprt);
put_net(xprt->xprt_net);
xprt_free_all_slots(xprt);
xprt_free_id(xprt);
--
2.26.2
next prev parent reply other threads:[~2021-02-15 17:41 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-15 17:39 [PATCH v1 0/8] sysfs files for multipath transport control Dan Aloni
2021-02-15 17:39 ` [PATCH v1 1/8] sunrpc: rename 'net' to 'client' Dan Aloni
2021-02-16 21:24 ` Anna Schumaker
2021-02-17 18:58 ` Dan Aloni
2021-02-15 17:39 ` [PATCH v1 2/8] sunrpc: add xprt id Dan Aloni
2021-02-15 17:39 ` Dan Aloni [this message]
2021-02-16 21:46 ` [PATCH v1 3/8] sunrpc: add a directory per sunrpc xprt Anna Schumaker
2021-02-17 19:01 ` Dan Aloni
2021-02-15 17:39 ` [PATCH v1 4/8] sunrpc: have client directory a symlink to the root transport Dan Aloni
2021-02-15 17:39 ` [PATCH v1 5/8] sunrpc: add IDs to multipath Dan Aloni
2021-02-15 17:40 ` [PATCH v1 6/8] sunrpc: add multipath directory and symlink from client Dan Aloni
2021-02-15 17:40 ` [PATCH v1 7/8] sunrpc: change rpc_clnt_add_xprt() to rpc_add_xprt() Dan Aloni
2021-02-15 17:40 ` [PATCH v1 8/8] sunrpc: introduce an 'add' node to 'multipath' sysfs directory Dan Aloni
2021-03-02 3:56 ` [PATCH v1 0/8] sysfs files for multipath transport control Olga Kornievskaia
2021-03-04 11:58 ` Dan Aloni
2021-03-04 18:39 ` Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210215174002.2376333-4-dan@kernelim.com \
--to=dan@kernelim.com \
--cc=anna.schumaker@netapp.com \
--cc=linux-nfs@vger.kernel.org \
--cc=trond.myklebust@hammerspace.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox