aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2006-08-22 20:06:20 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-09-22 23:24:49 -0400
commitc2866763b4029411d166040306691773c12d4caf (patch)
tree5b16b3a293843062234c5eaf377da2af93365266 /net/sunrpc/xprt.c
parent6ca948238724c945bd353f51d54ae7d285f3889f (diff)
SUNRPC: use sockaddr + size when creating remote transport endpoints
Prepare for more generic transport endpoint handling needed by transports that might use different forms of addressing, such as IPv6. Introduce a single function call to replace the two-call xprt_create_proto/rpc_create_client API. Define a new rpc_create_args structure that allows callers to pass in remote endpoint addresses of varying length. Test-plan: Compile kernel with CONFIG_NFS enabled. 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.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 4987517cc74b..17f56cfe2412 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -887,6 +887,81 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i
887 to->to_exponential = 0; 887 to->to_exponential = 0;
888} 888}
889 889
890/**
891 * xprt_create_transport - create an RPC transport
892 * @proto: requested transport protocol
893 * @ap: remote peer address
894 * @size: length of address
895 * @to: timeout parameters
896 *
897 */
898struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to)
899{
900 int result;
901 struct rpc_xprt *xprt;
902 struct rpc_rqst *req;
903
904 if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) {
905 dprintk("RPC: xprt_create_transport: no memory\n");
906 return ERR_PTR(-ENOMEM);
907 }
908 if (size <= sizeof(xprt->addr)) {
909 memcpy(&xprt->addr, ap, size);
910 xprt->addrlen = size;
911 } else {
912 kfree(xprt);
913 dprintk("RPC: xprt_create_transport: address too large\n");
914 return ERR_PTR(-EBADF);
915 }
916
917 switch (proto) {
918 case IPPROTO_UDP:
919 result = xs_setup_udp(xprt, to);
920 break;
921 case IPPROTO_TCP:
922 result = xs_setup_tcp(xprt, to);
923 break;
924 default:
925 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
926 proto);
927 return ERR_PTR(-EIO);
928 }
929 if (result) {
930 kfree(xprt);
931 dprintk("RPC: xprt_create_transport: failed, %d\n", result);
932 return ERR_PTR(result);
933 }
934
935 spin_lock_init(&xprt->transport_lock);
936 spin_lock_init(&xprt->reserve_lock);
937
938 INIT_LIST_HEAD(&xprt->free);
939 INIT_LIST_HEAD(&xprt->recv);
940 INIT_WORK(&xprt->task_cleanup, xprt_autoclose, xprt);
941 init_timer(&xprt->timer);
942 xprt->timer.function = xprt_init_autodisconnect;
943 xprt->timer.data = (unsigned long) xprt;
944 xprt->last_used = jiffies;
945 xprt->cwnd = RPC_INITCWND;
946
947 rpc_init_wait_queue(&xprt->binding, "xprt_binding");
948 rpc_init_wait_queue(&xprt->pending, "xprt_pending");
949 rpc_init_wait_queue(&xprt->sending, "xprt_sending");
950 rpc_init_wait_queue(&xprt->resend, "xprt_resend");
951 rpc_init_priority_wait_queue(&xprt->backlog, "xprt_backlog");
952
953 /* initialize free list */
954 for (req = &xprt->slot[xprt->max_reqs-1]; req >= &xprt->slot[0]; req--)
955 list_add(&req->rq_list, &xprt->free);
956
957 xprt_init_xid(xprt);
958
959 dprintk("RPC: created transport %p with %u slots\n", xprt,
960 xprt->max_reqs);
961
962 return xprt;
963}
964
890static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to) 965static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
891{ 966{
892 int result; 967 int result;