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.c80
1 files changed, 57 insertions, 23 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index d5553b8179f9..75d748eee0eb 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -188,9 +188,9 @@ out_sleep:
188 task->tk_timeout = 0; 188 task->tk_timeout = 0;
189 task->tk_status = -EAGAIN; 189 task->tk_status = -EAGAIN;
190 if (req && req->rq_ntrans) 190 if (req && req->rq_ntrans)
191 rpc_sleep_on(&xprt->resend, task, NULL, NULL); 191 rpc_sleep_on(&xprt->resend, task, NULL);
192 else 192 else
193 rpc_sleep_on(&xprt->sending, task, NULL, NULL); 193 rpc_sleep_on(&xprt->sending, task, NULL);
194 return 0; 194 return 0;
195} 195}
196EXPORT_SYMBOL_GPL(xprt_reserve_xprt); 196EXPORT_SYMBOL_GPL(xprt_reserve_xprt);
@@ -238,9 +238,9 @@ out_sleep:
238 task->tk_timeout = 0; 238 task->tk_timeout = 0;
239 task->tk_status = -EAGAIN; 239 task->tk_status = -EAGAIN;
240 if (req && req->rq_ntrans) 240 if (req && req->rq_ntrans)
241 rpc_sleep_on(&xprt->resend, task, NULL, NULL); 241 rpc_sleep_on(&xprt->resend, task, NULL);
242 else 242 else
243 rpc_sleep_on(&xprt->sending, task, NULL, NULL); 243 rpc_sleep_on(&xprt->sending, task, NULL);
244 return 0; 244 return 0;
245} 245}
246EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong); 246EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong);
@@ -447,13 +447,13 @@ EXPORT_SYMBOL_GPL(xprt_wake_pending_tasks);
447 * @task: task to be put to sleep 447 * @task: task to be put to sleep
448 * 448 *
449 */ 449 */
450void xprt_wait_for_buffer_space(struct rpc_task *task) 450void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action)
451{ 451{
452 struct rpc_rqst *req = task->tk_rqstp; 452 struct rpc_rqst *req = task->tk_rqstp;
453 struct rpc_xprt *xprt = req->rq_xprt; 453 struct rpc_xprt *xprt = req->rq_xprt;
454 454
455 task->tk_timeout = req->rq_timeout; 455 task->tk_timeout = req->rq_timeout;
456 rpc_sleep_on(&xprt->pending, task, NULL, NULL); 456 rpc_sleep_on(&xprt->pending, task, action);
457} 457}
458EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space); 458EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);
459 459
@@ -472,7 +472,7 @@ void xprt_write_space(struct rpc_xprt *xprt)
472 if (xprt->snd_task) { 472 if (xprt->snd_task) {
473 dprintk("RPC: write space: waking waiting task on " 473 dprintk("RPC: write space: waking waiting task on "
474 "xprt %p\n", xprt); 474 "xprt %p\n", xprt);
475 rpc_wake_up_task(xprt->snd_task); 475 rpc_wake_up_queued_task(&xprt->pending, xprt->snd_task);
476 } 476 }
477 spin_unlock_bh(&xprt->transport_lock); 477 spin_unlock_bh(&xprt->transport_lock);
478} 478}
@@ -602,11 +602,37 @@ void xprt_force_disconnect(struct rpc_xprt *xprt)
602 /* Try to schedule an autoclose RPC call */ 602 /* Try to schedule an autoclose RPC call */
603 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) 603 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
604 queue_work(rpciod_workqueue, &xprt->task_cleanup); 604 queue_work(rpciod_workqueue, &xprt->task_cleanup);
605 else if (xprt->snd_task != NULL) 605 xprt_wake_pending_tasks(xprt, -ENOTCONN);
606 rpc_wake_up_task(xprt->snd_task); 606 spin_unlock_bh(&xprt->transport_lock);
607}
608
609/**
610 * xprt_conditional_disconnect - force a transport to disconnect
611 * @xprt: transport to disconnect
612 * @cookie: 'connection cookie'
613 *
614 * This attempts to break the connection if and only if 'cookie' matches
615 * the current transport 'connection cookie'. It ensures that we don't
616 * try to break the connection more than once when we need to retransmit
617 * a batch of RPC requests.
618 *
619 */
620void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie)
621{
622 /* Don't race with the test_bit() in xprt_clear_locked() */
623 spin_lock_bh(&xprt->transport_lock);
624 if (cookie != xprt->connect_cookie)
625 goto out;
626 if (test_bit(XPRT_CLOSING, &xprt->state) || !xprt_connected(xprt))
627 goto out;
628 set_bit(XPRT_CLOSE_WAIT, &xprt->state);
629 /* Try to schedule an autoclose RPC call */
630 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
631 queue_work(rpciod_workqueue, &xprt->task_cleanup);
632 xprt_wake_pending_tasks(xprt, -ENOTCONN);
633out:
607 spin_unlock_bh(&xprt->transport_lock); 634 spin_unlock_bh(&xprt->transport_lock);
608} 635}
609EXPORT_SYMBOL_GPL(xprt_force_disconnect);
610 636
611static void 637static void
612xprt_init_autodisconnect(unsigned long data) 638xprt_init_autodisconnect(unsigned long data)
@@ -653,7 +679,7 @@ void xprt_connect(struct rpc_task *task)
653 task->tk_rqstp->rq_bytes_sent = 0; 679 task->tk_rqstp->rq_bytes_sent = 0;
654 680
655 task->tk_timeout = xprt->connect_timeout; 681 task->tk_timeout = xprt->connect_timeout;
656 rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL); 682 rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
657 xprt->stat.connect_start = jiffies; 683 xprt->stat.connect_start = jiffies;
658 xprt->ops->connect(task); 684 xprt->ops->connect(task);
659 } 685 }
@@ -749,18 +775,20 @@ EXPORT_SYMBOL_GPL(xprt_update_rtt);
749void xprt_complete_rqst(struct rpc_task *task, int copied) 775void xprt_complete_rqst(struct rpc_task *task, int copied)
750{ 776{
751 struct rpc_rqst *req = task->tk_rqstp; 777 struct rpc_rqst *req = task->tk_rqstp;
778 struct rpc_xprt *xprt = req->rq_xprt;
752 779
753 dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", 780 dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
754 task->tk_pid, ntohl(req->rq_xid), copied); 781 task->tk_pid, ntohl(req->rq_xid), copied);
755 782
756 task->tk_xprt->stat.recvs++; 783 xprt->stat.recvs++;
757 task->tk_rtt = (long)jiffies - req->rq_xtime; 784 task->tk_rtt = (long)jiffies - req->rq_xtime;
758 785
759 list_del_init(&req->rq_list); 786 list_del_init(&req->rq_list);
787 req->rq_private_buf.len = copied;
760 /* Ensure all writes are done before we update req->rq_received */ 788 /* Ensure all writes are done before we update req->rq_received */
761 smp_wmb(); 789 smp_wmb();
762 req->rq_received = req->rq_private_buf.len = copied; 790 req->rq_received = copied;
763 rpc_wake_up_task(task); 791 rpc_wake_up_queued_task(&xprt->pending, task);
764} 792}
765EXPORT_SYMBOL_GPL(xprt_complete_rqst); 793EXPORT_SYMBOL_GPL(xprt_complete_rqst);
766 794
@@ -769,17 +797,17 @@ static void xprt_timer(struct rpc_task *task)
769 struct rpc_rqst *req = task->tk_rqstp; 797 struct rpc_rqst *req = task->tk_rqstp;
770 struct rpc_xprt *xprt = req->rq_xprt; 798 struct rpc_xprt *xprt = req->rq_xprt;
771 799
800 if (task->tk_status != -ETIMEDOUT)
801 return;
772 dprintk("RPC: %5u xprt_timer\n", task->tk_pid); 802 dprintk("RPC: %5u xprt_timer\n", task->tk_pid);
773 803
774 spin_lock(&xprt->transport_lock); 804 spin_lock_bh(&xprt->transport_lock);
775 if (!req->rq_received) { 805 if (!req->rq_received) {
776 if (xprt->ops->timer) 806 if (xprt->ops->timer)
777 xprt->ops->timer(task); 807 xprt->ops->timer(task);
778 task->tk_status = -ETIMEDOUT; 808 } else
779 } 809 task->tk_status = 0;
780 task->tk_timeout = 0; 810 spin_unlock_bh(&xprt->transport_lock);
781 rpc_wake_up_task(task);
782 spin_unlock(&xprt->transport_lock);
783} 811}
784 812
785/** 813/**
@@ -849,6 +877,7 @@ void xprt_transmit(struct rpc_task *task)
849 } else if (!req->rq_bytes_sent) 877 } else if (!req->rq_bytes_sent)
850 return; 878 return;
851 879
880 req->rq_connect_cookie = xprt->connect_cookie;
852 status = xprt->ops->send_request(task); 881 status = xprt->ops->send_request(task);
853 if (status == 0) { 882 if (status == 0) {
854 dprintk("RPC: %5u xmit complete\n", task->tk_pid); 883 dprintk("RPC: %5u xmit complete\n", task->tk_pid);
@@ -864,7 +893,7 @@ void xprt_transmit(struct rpc_task *task)
864 if (!xprt_connected(xprt)) 893 if (!xprt_connected(xprt))
865 task->tk_status = -ENOTCONN; 894 task->tk_status = -ENOTCONN;
866 else if (!req->rq_received) 895 else if (!req->rq_received)
867 rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer); 896 rpc_sleep_on(&xprt->pending, task, xprt_timer);
868 spin_unlock_bh(&xprt->transport_lock); 897 spin_unlock_bh(&xprt->transport_lock);
869 return; 898 return;
870 } 899 }
@@ -875,7 +904,7 @@ void xprt_transmit(struct rpc_task *task)
875 */ 904 */
876 task->tk_status = status; 905 task->tk_status = status;
877 if (status == -ECONNREFUSED) 906 if (status == -ECONNREFUSED)
878 rpc_sleep_on(&xprt->sending, task, NULL, NULL); 907 rpc_sleep_on(&xprt->sending, task, NULL);
879} 908}
880 909
881static inline void do_xprt_reserve(struct rpc_task *task) 910static inline void do_xprt_reserve(struct rpc_task *task)
@@ -895,7 +924,7 @@ static inline void do_xprt_reserve(struct rpc_task *task)
895 dprintk("RPC: waiting for request slot\n"); 924 dprintk("RPC: waiting for request slot\n");
896 task->tk_status = -EAGAIN; 925 task->tk_status = -EAGAIN;
897 task->tk_timeout = 0; 926 task->tk_timeout = 0;
898 rpc_sleep_on(&xprt->backlog, task, NULL, NULL); 927 rpc_sleep_on(&xprt->backlog, task, NULL);
899} 928}
900 929
901/** 930/**
@@ -1052,6 +1081,11 @@ static void xprt_destroy(struct kref *kref)
1052 xprt->shutdown = 1; 1081 xprt->shutdown = 1;
1053 del_timer_sync(&xprt->timer); 1082 del_timer_sync(&xprt->timer);
1054 1083
1084 rpc_destroy_wait_queue(&xprt->binding);
1085 rpc_destroy_wait_queue(&xprt->pending);
1086 rpc_destroy_wait_queue(&xprt->sending);
1087 rpc_destroy_wait_queue(&xprt->resend);
1088 rpc_destroy_wait_queue(&xprt->backlog);
1055 /* 1089 /*
1056 * Tear down transport state and free the rpc_xprt 1090 * Tear down transport state and free the rpc_xprt
1057 */ 1091 */