diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2006-10-17 14:44:27 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-12-06 10:46:34 -0500 |
commit | c8541ecdd5692bcfbcb5305cab9a873288d29175 (patch) | |
tree | 45714725337f22a5eb27cbe5b87c3b01f37c9490 /net/sunrpc/xprt.c | |
parent | e744cf2e3ab8535a8494a4cf0177de26f94586da (diff) |
SUNRPC: Make the transport-specific setup routine allocate rpc_xprt
Change the location where the rpc_xprt structure is allocated so each
transport implementation can allocate a private area from the same
chunk of memory.
Note also that xprt->ops->destroy, rather than xprt_destroy, is now
responsible for freeing rpc_xprt when the transport is destroyed.
Test plan:
Connectathon.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r-- | net/sunrpc/xprt.c | 31 |
1 files changed, 10 insertions, 21 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 80857470dc11..8cc2afa2942c 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -891,39 +891,25 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i | |||
891 | */ | 891 | */ |
892 | struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to) | 892 | struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to) |
893 | { | 893 | { |
894 | int result; | ||
895 | struct rpc_xprt *xprt; | 894 | struct rpc_xprt *xprt; |
896 | struct rpc_rqst *req; | 895 | struct rpc_rqst *req; |
897 | 896 | ||
898 | if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) { | ||
899 | dprintk("RPC: xprt_create_transport: no memory\n"); | ||
900 | return ERR_PTR(-ENOMEM); | ||
901 | } | ||
902 | if (size <= sizeof(xprt->addr)) { | ||
903 | memcpy(&xprt->addr, ap, size); | ||
904 | xprt->addrlen = size; | ||
905 | } else { | ||
906 | kfree(xprt); | ||
907 | dprintk("RPC: xprt_create_transport: address too large\n"); | ||
908 | return ERR_PTR(-EBADF); | ||
909 | } | ||
910 | |||
911 | switch (proto) { | 897 | switch (proto) { |
912 | case IPPROTO_UDP: | 898 | case IPPROTO_UDP: |
913 | result = xs_setup_udp(xprt, to); | 899 | xprt = xs_setup_udp(ap, size, to); |
914 | break; | 900 | break; |
915 | case IPPROTO_TCP: | 901 | case IPPROTO_TCP: |
916 | result = xs_setup_tcp(xprt, to); | 902 | xprt = xs_setup_tcp(ap, size, to); |
917 | break; | 903 | break; |
918 | default: | 904 | default: |
919 | printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n", | 905 | printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n", |
920 | proto); | 906 | proto); |
921 | return ERR_PTR(-EIO); | 907 | return ERR_PTR(-EIO); |
922 | } | 908 | } |
923 | if (result) { | 909 | if (IS_ERR(xprt)) { |
924 | kfree(xprt); | 910 | dprintk("RPC: xprt_create_transport: failed, %ld\n", |
925 | dprintk("RPC: xprt_create_transport: failed, %d\n", result); | 911 | -PTR_ERR(xprt)); |
926 | return ERR_PTR(result); | 912 | return xprt; |
927 | } | 913 | } |
928 | 914 | ||
929 | kref_init(&xprt->kref); | 915 | kref_init(&xprt->kref); |
@@ -969,8 +955,11 @@ static void xprt_destroy(struct kref *kref) | |||
969 | dprintk("RPC: destroying transport %p\n", xprt); | 955 | dprintk("RPC: destroying transport %p\n", xprt); |
970 | xprt->shutdown = 1; | 956 | xprt->shutdown = 1; |
971 | del_timer_sync(&xprt->timer); | 957 | del_timer_sync(&xprt->timer); |
958 | |||
959 | /* | ||
960 | * Tear down transport state and free the rpc_xprt | ||
961 | */ | ||
972 | xprt->ops->destroy(xprt); | 962 | xprt->ops->destroy(xprt); |
973 | kfree(xprt); | ||
974 | } | 963 | } |
975 | 964 | ||
976 | /** | 965 | /** |