diff options
-rw-r--r-- | include/linux/sunrpc/xprt.h | 60 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 14 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 6 |
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 *, | |||
240 | int xs_setup_tcp(struct rpc_xprt *, | 240 | int 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) \ | 250 | static 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 | |||
255 | static inline void xprt_clear_connected(struct rpc_xprt *xprt) | ||
256 | { | ||
257 | clear_bit(XPRT_CONNECTED, &xprt->state); | ||
258 | } | ||
259 | |||
260 | static inline int xprt_connected(struct rpc_xprt *xprt) | ||
261 | { | ||
262 | return test_bit(XPRT_CONNECTED, &xprt->state); | ||
263 | } | ||
264 | |||
265 | static inline int xprt_test_and_set_connected(struct rpc_xprt *xprt) | ||
266 | { | ||
267 | return test_and_set_bit(XPRT_CONNECTED, &xprt->state); | ||
268 | } | ||
269 | |||
270 | static inline int xprt_test_and_clear_connected(struct rpc_xprt *xprt) | ||
271 | { | ||
272 | return test_and_clear_bit(XPRT_CONNECTED, &xprt->state); | ||
273 | } | ||
274 | |||
275 | static 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 | |||
282 | static inline int xprt_connecting(struct rpc_xprt *xprt) | ||
283 | { | ||
284 | return test_bit(XPRT_CONNECTING, &xprt->state); | ||
285 | } | ||
286 | |||
287 | static 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(); |
93 | out_sleep: | 93 | out_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 | } |
140 | out_unlock: | 140 | out_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); |
927 | out_clear: | 927 | out_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, |