diff options
author | \"Talpey, Thomas\ <Thomas.Talpey@netapp.com> | 2007-09-10 13:46:39 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-09 17:17:42 -0400 |
commit | bc25571e21e8bd053554209f5b1b228ad71e6b99 (patch) | |
tree | 4c008cc445f24c6b5501b2867b8ba7a752b5d710 | |
parent | 81c098af3da7981902e9f8163aeccc2467c4ba6d (diff) |
SUNRPC: Finish API to load RPC transport implementations dynamically
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>
-rw-r--r-- | net/sunrpc/xprt.c | 26 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 47 |
2 files changed, 57 insertions, 16 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 520859622af5..7f8c60b84396 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -983,19 +983,23 @@ struct rpc_xprt *xprt_create_transport(struct rpc_xprtsock_create *args) | |||
983 | { | 983 | { |
984 | struct rpc_xprt *xprt; | 984 | struct rpc_xprt *xprt; |
985 | struct rpc_rqst *req; | 985 | struct rpc_rqst *req; |
986 | struct xprt_class *t; | ||
986 | 987 | ||
987 | switch (args->proto) { | 988 | spin_lock(&xprt_list_lock); |
988 | case IPPROTO_UDP: | 989 | list_for_each_entry(t, &xprt_list, list) { |
989 | xprt = xs_setup_udp(args); | 990 | if ((t->family == args->dstaddr->sa_family) && |
990 | break; | 991 | (t->protocol == args->proto)) { |
991 | case IPPROTO_TCP: | 992 | spin_unlock(&xprt_list_lock); |
992 | xprt = xs_setup_tcp(args); | 993 | goto found; |
993 | break; | 994 | } |
994 | default: | ||
995 | printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n", | ||
996 | args->proto); | ||
997 | return ERR_PTR(-EIO); | ||
998 | } | 995 | } |
996 | spin_unlock(&xprt_list_lock); | ||
997 | printk(KERN_ERR "RPC: transport (%u/%d) not supported\n", | ||
998 | args->dstaddr->sa_family, args->proto); | ||
999 | return ERR_PTR(-EIO); | ||
1000 | |||
1001 | found: | ||
1002 | xprt = t->setup(args); | ||
999 | if (IS_ERR(xprt)) { | 1003 | if (IS_ERR(xprt)) { |
1000 | dprintk("RPC: xprt_create_transport: failed, %ld\n", | 1004 | dprintk("RPC: xprt_create_transport: failed, %ld\n", |
1001 | -PTR_ERR(xprt)); | 1005 | -PTR_ERR(xprt)); |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 5bdce8fa2d56..3bc9c921c82f 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/module.h> | ||
23 | #include <linux/capability.h> | 24 | #include <linux/capability.h> |
24 | #include <linux/pagemap.h> | 25 | #include <linux/pagemap.h> |
25 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
@@ -777,6 +778,7 @@ static void xs_destroy(struct rpc_xprt *xprt) | |||
777 | xs_free_peer_addresses(xprt); | 778 | xs_free_peer_addresses(xprt); |
778 | kfree(xprt->slot); | 779 | kfree(xprt->slot); |
779 | kfree(xprt); | 780 | kfree(xprt); |
781 | module_put(THIS_MODULE); | ||
780 | } | 782 | } |
781 | 783 | ||
782 | static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) | 784 | static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) |
@@ -1782,7 +1784,8 @@ static struct rpc_xprt_ops xs_tcp_ops = { | |||
1782 | .print_stats = xs_tcp_print_stats, | 1784 | .print_stats = xs_tcp_print_stats, |
1783 | }; | 1785 | }; |
1784 | 1786 | ||
1785 | static struct rpc_xprt *xs_setup_xprt(struct rpc_xprtsock_create *args, unsigned int slot_table_size) | 1787 | static struct rpc_xprt *xs_setup_xprt(struct rpc_xprtsock_create *args, |
1788 | unsigned int slot_table_size) | ||
1786 | { | 1789 | { |
1787 | struct rpc_xprt *xprt; | 1790 | struct rpc_xprt *xprt; |
1788 | struct sock_xprt *new; | 1791 | struct sock_xprt *new; |
@@ -1876,7 +1879,12 @@ struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args) | |||
1876 | dprintk("RPC: set up transport to address %s\n", | 1879 | dprintk("RPC: set up transport to address %s\n", |
1877 | xprt->address_strings[RPC_DISPLAY_ALL]); | 1880 | xprt->address_strings[RPC_DISPLAY_ALL]); |
1878 | 1881 | ||
1879 | return xprt; | 1882 | if (try_module_get(THIS_MODULE)) |
1883 | return xprt; | ||
1884 | |||
1885 | kfree(xprt->slot); | ||
1886 | kfree(xprt); | ||
1887 | return ERR_PTR(-EINVAL); | ||
1880 | } | 1888 | } |
1881 | 1889 | ||
1882 | /** | 1890 | /** |
@@ -1934,11 +1942,34 @@ struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args) | |||
1934 | dprintk("RPC: set up transport to address %s\n", | 1942 | dprintk("RPC: set up transport to address %s\n", |
1935 | xprt->address_strings[RPC_DISPLAY_ALL]); | 1943 | xprt->address_strings[RPC_DISPLAY_ALL]); |
1936 | 1944 | ||
1937 | return xprt; | 1945 | if (try_module_get(THIS_MODULE)) |
1946 | return xprt; | ||
1947 | |||
1948 | kfree(xprt->slot); | ||
1949 | kfree(xprt); | ||
1950 | return ERR_PTR(-EINVAL); | ||
1938 | } | 1951 | } |
1939 | 1952 | ||
1953 | static struct xprt_class xs_udp_transport = { | ||
1954 | .list = LIST_HEAD_INIT(xs_udp_transport.list), | ||
1955 | .name = "udp", | ||
1956 | .owner = THIS_MODULE, | ||
1957 | .family = AF_INET, | ||
1958 | .protocol = IPPROTO_UDP, | ||
1959 | .setup = xs_setup_udp, | ||
1960 | }; | ||
1961 | |||
1962 | static struct xprt_class xs_tcp_transport = { | ||
1963 | .list = LIST_HEAD_INIT(xs_tcp_transport.list), | ||
1964 | .name = "tcp", | ||
1965 | .owner = THIS_MODULE, | ||
1966 | .family = AF_INET, | ||
1967 | .protocol = IPPROTO_TCP, | ||
1968 | .setup = xs_setup_tcp, | ||
1969 | }; | ||
1970 | |||
1940 | /** | 1971 | /** |
1941 | * init_socket_xprt - set up xprtsock's sysctls | 1972 | * init_socket_xprt - set up xprtsock's sysctls, register with RPC client |
1942 | * | 1973 | * |
1943 | */ | 1974 | */ |
1944 | int init_socket_xprt(void) | 1975 | int init_socket_xprt(void) |
@@ -1948,11 +1979,14 @@ int init_socket_xprt(void) | |||
1948 | sunrpc_table_header = register_sysctl_table(sunrpc_table); | 1979 | sunrpc_table_header = register_sysctl_table(sunrpc_table); |
1949 | #endif | 1980 | #endif |
1950 | 1981 | ||
1982 | xprt_register_transport(&xs_udp_transport); | ||
1983 | xprt_register_transport(&xs_tcp_transport); | ||
1984 | |||
1951 | return 0; | 1985 | return 0; |
1952 | } | 1986 | } |
1953 | 1987 | ||
1954 | /** | 1988 | /** |
1955 | * cleanup_socket_xprt - remove xprtsock's sysctls | 1989 | * cleanup_socket_xprt - remove xprtsock's sysctls, unregister |
1956 | * | 1990 | * |
1957 | */ | 1991 | */ |
1958 | void cleanup_socket_xprt(void) | 1992 | void cleanup_socket_xprt(void) |
@@ -1963,4 +1997,7 @@ void cleanup_socket_xprt(void) | |||
1963 | sunrpc_table_header = NULL; | 1997 | sunrpc_table_header = NULL; |
1964 | } | 1998 | } |
1965 | #endif | 1999 | #endif |
2000 | |||
2001 | xprt_unregister_transport(&xs_udp_transport); | ||
2002 | xprt_unregister_transport(&xs_tcp_transport); | ||
1966 | } | 2003 | } |