lkml.org 
[lkml]   [2020]   [Dec]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 190/346] SUNRPC: xprt_load_transport() needs to support the netid "rdma6"
    Date
    From: Trond Myklebust <trond.myklebust@hammerspace.com>

    [ Upstream commit d5aa6b22e2258f05317313ecc02efbb988ed6d38 ]

    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: 181342c5ebe8 ("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>
    ---
    include/linux/sunrpc/xprt.h | 1 +
    net/sunrpc/xprt.c | 65 +++++++++++++++++++++++++--------
    net/sunrpc/xprtrdma/module.c | 1 +
    net/sunrpc/xprtrdma/transport.c | 1 +
    net/sunrpc/xprtsock.c | 4 ++
    5 files changed, 56 insertions(+), 16 deletions(-)

    diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
    index e7bbd82908b10..69fed13e633b7 100644
    --- a/include/linux/sunrpc/xprt.h
    +++ b/include/linux/sunrpc/xprt.h
    @@ -317,6 +317,7 @@ struct xprt_class {
    struct rpc_xprt * (*setup)(struct xprt_create *);
    struct module *owner;
    char name[32];
    + const char * netid[];
    };

    /*
    diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
    index 5e7c13aa66d0d..9c4235ce57894 100644
    --- a/net/sunrpc/xprt.c
    +++ b/net/sunrpc/xprt.c
    @@ -143,31 +143,64 @@ out:
    }
    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);

    diff --git a/net/sunrpc/xprtrdma/module.c b/net/sunrpc/xprtrdma/module.c
    index 620327c01302c..45c5b41ac8dc9 100644
    --- a/net/sunrpc/xprtrdma/module.c
    +++ b/net/sunrpc/xprtrdma/module.c
    @@ -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)
    {
    diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
    index f56f36b4d742d..fdd14908eacbd 100644
    --- a/net/sunrpc/xprtrdma/transport.c
    +++ b/net/sunrpc/xprtrdma/transport.c
    @@ -854,6 +854,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)
    diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
    index 9dc059dea689d..798fbd89ed42f 100644
    --- a/net/sunrpc/xprtsock.c
    +++ b/net/sunrpc/xprtsock.c
    @@ -3241,6 +3241,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 = {
    @@ -3249,6 +3250,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 = {
    @@ -3257,6 +3259,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 = {
    @@ -3265,6 +3268,7 @@ static struct xprt_class xs_bc_tcp_transport = {
    .owner = THIS_MODULE,
    .ident = XPRT_TRANSPORT_BC_TCP,
    .setup = xs_setup_bc_tcp,
    + .netid = { "" },
    };

    /**
    --
    2.27.0


    \
     
     \ /
      Last update: 2020-12-28 14:32    [W:4.487 / U:0.592 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site