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.c66
1 files changed, 25 insertions, 41 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 6dda3860351f..8ff2c8acb223 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -119,6 +119,17 @@ out_sleep:
119 return 0; 119 return 0;
120} 120}
121 121
122static void xprt_clear_locked(struct rpc_xprt *xprt)
123{
124 xprt->snd_task = NULL;
125 if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state) || xprt->shutdown) {
126 smp_mb__before_clear_bit();
127 clear_bit(XPRT_LOCKED, &xprt->state);
128 smp_mb__after_clear_bit();
129 } else
130 schedule_work(&xprt->task_cleanup);
131}
132
122/* 133/*
123 * xprt_reserve_xprt_cong - serialize write access to transports 134 * xprt_reserve_xprt_cong - serialize write access to transports
124 * @task: task that is requesting access to the transport 135 * @task: task that is requesting access to the transport
@@ -145,9 +156,7 @@ int xprt_reserve_xprt_cong(struct rpc_task *task)
145 } 156 }
146 return 1; 157 return 1;
147 } 158 }
148 smp_mb__before_clear_bit(); 159 xprt_clear_locked(xprt);
149 clear_bit(XPRT_LOCKED, &xprt->state);
150 smp_mb__after_clear_bit();
151out_sleep: 160out_sleep:
152 dprintk("RPC: %4d failed to lock transport %p\n", task->tk_pid, xprt); 161 dprintk("RPC: %4d failed to lock transport %p\n", task->tk_pid, xprt);
153 task->tk_timeout = 0; 162 task->tk_timeout = 0;
@@ -193,9 +202,7 @@ static void __xprt_lock_write_next(struct rpc_xprt *xprt)
193 return; 202 return;
194 203
195out_unlock: 204out_unlock:
196 smp_mb__before_clear_bit(); 205 xprt_clear_locked(xprt);
197 clear_bit(XPRT_LOCKED, &xprt->state);
198 smp_mb__after_clear_bit();
199} 206}
200 207
201static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt) 208static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
@@ -222,9 +229,7 @@ static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
222 return; 229 return;
223 } 230 }
224out_unlock: 231out_unlock:
225 smp_mb__before_clear_bit(); 232 xprt_clear_locked(xprt);
226 clear_bit(XPRT_LOCKED, &xprt->state);
227 smp_mb__after_clear_bit();
228} 233}
229 234
230/** 235/**
@@ -237,10 +242,7 @@ out_unlock:
237void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) 242void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
238{ 243{
239 if (xprt->snd_task == task) { 244 if (xprt->snd_task == task) {
240 xprt->snd_task = NULL; 245 xprt_clear_locked(xprt);
241 smp_mb__before_clear_bit();
242 clear_bit(XPRT_LOCKED, &xprt->state);
243 smp_mb__after_clear_bit();
244 __xprt_lock_write_next(xprt); 246 __xprt_lock_write_next(xprt);
245 } 247 }
246} 248}
@@ -256,10 +258,7 @@ void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
256void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task) 258void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
257{ 259{
258 if (xprt->snd_task == task) { 260 if (xprt->snd_task == task) {
259 xprt->snd_task = NULL; 261 xprt_clear_locked(xprt);
260 smp_mb__before_clear_bit();
261 clear_bit(XPRT_LOCKED, &xprt->state);
262 smp_mb__after_clear_bit();
263 __xprt_lock_write_next_cong(xprt); 262 __xprt_lock_write_next_cong(xprt);
264 } 263 }
265} 264}
@@ -535,10 +534,6 @@ void xprt_connect(struct rpc_task *task)
535 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,
536 xprt, (xprt_connected(xprt) ? "is" : "is not")); 535 xprt, (xprt_connected(xprt) ? "is" : "is not"));
537 536
538 if (xprt->shutdown) {
539 task->tk_status = -EIO;
540 return;
541 }
542 if (!xprt->addr.sin_port) { 537 if (!xprt->addr.sin_port) {
543 task->tk_status = -EIO; 538 task->tk_status = -EIO;
544 return; 539 return;
@@ -687,9 +682,6 @@ int xprt_prepare_transmit(struct rpc_task *task)
687 682
688 dprintk("RPC: %4d xprt_prepare_transmit\n", task->tk_pid); 683 dprintk("RPC: %4d xprt_prepare_transmit\n", task->tk_pid);
689 684
690 if (xprt->shutdown)
691 return -EIO;
692
693 spin_lock_bh(&xprt->transport_lock); 685 spin_lock_bh(&xprt->transport_lock);
694 if (req->rq_received && !req->rq_bytes_sent) { 686 if (req->rq_received && !req->rq_bytes_sent) {
695 err = req->rq_received; 687 err = req->rq_received;
@@ -814,11 +806,9 @@ void xprt_reserve(struct rpc_task *task)
814 struct rpc_xprt *xprt = task->tk_xprt; 806 struct rpc_xprt *xprt = task->tk_xprt;
815 807
816 task->tk_status = -EIO; 808 task->tk_status = -EIO;
817 if (!xprt->shutdown) { 809 spin_lock(&xprt->reserve_lock);
818 spin_lock(&xprt->reserve_lock); 810 do_xprt_reserve(task);
819 do_xprt_reserve(task); 811 spin_unlock(&xprt->reserve_lock);
820 spin_unlock(&xprt->reserve_lock);
821 }
822} 812}
823 813
824static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt) 814static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
@@ -838,6 +828,8 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
838 req->rq_timeout = xprt->timeout.to_initval; 828 req->rq_timeout = xprt->timeout.to_initval;
839 req->rq_task = task; 829 req->rq_task = task;
840 req->rq_xprt = xprt; 830 req->rq_xprt = xprt;
831 req->rq_buffer = NULL;
832 req->rq_bufsize = 0;
841 req->rq_xid = xprt_alloc_xid(xprt); 833 req->rq_xid = xprt_alloc_xid(xprt);
842 req->rq_release_snd_buf = NULL; 834 req->rq_release_snd_buf = NULL;
843 dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, 835 dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
@@ -863,10 +855,11 @@ void xprt_release(struct rpc_task *task)
863 if (!list_empty(&req->rq_list)) 855 if (!list_empty(&req->rq_list))
864 list_del(&req->rq_list); 856 list_del(&req->rq_list);
865 xprt->last_used = jiffies; 857 xprt->last_used = jiffies;
866 if (list_empty(&xprt->recv) && !xprt->shutdown) 858 if (list_empty(&xprt->recv))
867 mod_timer(&xprt->timer, 859 mod_timer(&xprt->timer,
868 xprt->last_used + xprt->idle_timeout); 860 xprt->last_used + xprt->idle_timeout);
869 spin_unlock_bh(&xprt->transport_lock); 861 spin_unlock_bh(&xprt->transport_lock);
862 xprt->ops->buf_free(task);
870 task->tk_rqstp = NULL; 863 task->tk_rqstp = NULL;
871 if (req->rq_release_snd_buf) 864 if (req->rq_release_snd_buf)
872 req->rq_release_snd_buf(req); 865 req->rq_release_snd_buf(req);
@@ -974,16 +967,6 @@ struct rpc_xprt *xprt_create_proto(int proto, struct sockaddr_in *sap, struct rp
974 return xprt; 967 return xprt;
975} 968}
976 969
977static void xprt_shutdown(struct rpc_xprt *xprt)
978{
979 xprt->shutdown = 1;
980 rpc_wake_up(&xprt->sending);
981 rpc_wake_up(&xprt->resend);
982 xprt_wake_pending_tasks(xprt, -EIO);
983 rpc_wake_up(&xprt->backlog);
984 del_timer_sync(&xprt->timer);
985}
986
987/** 970/**
988 * xprt_destroy - destroy an RPC transport, killing off all requests. 971 * xprt_destroy - destroy an RPC transport, killing off all requests.
989 * @xprt: transport to destroy 972 * @xprt: transport to destroy
@@ -992,7 +975,8 @@ static void xprt_shutdown(struct rpc_xprt *xprt)
992int xprt_destroy(struct rpc_xprt *xprt) 975int xprt_destroy(struct rpc_xprt *xprt)
993{ 976{
994 dprintk("RPC: destroying transport %p\n", xprt); 977 dprintk("RPC: destroying transport %p\n", xprt);
995 xprt_shutdown(xprt); 978 xprt->shutdown = 1;
979 del_timer_sync(&xprt->timer);
996 xprt->ops->destroy(xprt); 980 xprt->ops->destroy(xprt);
997 kfree(xprt); 981 kfree(xprt);
998 982