Skip to content

Commit

Permalink
SUNRPC: Finish API to load RPC transport implementations dynamically
Browse files Browse the repository at this point in the history
Allow RPC client transport implementations to be loaded as needed, or
as they become available from distributors or third-party vendors.

Note that we leave the IP sockets implementation in sunrpc.o
permanently, as IP functionality is always available in any
kernel that runs NFS.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Tom Talpey <tmt@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
\"Talpey, Thomas\ authored and Trond Myklebust committed Oct 9, 2007
1 parent 81c098a commit bc25571
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 16 deletions.
26 changes: 15 additions & 11 deletions net/sunrpc/xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -983,19 +983,23 @@ struct rpc_xprt *xprt_create_transport(struct rpc_xprtsock_create *args)
{
struct rpc_xprt *xprt;
struct rpc_rqst *req;
struct xprt_class *t;

switch (args->proto) {
case IPPROTO_UDP:
xprt = xs_setup_udp(args);
break;
case IPPROTO_TCP:
xprt = xs_setup_tcp(args);
break;
default:
printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
args->proto);
return ERR_PTR(-EIO);
spin_lock(&xprt_list_lock);
list_for_each_entry(t, &xprt_list, list) {
if ((t->family == args->dstaddr->sa_family) &&
(t->protocol == args->proto)) {
spin_unlock(&xprt_list_lock);
goto found;
}
}
spin_unlock(&xprt_list_lock);
printk(KERN_ERR "RPC: transport (%u/%d) not supported\n",
args->dstaddr->sa_family, args->proto);
return ERR_PTR(-EIO);

found:
xprt = t->setup(args);
if (IS_ERR(xprt)) {
dprintk("RPC: xprt_create_transport: failed, %ld\n",
-PTR_ERR(xprt));
Expand Down
47 changes: 42 additions & 5 deletions net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <linux/types.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/capability.h>
#include <linux/pagemap.h>
#include <linux/errno.h>
Expand Down Expand Up @@ -777,6 +778,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
xs_free_peer_addresses(xprt);
kfree(xprt->slot);
kfree(xprt);
module_put(THIS_MODULE);
}

static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
Expand Down Expand Up @@ -1782,7 +1784,8 @@ static struct rpc_xprt_ops xs_tcp_ops = {
.print_stats = xs_tcp_print_stats,
};

static struct rpc_xprt *xs_setup_xprt(struct rpc_xprtsock_create *args, unsigned int slot_table_size)
static struct rpc_xprt *xs_setup_xprt(struct rpc_xprtsock_create *args,
unsigned int slot_table_size)
{
struct rpc_xprt *xprt;
struct sock_xprt *new;
Expand Down Expand Up @@ -1876,7 +1879,12 @@ struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args)
dprintk("RPC: set up transport to address %s\n",
xprt->address_strings[RPC_DISPLAY_ALL]);

return xprt;
if (try_module_get(THIS_MODULE))
return xprt;

kfree(xprt->slot);
kfree(xprt);
return ERR_PTR(-EINVAL);
}

/**
Expand Down Expand Up @@ -1934,11 +1942,34 @@ struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args)
dprintk("RPC: set up transport to address %s\n",
xprt->address_strings[RPC_DISPLAY_ALL]);

return xprt;
if (try_module_get(THIS_MODULE))
return xprt;

kfree(xprt->slot);
kfree(xprt);
return ERR_PTR(-EINVAL);
}

static struct xprt_class xs_udp_transport = {
.list = LIST_HEAD_INIT(xs_udp_transport.list),
.name = "udp",
.owner = THIS_MODULE,
.family = AF_INET,
.protocol = IPPROTO_UDP,
.setup = xs_setup_udp,
};

static struct xprt_class xs_tcp_transport = {
.list = LIST_HEAD_INIT(xs_tcp_transport.list),
.name = "tcp",
.owner = THIS_MODULE,
.family = AF_INET,
.protocol = IPPROTO_TCP,
.setup = xs_setup_tcp,
};

/**
* init_socket_xprt - set up xprtsock's sysctls
* init_socket_xprt - set up xprtsock's sysctls, register with RPC client
*
*/
int init_socket_xprt(void)
Expand All @@ -1948,11 +1979,14 @@ int init_socket_xprt(void)
sunrpc_table_header = register_sysctl_table(sunrpc_table);
#endif

xprt_register_transport(&xs_udp_transport);
xprt_register_transport(&xs_tcp_transport);

return 0;
}

/**
* cleanup_socket_xprt - remove xprtsock's sysctls
* cleanup_socket_xprt - remove xprtsock's sysctls, unregister
*
*/
void cleanup_socket_xprt(void)
Expand All @@ -1963,4 +1997,7 @@ void cleanup_socket_xprt(void)
sunrpc_table_header = NULL;
}
#endif

xprt_unregister_transport(&xs_udp_transport);
xprt_unregister_transport(&xs_tcp_transport);
}

0 comments on commit bc25571

Please sign in to comment.