aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/xprt.h60
-rw-r--r--net/sunrpc/xprt.c14
-rw-r--r--net/sunrpc/xprtsock.c6
3 files changed, 58 insertions, 22 deletions
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 41ce296dded1..009a3bb4f997 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -163,7 +163,7 @@ struct rpc_xprt {
163 struct list_head free; /* free slots */ 163 struct list_head free; /* free slots */
164 struct rpc_rqst * slot; /* slot table storage */ 164 struct rpc_rqst * slot; /* slot table storage */
165 unsigned int max_reqs; /* total slots */ 165 unsigned int max_reqs; /* total slots */
166 unsigned long sockstate; /* Socket state */ 166 unsigned long state; /* transport state */
167 unsigned char shutdown : 1, /* being shut down */ 167 unsigned char shutdown : 1, /* being shut down */
168 nocong : 1, /* no congestion control */ 168 nocong : 1, /* no congestion control */
169 resvport : 1, /* use a reserved port */ 169 resvport : 1, /* use a reserved port */
@@ -240,16 +240,54 @@ int xs_setup_udp(struct rpc_xprt *,
240int xs_setup_tcp(struct rpc_xprt *, 240int xs_setup_tcp(struct rpc_xprt *,
241 struct rpc_timeout *); 241 struct rpc_timeout *);
242 242
243#define XPRT_LOCKED 0 243/*
244#define XPRT_CONNECT 1 244 * Reserved bit positions in xprt->state
245#define XPRT_CONNECTING 2 245 */
246 246#define XPRT_LOCKED (0)
247#define xprt_connected(xp) (test_bit(XPRT_CONNECT, &(xp)->sockstate)) 247#define XPRT_CONNECTED (1)
248#define xprt_set_connected(xp) (set_bit(XPRT_CONNECT, &(xp)->sockstate)) 248#define XPRT_CONNECTING (2)
249#define xprt_test_and_set_connected(xp) (test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate)) 249
250#define xprt_test_and_clear_connected(xp) \ 250static inline void xprt_set_connected(struct rpc_xprt *xprt)
251 (test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate)) 251{
252#define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate)) 252 set_bit(XPRT_CONNECTED, &xprt->state);
253}
254
255static inline void xprt_clear_connected(struct rpc_xprt *xprt)
256{
257 clear_bit(XPRT_CONNECTED, &xprt->state);
258}
259
260static inline int xprt_connected(struct rpc_xprt *xprt)
261{
262 return test_bit(XPRT_CONNECTED, &xprt->state);
263}
264
265static inline int xprt_test_and_set_connected(struct rpc_xprt *xprt)
266{
267 return test_and_set_bit(XPRT_CONNECTED, &xprt->state);
268}
269
270static inline int xprt_test_and_clear_connected(struct rpc_xprt *xprt)
271{
272 return test_and_clear_bit(XPRT_CONNECTED, &xprt->state);
273}
274
275static inline void xprt_clear_connecting(struct rpc_xprt *xprt)
276{
277 smp_mb__before_clear_bit();
278 clear_bit(XPRT_CONNECTING, &xprt->state);
279 smp_mb__after_clear_bit();
280}
281
282static inline int xprt_connecting(struct rpc_xprt *xprt)
283{
284 return test_bit(XPRT_CONNECTING, &xprt->state);
285}
286
287static inline int xprt_test_and_set_connecting(struct rpc_xprt *xprt)
288{
289 return test_and_set_bit(XPRT_CONNECTING, &xprt->state);
290}
253 291
254#endif /* __KERNEL__*/ 292#endif /* __KERNEL__*/
255 293
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 9c45c522e3ef..57c5e77b155e 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -74,7 +74,7 @@ __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
74{ 74{
75 struct rpc_rqst *req = task->tk_rqstp; 75 struct rpc_rqst *req = task->tk_rqstp;
76 76
77 if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate)) { 77 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
78 if (task == xprt->snd_task) 78 if (task == xprt->snd_task)
79 return 1; 79 return 1;
80 goto out_sleep; 80 goto out_sleep;
@@ -88,7 +88,7 @@ __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
88 return 1; 88 return 1;
89 } 89 }
90 smp_mb__before_clear_bit(); 90 smp_mb__before_clear_bit();
91 clear_bit(XPRT_LOCKED, &xprt->sockstate); 91 clear_bit(XPRT_LOCKED, &xprt->state);
92 smp_mb__after_clear_bit(); 92 smp_mb__after_clear_bit();
93out_sleep: 93out_sleep:
94 dprintk("RPC: %4d failed to lock socket %p\n", task->tk_pid, xprt); 94 dprintk("RPC: %4d failed to lock socket %p\n", task->tk_pid, xprt);
@@ -118,7 +118,7 @@ __xprt_lock_write_next(struct rpc_xprt *xprt)
118{ 118{
119 struct rpc_task *task; 119 struct rpc_task *task;
120 120
121 if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate)) 121 if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
122 return; 122 return;
123 if (!xprt->nocong && RPCXPRT_CONGESTED(xprt)) 123 if (!xprt->nocong && RPCXPRT_CONGESTED(xprt))
124 goto out_unlock; 124 goto out_unlock;
@@ -139,7 +139,7 @@ __xprt_lock_write_next(struct rpc_xprt *xprt)
139 } 139 }
140out_unlock: 140out_unlock:
141 smp_mb__before_clear_bit(); 141 smp_mb__before_clear_bit();
142 clear_bit(XPRT_LOCKED, &xprt->sockstate); 142 clear_bit(XPRT_LOCKED, &xprt->state);
143 smp_mb__after_clear_bit(); 143 smp_mb__after_clear_bit();
144} 144}
145 145
@@ -152,7 +152,7 @@ __xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
152 if (xprt->snd_task == task) { 152 if (xprt->snd_task == task) {
153 xprt->snd_task = NULL; 153 xprt->snd_task = NULL;
154 smp_mb__before_clear_bit(); 154 smp_mb__before_clear_bit();
155 clear_bit(XPRT_LOCKED, &xprt->sockstate); 155 clear_bit(XPRT_LOCKED, &xprt->state);
156 smp_mb__after_clear_bit(); 156 smp_mb__after_clear_bit();
157 __xprt_lock_write_next(xprt); 157 __xprt_lock_write_next(xprt);
158 } 158 }
@@ -312,11 +312,11 @@ xprt_init_autodisconnect(unsigned long data)
312 spin_lock(&xprt->transport_lock); 312 spin_lock(&xprt->transport_lock);
313 if (!list_empty(&xprt->recv) || xprt->shutdown) 313 if (!list_empty(&xprt->recv) || xprt->shutdown)
314 goto out_abort; 314 goto out_abort;
315 if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate)) 315 if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
316 goto out_abort; 316 goto out_abort;
317 spin_unlock(&xprt->transport_lock); 317 spin_unlock(&xprt->transport_lock);
318 /* Let keventd close the socket */ 318 /* Let keventd close the socket */
319 if (test_bit(XPRT_CONNECTING, &xprt->sockstate) != 0) 319 if (xprt_connecting(xprt))
320 xprt_release_write(xprt, NULL); 320 xprt_release_write(xprt, NULL);
321 else 321 else
322 schedule_work(&xprt->task_cleanup); 322 schedule_work(&xprt->task_cleanup);
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index bc90caab6088..76a33b54f436 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -925,9 +925,7 @@ out:
925 else 925 else
926 rpc_wake_up(&xprt->pending); 926 rpc_wake_up(&xprt->pending);
927out_clear: 927out_clear:
928 smp_mb__before_clear_bit(); 928 xprt_clear_connecting(xprt);
929 clear_bit(XPRT_CONNECTING, &xprt->sockstate);
930 smp_mb__after_clear_bit();
931} 929}
932 930
933/** 931/**
@@ -940,7 +938,7 @@ static void xs_connect(struct rpc_task *task)
940{ 938{
941 struct rpc_xprt *xprt = task->tk_xprt; 939 struct rpc_xprt *xprt = task->tk_xprt;
942 940
943 if (!test_and_set_bit(XPRT_CONNECTING, &xprt->sockstate)) { 941 if (!xprt_test_and_set_connecting(xprt)) {
944 if (xprt->sock != NULL) { 942 if (xprt->sock != NULL) {
945 dprintk("RPC: xs_connect delayed xprt %p\n", xprt); 943 dprintk("RPC: xs_connect delayed xprt %p\n", xprt);
946 schedule_delayed_work(&xprt->sock_connect, 944 schedule_delayed_work(&xprt->sock_connect,