aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c86
1 files changed, 50 insertions, 36 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index e8c2bc4977f3..1f786f68729d 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -534,7 +534,7 @@ void xprt_connect(struct rpc_task *task)
534 dprintk("RPC: %4d xprt_connect xprt %p %s connected\n", task->tk_pid, 534 dprintk("RPC: %4d xprt_connect xprt %p %s connected\n", task->tk_pid,
535 xprt, (xprt_connected(xprt) ? "is" : "is not")); 535 xprt, (xprt_connected(xprt) ? "is" : "is not"));
536 536
537 if (!xprt->addr.sin_port) { 537 if (!xprt_bound(xprt)) {
538 task->tk_status = -EIO; 538 task->tk_status = -EIO;
539 return; 539 return;
540 } 540 }
@@ -585,13 +585,6 @@ static void xprt_connect_status(struct rpc_task *task)
585 task->tk_pid, -task->tk_status, task->tk_client->cl_server); 585 task->tk_pid, -task->tk_status, task->tk_client->cl_server);
586 xprt_release_write(xprt, task); 586 xprt_release_write(xprt, task);
587 task->tk_status = -EIO; 587 task->tk_status = -EIO;
588 return;
589 }
590
591 /* if soft mounted, just cause this RPC to fail */
592 if (RPC_IS_SOFT(task)) {
593 xprt_release_write(xprt, task);
594 task->tk_status = -EIO;
595 } 588 }
596} 589}
597 590
@@ -829,6 +822,7 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
829 req->rq_bufsize = 0; 822 req->rq_bufsize = 0;
830 req->rq_xid = xprt_alloc_xid(xprt); 823 req->rq_xid = xprt_alloc_xid(xprt);
831 req->rq_release_snd_buf = NULL; 824 req->rq_release_snd_buf = NULL;
825 xprt_reset_majortimeo(req);
832 dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, 826 dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
833 req, ntohl(req->rq_xid)); 827 req, ntohl(req->rq_xid));
834} 828}
@@ -887,16 +881,32 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i
887 to->to_exponential = 0; 881 to->to_exponential = 0;
888} 882}
889 883
890static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to) 884/**
885 * xprt_create_transport - create an RPC transport
886 * @proto: requested transport protocol
887 * @ap: remote peer address
888 * @size: length of address
889 * @to: timeout parameters
890 *
891 */
892struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to)
891{ 893{
892 int result; 894 int result;
893 struct rpc_xprt *xprt; 895 struct rpc_xprt *xprt;
894 struct rpc_rqst *req; 896 struct rpc_rqst *req;
895 897
896 if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) 898 if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) {
899 dprintk("RPC: xprt_create_transport: no memory\n");
897 return ERR_PTR(-ENOMEM); 900 return ERR_PTR(-ENOMEM);
898 901 }
899 xprt->addr = *ap; 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 }
900 910
901 switch (proto) { 911 switch (proto) {
902 case IPPROTO_UDP: 912 case IPPROTO_UDP:
@@ -908,14 +918,15 @@ static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc
908 default: 918 default:
909 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n", 919 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
910 proto); 920 proto);
911 result = -EIO; 921 return ERR_PTR(-EIO);
912 break;
913 } 922 }
914 if (result) { 923 if (result) {
915 kfree(xprt); 924 kfree(xprt);
925 dprintk("RPC: xprt_create_transport: failed, %d\n", result);
916 return ERR_PTR(result); 926 return ERR_PTR(result);
917 } 927 }
918 928
929 kref_init(&xprt->kref);
919 spin_lock_init(&xprt->transport_lock); 930 spin_lock_init(&xprt->transport_lock);
920 spin_lock_init(&xprt->reserve_lock); 931 spin_lock_init(&xprt->reserve_lock);
921 932
@@ -928,6 +939,7 @@ static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc
928 xprt->last_used = jiffies; 939 xprt->last_used = jiffies;
929 xprt->cwnd = RPC_INITCWND; 940 xprt->cwnd = RPC_INITCWND;
930 941
942 rpc_init_wait_queue(&xprt->binding, "xprt_binding");
931 rpc_init_wait_queue(&xprt->pending, "xprt_pending"); 943 rpc_init_wait_queue(&xprt->pending, "xprt_pending");
932 rpc_init_wait_queue(&xprt->sending, "xprt_sending"); 944 rpc_init_wait_queue(&xprt->sending, "xprt_sending");
933 rpc_init_wait_queue(&xprt->resend, "xprt_resend"); 945 rpc_init_wait_queue(&xprt->resend, "xprt_resend");
@@ -941,41 +953,43 @@ static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc
941 953
942 dprintk("RPC: created transport %p with %u slots\n", xprt, 954 dprintk("RPC: created transport %p with %u slots\n", xprt,
943 xprt->max_reqs); 955 xprt->max_reqs);
944
945 return xprt;
946}
947 956
948/**
949 * xprt_create_proto - create an RPC client transport
950 * @proto: requested transport protocol
951 * @sap: remote peer's address
952 * @to: timeout parameters for new transport
953 *
954 */
955struct rpc_xprt *xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
956{
957 struct rpc_xprt *xprt;
958
959 xprt = xprt_setup(proto, sap, to);
960 if (IS_ERR(xprt))
961 dprintk("RPC: xprt_create_proto failed\n");
962 else
963 dprintk("RPC: xprt_create_proto created xprt %p\n", xprt);
964 return xprt; 957 return xprt;
965} 958}
966 959
967/** 960/**
968 * xprt_destroy - destroy an RPC transport, killing off all requests. 961 * xprt_destroy - destroy an RPC transport, killing off all requests.
969 * @xprt: transport to destroy 962 * @kref: kref for the transport to destroy
970 * 963 *
971 */ 964 */
972int xprt_destroy(struct rpc_xprt *xprt) 965static void xprt_destroy(struct kref *kref)
973{ 966{
967 struct rpc_xprt *xprt = container_of(kref, struct rpc_xprt, kref);
968
974 dprintk("RPC: destroying transport %p\n", xprt); 969 dprintk("RPC: destroying transport %p\n", xprt);
975 xprt->shutdown = 1; 970 xprt->shutdown = 1;
976 del_timer_sync(&xprt->timer); 971 del_timer_sync(&xprt->timer);
977 xprt->ops->destroy(xprt); 972 xprt->ops->destroy(xprt);
978 kfree(xprt); 973 kfree(xprt);
974}
979 975
980 return 0; 976/**
977 * xprt_put - release a reference to an RPC transport.
978 * @xprt: pointer to the transport
979 *
980 */
981void xprt_put(struct rpc_xprt *xprt)
982{
983 kref_put(&xprt->kref, xprt_destroy);
984}
985
986/**
987 * xprt_get - return a reference to an RPC transport.
988 * @xprt: pointer to the transport
989 *
990 */
991struct rpc_xprt *xprt_get(struct rpc_xprt *xprt)
992{
993 kref_get(&xprt->kref);
994 return xprt;
981} 995}