diff options
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r-- | net/sunrpc/xprt.c | 86 |
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 | ||
890 | static 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 | */ | ||
892 | struct 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 | */ | ||
955 | struct 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 | */ |
972 | int xprt_destroy(struct rpc_xprt *xprt) | 965 | static 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 | */ | ||
981 | void 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 | */ | ||
991 | struct rpc_xprt *xprt_get(struct rpc_xprt *xprt) | ||
992 | { | ||
993 | kref_get(&xprt->kref); | ||
994 | return xprt; | ||
981 | } | 995 | } |