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 6/8] sunrpc: add multipath directory and symlink from client
Date: Mon, 15 Feb 2021 19:40:00 +0200 [thread overview]
Message-ID: <20210215174002.2376333-7-dan@kernelim.com> (raw)
In-Reply-To: <20210215174002.2376333-1-dan@kernelim.com>
This also adds a `list` attribute to multipath directory that provides
the transport IDs of the transports contained in the multipath object.
Signed-off-by: Dan Aloni <dan@kernelim.com>
---
include/linux/sunrpc/xprtmultipath.h | 2 +
net/sunrpc/sysfs.c | 122 +++++++++++++++++++++++++++
net/sunrpc/sysfs.h | 8 ++
net/sunrpc/xprtmultipath.c | 10 +++
4 files changed, 142 insertions(+)
diff --git a/include/linux/sunrpc/xprtmultipath.h b/include/linux/sunrpc/xprtmultipath.h
index ef95a6f18ccf..2d0832dc10f5 100644
--- a/include/linux/sunrpc/xprtmultipath.h
+++ b/include/linux/sunrpc/xprtmultipath.h
@@ -24,6 +24,8 @@ struct rpc_xprt_switch {
const struct rpc_xprt_iter_ops *xps_iter_ops;
+ void *xps_sysfs; /* /sys/kernel/sunrpc/multipath/<id> */
+
struct rcu_head xps_rcu;
};
diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c
index ae608235d7e0..3592f3b862b2 100644
--- a/net/sunrpc/sysfs.c
+++ b/net/sunrpc/sysfs.c
@@ -10,6 +10,7 @@
struct kobject *rpc_client_kobj;
struct kobject *rpc_xprt_kobj;
+struct kobject *rpc_xps_kobj;
static struct kset *rpc_sunrpc_kset;
static void rpc_netns_object_release(struct kobject *kobj)
@@ -58,8 +59,15 @@ int rpc_sysfs_init(void)
if (!rpc_xprt_kobj)
goto err_client;
+ rpc_xps_kobj = rpc_netns_object_alloc("multipath", rpc_sunrpc_kset, NULL);
+ if (!rpc_xps_kobj)
+ goto err_xprt;
+
return 0;
+err_xprt:
+ kobject_put(rpc_xprt_kobj);
+ rpc_xprt_kobj = NULL;
err_client:
kobject_put(rpc_client_kobj);
rpc_client_kobj = NULL;
@@ -95,6 +103,7 @@ static struct kobj_type rpc_netns_client_type = {
void rpc_sysfs_exit(void)
{
+ kobject_put(rpc_xps_kobj);
kobject_put(rpc_xprt_kobj);
kobject_put(rpc_client_kobj);
kset_unregister(rpc_sunrpc_kset);
@@ -122,17 +131,29 @@ void rpc_netns_client_sysfs_setup(struct rpc_clnt *clnt, struct net *net)
struct rpc_netns_client *rpc_client;
struct rpc_xprt *xprt = rcu_dereference(clnt->cl_xprt);
struct rpc_netns_xprt *rpc_xprt;
+ struct rpc_netns_multipath *rpc_multipath;
+ struct rpc_xprt_switch *xps;
int ret;
+ xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch));
+
rpc_client = rpc_netns_client_alloc(rpc_client_kobj, net, clnt->cl_clid);
if (rpc_client) {
rpc_xprt = xprt->sysfs;
ret = sysfs_create_link_nowarn(&rpc_client->kobject,
&rpc_xprt->kobject, "transport");
+ if (xps) {
+ rpc_multipath = xps->xps_sysfs;
+ ret = sysfs_create_link_nowarn(&rpc_client->kobject,
+ &rpc_multipath->kobject,
+ "multipath");
+ }
clnt->cl_sysfs = rpc_client;
rpc_client->clnt = clnt;
kobject_uevent(&rpc_client->kobject, KOBJ_ADD);
}
+
+ xprt_switch_put(xps);
}
void rpc_netns_client_sysfs_destroy(struct rpc_clnt *clnt)
@@ -141,6 +162,7 @@ void rpc_netns_client_sysfs_destroy(struct rpc_clnt *clnt)
if (rpc_client) {
sysfs_remove_link(&rpc_client->kobject, "transport");
+ sysfs_remove_link(&rpc_client->kobject, "multipath");
kobject_uevent(&rpc_client->kobject, KOBJ_REMOVE);
kobject_del(&rpc_client->kobject);
kobject_put(&rpc_client->kobject);
@@ -255,3 +277,103 @@ void rpc_netns_xprt_sysfs_destroy(struct rpc_xprt *xprt)
xprt->sysfs = NULL;
}
}
+
+static void rpc_netns_multipath_release(struct kobject *kobj)
+{
+ struct rpc_netns_multipath *c;
+
+ c = container_of(kobj, struct rpc_netns_multipath, kobject);
+ kfree(c);
+}
+
+static const void *rpc_netns_multipath_namespace(struct kobject *kobj)
+{
+ return container_of(kobj, struct rpc_netns_multipath, kobject)->net;
+}
+
+static ssize_t rpc_netns_multipath_list_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct rpc_netns_multipath *c =
+ container_of(kobj, struct rpc_netns_multipath, kobject);
+ struct rpc_xprt_switch *xps = c->xps;
+ struct rpc_xprt_iter xpi;
+ int pos = 0;
+
+ xprt_iter_init_listall(&xpi, xps);
+ for (;;) {
+ struct rpc_xprt *xprt = xprt_iter_get_next(&xpi);
+ if (!xprt)
+ break;
+
+ snprintf(&buf[pos], PAGE_SIZE - pos, "%d\n", xprt->id);
+ pos += strlen(&buf[pos]);
+ xprt_put(xprt);
+ }
+ xprt_iter_destroy(&xpi);
+
+ return pos;
+}
+
+static ssize_t rpc_netns_multipath_list_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ return -EINVAL;
+}
+
+static struct kobj_attribute rpc_netns_multipath_list = __ATTR(list,
+ 0644, rpc_netns_multipath_list_show, rpc_netns_multipath_list_store);
+
+
+static struct attribute *rpc_netns_multipath_attrs[] = {
+ &rpc_netns_multipath_list.attr,
+ NULL,
+};
+
+static struct kobj_type rpc_netns_multipath_type = {
+ .release = rpc_netns_multipath_release,
+ .default_attrs = rpc_netns_multipath_attrs,
+ .sysfs_ops = &kobj_sysfs_ops,
+ .namespace = rpc_netns_multipath_namespace,
+};
+
+static struct rpc_netns_multipath *rpc_netns_multipath_alloc(struct kobject *parent,
+ struct net *net, int id)
+{
+ struct rpc_netns_multipath *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_multipath_type,
+ parent, "%d", id) == 0)
+ return p;
+ kobject_put(&p->kobject);
+ }
+ return NULL;
+}
+
+void rpc_netns_multipath_sysfs_setup(struct rpc_xprt_switch *xps, struct net *net)
+{
+ struct rpc_netns_multipath *rpc_multipath;
+
+ rpc_multipath = rpc_netns_multipath_alloc(rpc_xps_kobj, net, xps->xps_id);
+ if (rpc_multipath) {
+ xps->xps_sysfs = rpc_multipath;
+ rpc_multipath->xps = xps;
+ kobject_uevent(&rpc_multipath->kobject, KOBJ_ADD);
+ }
+}
+
+void rpc_netns_multipath_sysfs_destroy(struct rpc_xprt_switch *xps)
+{
+ struct rpc_netns_multipath *rpc_multipath = xps->xps_sysfs;
+
+ if (rpc_multipath) {
+ kobject_uevent(&rpc_multipath->kobject, KOBJ_REMOVE);
+ kobject_del(&rpc_multipath->kobject);
+ kobject_put(&rpc_multipath->kobject);
+ xps->xps_sysfs = NULL;
+ }
+}
diff --git a/net/sunrpc/sysfs.h b/net/sunrpc/sysfs.h
index e08dd7f6a1ec..b2e379f78b91 100644
--- a/net/sunrpc/sysfs.h
+++ b/net/sunrpc/sysfs.h
@@ -17,6 +17,12 @@ struct rpc_netns_xprt {
struct rpc_xprt *xprt;
};
+struct rpc_netns_multipath {
+ struct kobject kobject;
+ struct net *net;
+ struct rpc_xprt_switch *xps;
+};
+
extern struct kobject *rpc_client_kobj;
extern struct kobject *rpc_xprt_kobj;
@@ -27,5 +33,7 @@ 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);
+void rpc_netns_multipath_sysfs_setup(struct rpc_xprt_switch *xps, struct net *net);
+void rpc_netns_multipath_sysfs_destroy(struct rpc_xprt_switch *xps);
#endif
diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c
index 52a9584b23af..d03fb3bb74ce 100644
--- a/net/sunrpc/xprtmultipath.c
+++ b/net/sunrpc/xprtmultipath.c
@@ -19,6 +19,8 @@
#include <linux/sunrpc/addr.h>
#include <linux/sunrpc/xprtmultipath.h>
+#include "sysfs.h"
+
typedef struct rpc_xprt *(*xprt_switch_find_xprt_t)(struct rpc_xprt_switch *xps,
const struct rpc_xprt *cur);
@@ -83,6 +85,9 @@ void rpc_xprt_switch_remove_xprt(struct rpc_xprt_switch *xps,
spin_lock(&xps->xps_lock);
xprt_switch_remove_xprt_locked(xps, xprt);
spin_unlock(&xps->xps_lock);
+
+ if (!xps->xps_net)
+ rpc_netns_multipath_sysfs_destroy(xps);
xprt_put(xprt);
}
@@ -135,6 +140,10 @@ struct rpc_xprt_switch *xprt_switch_alloc(struct rpc_xprt *xprt,
INIT_LIST_HEAD(&xps->xps_xprt_list);
xps->xps_iter_ops = &rpc_xprt_iter_singular;
xprt_switch_add_xprt_locked(xps, xprt);
+ xps->xps_sysfs = NULL;
+
+ if (xprt->xprt_net != NULL)
+ rpc_netns_multipath_sysfs_setup(xps, xprt->xprt_net);
}
return xps;
@@ -162,6 +171,7 @@ static void xprt_switch_free(struct kref *kref)
struct rpc_xprt_switch, xps_kref);
xprt_switch_free_entries(xps);
+ rpc_netns_multipath_sysfs_destroy(xps);
xprt_switch_free_id(xps);
kfree_rcu(xps, xps_rcu);
}
--
2.26.2
next prev parent reply other threads:[~2021-02-15 17:42 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 ` [PATCH v1 3/8] sunrpc: add a directory per sunrpc xprt Dan Aloni
2021-02-16 21:46 ` 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 ` Dan Aloni [this message]
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-7-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.