Skip to content

Commit

Permalink
SUNRPC: xprt_load_transport() needs to support the netid "rdma6"
Browse files Browse the repository at this point in the history
[ Upstream commit d5aa6b2 ]

According to RFC5666, the correct netid for an IPv6 addressed RDMA
transport is "rdma6", which we've supported as a mount option since
Linux-4.7. The problem is when we try to load the module "xprtrdma6",
that will fail, since there is no modulealias of that name.

Fixes: 181342c ("xprtrdma: Add rdma6 option to support NFS/RDMA IPv6")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Trond Myklebust authored and gregkh committed Dec 30, 2020
1 parent 78c9026 commit c1e628f
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 16 deletions.
1 change: 1 addition & 0 deletions include/linux/sunrpc/xprt.h
Expand Up @@ -330,6 +330,7 @@ struct xprt_class {
struct rpc_xprt * (*setup)(struct xprt_create *);
struct module *owner;
char name[32];
const char * netid[];
};

/*
Expand Down
65 changes: 49 additions & 16 deletions net/sunrpc/xprt.c
Expand Up @@ -151,31 +151,64 @@ int xprt_unregister_transport(struct xprt_class *transport)
}
EXPORT_SYMBOL_GPL(xprt_unregister_transport);

static void
xprt_class_release(const struct xprt_class *t)
{
module_put(t->owner);
}

static const struct xprt_class *
xprt_class_find_by_netid_locked(const char *netid)
{
const struct xprt_class *t;
unsigned int i;

list_for_each_entry(t, &xprt_list, list) {
for (i = 0; t->netid[i][0] != '\0'; i++) {
if (strcmp(t->netid[i], netid) != 0)
continue;
if (!try_module_get(t->owner))
continue;
return t;
}
}
return NULL;
}

static const struct xprt_class *
xprt_class_find_by_netid(const char *netid)
{
const struct xprt_class *t;

spin_lock(&xprt_list_lock);
t = xprt_class_find_by_netid_locked(netid);
if (!t) {
spin_unlock(&xprt_list_lock);
request_module("rpc%s", netid);
spin_lock(&xprt_list_lock);
t = xprt_class_find_by_netid_locked(netid);
}
spin_unlock(&xprt_list_lock);
return t;
}

/**
* xprt_load_transport - load a transport implementation
* @transport_name: transport to load
* @netid: transport to load
*
* Returns:
* 0: transport successfully loaded
* -ENOENT: transport module not available
*/
int xprt_load_transport(const char *transport_name)
int xprt_load_transport(const char *netid)
{
struct xprt_class *t;
int result;
const struct xprt_class *t;

result = 0;
spin_lock(&xprt_list_lock);
list_for_each_entry(t, &xprt_list, list) {
if (strcmp(t->name, transport_name) == 0) {
spin_unlock(&xprt_list_lock);
goto out;
}
}
spin_unlock(&xprt_list_lock);
result = request_module("xprt%s", transport_name);
out:
return result;
t = xprt_class_find_by_netid(netid);
if (!t)
return -ENOENT;
xprt_class_release(t);
return 0;
}
EXPORT_SYMBOL_GPL(xprt_load_transport);

Expand Down
1 change: 1 addition & 0 deletions net/sunrpc/xprtrdma/module.c
Expand Up @@ -24,6 +24,7 @@ MODULE_DESCRIPTION("RPC/RDMA Transport");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("svcrdma");
MODULE_ALIAS("xprtrdma");
MODULE_ALIAS("rpcrdma6");

static void __exit rpc_rdma_cleanup(void)
{
Expand Down
1 change: 1 addition & 0 deletions net/sunrpc/xprtrdma/transport.c
Expand Up @@ -768,6 +768,7 @@ static struct xprt_class xprt_rdma = {
.owner = THIS_MODULE,
.ident = XPRT_TRANSPORT_RDMA,
.setup = xprt_setup_rdma,
.netid = { "rdma", "rdma6", "" },
};

void xprt_rdma_cleanup(void)
Expand Down
4 changes: 4 additions & 0 deletions net/sunrpc/xprtsock.c
Expand Up @@ -3059,6 +3059,7 @@ static struct xprt_class xs_local_transport = {
.owner = THIS_MODULE,
.ident = XPRT_TRANSPORT_LOCAL,
.setup = xs_setup_local,
.netid = { "" },
};

static struct xprt_class xs_udp_transport = {
Expand All @@ -3067,6 +3068,7 @@ static struct xprt_class xs_udp_transport = {
.owner = THIS_MODULE,
.ident = XPRT_TRANSPORT_UDP,
.setup = xs_setup_udp,
.netid = { "udp", "udp6", "" },
};

static struct xprt_class xs_tcp_transport = {
Expand All @@ -3075,6 +3077,7 @@ static struct xprt_class xs_tcp_transport = {
.owner = THIS_MODULE,
.ident = XPRT_TRANSPORT_TCP,
.setup = xs_setup_tcp,
.netid = { "tcp", "tcp6", "" },
};

static struct xprt_class xs_bc_tcp_transport = {
Expand All @@ -3083,6 +3086,7 @@ static struct xprt_class xs_bc_tcp_transport = {
.owner = THIS_MODULE,
.ident = XPRT_TRANSPORT_BC_TCP,
.setup = xs_setup_bc_tcp,
.netid = { "" },
};

/**
Expand Down

0 comments on commit c1e628f

Please sign in to comment.