diff options
author | Tom Tucker <tom@opengridcomputing.com> | 2007-12-30 22:08:27 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2008-02-01 16:42:13 -0500 |
commit | 0f0257eaa5d29b80f6ab2c40ed21aa65bb4527f6 (patch) | |
tree | 542f64ec74fc045c06f5a1ffc0d48f823de12ccb /net/sunrpc/svcsock.c | |
parent | 18d19f949d5a9c927b2b88402630c5137971b619 (diff) |
svc: Move the xprt independent code to the svc_xprt.c file
This functionally trivial patch moves all of the transport independent
functions from the svcsock.c file to the transport independent svc_xprt.c
file.
In addition the following formatting changes were made:
- White space cleanup
- Function signatures on single line
- The inline directive was removed
- Lines over 80 columns were reformatted
- The term 'socket' was changed to 'transport' in comments
- The SMP comment was moved and updated.
Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
Acked-by: Neil Brown <neilb@suse.de>
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Greg Banks <gnb@sgi.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r-- | net/sunrpc/svcsock.c | 834 |
1 files changed, 24 insertions, 810 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 0814a78ad7ad..343a85b700f0 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -48,66 +48,24 @@ | |||
48 | #include <linux/sunrpc/svcsock.h> | 48 | #include <linux/sunrpc/svcsock.h> |
49 | #include <linux/sunrpc/stats.h> | 49 | #include <linux/sunrpc/stats.h> |
50 | 50 | ||
51 | /* SMP locking strategy: | ||
52 | * | ||
53 | * svc_pool->sp_lock protects most of the fields of that pool. | ||
54 | * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt. | ||
55 | * when both need to be taken (rare), svc_serv->sv_lock is first. | ||
56 | * BKL protects svc_serv->sv_nrthread. | ||
57 | * svc_sock->sk_lock protects the svc_sock->sk_deferred list | ||
58 | * and the ->sk_info_authunix cache. | ||
59 | * svc_sock->sk_xprt.xpt_flags.XPT_BUSY prevents a svc_sock being | ||
60 | * enqueued multiply. | ||
61 | * | ||
62 | * Some flags can be set to certain values at any time | ||
63 | * providing that certain rules are followed: | ||
64 | * | ||
65 | * XPT_CONN, XPT_DATA, can be set or cleared at any time. | ||
66 | * after a set, svc_xprt_enqueue must be called. | ||
67 | * after a clear, the socket must be read/accepted | ||
68 | * if this succeeds, it must be set again. | ||
69 | * XPT_CLOSE can set at any time. It is never cleared. | ||
70 | * xpt_ref contains a bias of '1' until XPT_DEAD is set. | ||
71 | * so when xprt_ref hits zero, we know the transport is dead | ||
72 | * and no-one is using it. | ||
73 | * XPT_DEAD can only be set while XPT_BUSY is held which ensures | ||
74 | * no other thread will be using the socket or will try to | ||
75 | * set XPT_DEAD. | ||
76 | * | ||
77 | */ | ||
78 | |||
79 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | 51 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT |
80 | 52 | ||
81 | 53 | ||
82 | static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *, | 54 | static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *, |
83 | int *errp, int flags); | 55 | int *errp, int flags); |
84 | static void svc_delete_xprt(struct svc_xprt *xprt); | ||
85 | static void svc_udp_data_ready(struct sock *, int); | 56 | static void svc_udp_data_ready(struct sock *, int); |
86 | static int svc_udp_recvfrom(struct svc_rqst *); | 57 | static int svc_udp_recvfrom(struct svc_rqst *); |
87 | static int svc_udp_sendto(struct svc_rqst *); | 58 | static int svc_udp_sendto(struct svc_rqst *); |
88 | static void svc_close_xprt(struct svc_xprt *xprt); | ||
89 | static void svc_sock_detach(struct svc_xprt *); | 59 | static void svc_sock_detach(struct svc_xprt *); |
90 | static void svc_sock_free(struct svc_xprt *); | 60 | static void svc_sock_free(struct svc_xprt *); |
91 | 61 | ||
92 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); | ||
93 | static int svc_deferred_recv(struct svc_rqst *rqstp); | ||
94 | static struct cache_deferred_req *svc_defer(struct cache_req *req); | ||
95 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, | 62 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, |
96 | struct sockaddr *, int, int); | 63 | struct sockaddr *, int, int); |
97 | static void svc_age_temp_xprts(unsigned long closure); | ||
98 | |||
99 | /* apparently the "standard" is that clients close | ||
100 | * idle connections after 5 minutes, servers after | ||
101 | * 6 minutes | ||
102 | * http://www.connectathon.org/talks96/nfstcp.pdf | ||
103 | */ | ||
104 | static int svc_conn_age_period = 6*60; | ||
105 | |||
106 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 64 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
107 | static struct lock_class_key svc_key[2]; | 65 | static struct lock_class_key svc_key[2]; |
108 | static struct lock_class_key svc_slock_key[2]; | 66 | static struct lock_class_key svc_slock_key[2]; |
109 | 67 | ||
110 | static inline void svc_reclassify_socket(struct socket *sock) | 68 | static void svc_reclassify_socket(struct socket *sock) |
111 | { | 69 | { |
112 | struct sock *sk = sock->sk; | 70 | struct sock *sk = sock->sk; |
113 | BUG_ON(sock_owned_by_user(sk)); | 71 | BUG_ON(sock_owned_by_user(sk)); |
@@ -131,67 +89,11 @@ static inline void svc_reclassify_socket(struct socket *sock) | |||
131 | } | 89 | } |
132 | } | 90 | } |
133 | #else | 91 | #else |
134 | static inline void svc_reclassify_socket(struct socket *sock) | 92 | static void svc_reclassify_socket(struct socket *sock) |
135 | { | 93 | { |
136 | } | 94 | } |
137 | #endif | 95 | #endif |
138 | 96 | ||
139 | static char *__svc_print_addr(struct sockaddr *addr, char *buf, size_t len) | ||
140 | { | ||
141 | switch (addr->sa_family) { | ||
142 | case AF_INET: | ||
143 | snprintf(buf, len, "%u.%u.%u.%u, port=%u", | ||
144 | NIPQUAD(((struct sockaddr_in *) addr)->sin_addr), | ||
145 | ntohs(((struct sockaddr_in *) addr)->sin_port)); | ||
146 | break; | ||
147 | |||
148 | case AF_INET6: | ||
149 | snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x, port=%u", | ||
150 | NIP6(((struct sockaddr_in6 *) addr)->sin6_addr), | ||
151 | ntohs(((struct sockaddr_in6 *) addr)->sin6_port)); | ||
152 | break; | ||
153 | |||
154 | default: | ||
155 | snprintf(buf, len, "unknown address type: %d", addr->sa_family); | ||
156 | break; | ||
157 | } | ||
158 | return buf; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * svc_print_addr - Format rq_addr field for printing | ||
163 | * @rqstp: svc_rqst struct containing address to print | ||
164 | * @buf: target buffer for formatted address | ||
165 | * @len: length of target buffer | ||
166 | * | ||
167 | */ | ||
168 | char *svc_print_addr(struct svc_rqst *rqstp, char *buf, size_t len) | ||
169 | { | ||
170 | return __svc_print_addr(svc_addr(rqstp), buf, len); | ||
171 | } | ||
172 | EXPORT_SYMBOL_GPL(svc_print_addr); | ||
173 | |||
174 | /* | ||
175 | * Queue up an idle server thread. Must have pool->sp_lock held. | ||
176 | * Note: this is really a stack rather than a queue, so that we only | ||
177 | * use as many different threads as we need, and the rest don't pollute | ||
178 | * the cache. | ||
179 | */ | ||
180 | static inline void | ||
181 | svc_thread_enqueue(struct svc_pool *pool, struct svc_rqst *rqstp) | ||
182 | { | ||
183 | list_add(&rqstp->rq_list, &pool->sp_threads); | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * Dequeue an nfsd thread. Must have pool->sp_lock held. | ||
188 | */ | ||
189 | static inline void | ||
190 | svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp) | ||
191 | { | ||
192 | list_del(&rqstp->rq_list); | ||
193 | } | ||
194 | |||
195 | /* | 97 | /* |
196 | * Release an skbuff after use | 98 | * Release an skbuff after use |
197 | */ | 99 | */ |
@@ -214,220 +116,6 @@ static void svc_release_skb(struct svc_rqst *rqstp) | |||
214 | } | 116 | } |
215 | } | 117 | } |
216 | 118 | ||
217 | /* | ||
218 | * Queue up a socket with data pending. If there are idle nfsd | ||
219 | * processes, wake 'em up. | ||
220 | * | ||
221 | */ | ||
222 | void svc_xprt_enqueue(struct svc_xprt *xprt) | ||
223 | { | ||
224 | struct svc_serv *serv = xprt->xpt_server; | ||
225 | struct svc_pool *pool; | ||
226 | struct svc_rqst *rqstp; | ||
227 | int cpu; | ||
228 | |||
229 | if (!(xprt->xpt_flags & | ||
230 | ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) | ||
231 | return; | ||
232 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) | ||
233 | return; | ||
234 | |||
235 | cpu = get_cpu(); | ||
236 | pool = svc_pool_for_cpu(xprt->xpt_server, cpu); | ||
237 | put_cpu(); | ||
238 | |||
239 | spin_lock_bh(&pool->sp_lock); | ||
240 | |||
241 | if (!list_empty(&pool->sp_threads) && | ||
242 | !list_empty(&pool->sp_sockets)) | ||
243 | printk(KERN_ERR | ||
244 | "svc_xprt_enqueue: " | ||
245 | "threads and transports both waiting??\n"); | ||
246 | |||
247 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) { | ||
248 | /* Don't enqueue dead sockets */ | ||
249 | dprintk("svc: transport %p is dead, not enqueued\n", xprt); | ||
250 | goto out_unlock; | ||
251 | } | ||
252 | |||
253 | /* Mark socket as busy. It will remain in this state until the | ||
254 | * server has processed all pending data and put the socket back | ||
255 | * on the idle list. We update XPT_BUSY atomically because | ||
256 | * it also guards against trying to enqueue the svc_sock twice. | ||
257 | */ | ||
258 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) { | ||
259 | /* Don't enqueue socket while already enqueued */ | ||
260 | dprintk("svc: transport %p busy, not enqueued\n", xprt); | ||
261 | goto out_unlock; | ||
262 | } | ||
263 | BUG_ON(xprt->xpt_pool != NULL); | ||
264 | xprt->xpt_pool = pool; | ||
265 | |||
266 | /* Handle pending connection */ | ||
267 | if (test_bit(XPT_CONN, &xprt->xpt_flags)) | ||
268 | goto process; | ||
269 | |||
270 | /* Handle close in-progress */ | ||
271 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) | ||
272 | goto process; | ||
273 | |||
274 | /* Check if we have space to reply to a request */ | ||
275 | if (!xprt->xpt_ops->xpo_has_wspace(xprt)) { | ||
276 | /* Don't enqueue while not enough space for reply */ | ||
277 | dprintk("svc: no write space, transport %p not enqueued\n", | ||
278 | xprt); | ||
279 | xprt->xpt_pool = NULL; | ||
280 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
281 | goto out_unlock; | ||
282 | } | ||
283 | |||
284 | process: | ||
285 | if (!list_empty(&pool->sp_threads)) { | ||
286 | rqstp = list_entry(pool->sp_threads.next, | ||
287 | struct svc_rqst, | ||
288 | rq_list); | ||
289 | dprintk("svc: transport %p served by daemon %p\n", | ||
290 | xprt, rqstp); | ||
291 | svc_thread_dequeue(pool, rqstp); | ||
292 | if (rqstp->rq_xprt) | ||
293 | printk(KERN_ERR | ||
294 | "svc_xprt_enqueue: server %p, rq_xprt=%p!\n", | ||
295 | rqstp, rqstp->rq_xprt); | ||
296 | rqstp->rq_xprt = xprt; | ||
297 | svc_xprt_get(xprt); | ||
298 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
299 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | ||
300 | BUG_ON(xprt->xpt_pool != pool); | ||
301 | wake_up(&rqstp->rq_wait); | ||
302 | } else { | ||
303 | dprintk("svc: transport %p put into queue\n", xprt); | ||
304 | list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); | ||
305 | BUG_ON(xprt->xpt_pool != pool); | ||
306 | } | ||
307 | |||
308 | out_unlock: | ||
309 | spin_unlock_bh(&pool->sp_lock); | ||
310 | } | ||
311 | EXPORT_SYMBOL_GPL(svc_xprt_enqueue); | ||
312 | |||
313 | /* | ||
314 | * Dequeue the first socket. Must be called with the pool->sp_lock held. | ||
315 | */ | ||
316 | static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool) | ||
317 | { | ||
318 | struct svc_xprt *xprt; | ||
319 | |||
320 | if (list_empty(&pool->sp_sockets)) | ||
321 | return NULL; | ||
322 | |||
323 | xprt = list_entry(pool->sp_sockets.next, | ||
324 | struct svc_xprt, xpt_ready); | ||
325 | list_del_init(&xprt->xpt_ready); | ||
326 | |||
327 | dprintk("svc: transport %p dequeued, inuse=%d\n", | ||
328 | xprt, atomic_read(&xprt->xpt_ref.refcount)); | ||
329 | |||
330 | return xprt; | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * svc_xprt_received conditionally queues the transport for processing | ||
335 | * by another thread. The caller must hold the XPT_BUSY bit and must | ||
336 | * not thereafter touch transport data. | ||
337 | * | ||
338 | * Note: XPT_DATA only gets cleared when a read-attempt finds no (or | ||
339 | * insufficient) data. | ||
340 | */ | ||
341 | void svc_xprt_received(struct svc_xprt *xprt) | ||
342 | { | ||
343 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | ||
344 | xprt->xpt_pool = NULL; | ||
345 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
346 | svc_xprt_enqueue(xprt); | ||
347 | } | ||
348 | EXPORT_SYMBOL_GPL(svc_xprt_received); | ||
349 | |||
350 | /** | ||
351 | * svc_reserve - change the space reserved for the reply to a request. | ||
352 | * @rqstp: The request in question | ||
353 | * @space: new max space to reserve | ||
354 | * | ||
355 | * Each request reserves some space on the output queue of the socket | ||
356 | * to make sure the reply fits. This function reduces that reserved | ||
357 | * space to be the amount of space used already, plus @space. | ||
358 | * | ||
359 | */ | ||
360 | void svc_reserve(struct svc_rqst *rqstp, int space) | ||
361 | { | ||
362 | space += rqstp->rq_res.head[0].iov_len; | ||
363 | |||
364 | if (space < rqstp->rq_reserved) { | ||
365 | struct svc_xprt *xprt = rqstp->rq_xprt; | ||
366 | atomic_sub((rqstp->rq_reserved - space), &xprt->xpt_reserved); | ||
367 | rqstp->rq_reserved = space; | ||
368 | |||
369 | svc_xprt_enqueue(xprt); | ||
370 | } | ||
371 | } | ||
372 | |||
373 | static void svc_xprt_release(struct svc_rqst *rqstp) | ||
374 | { | ||
375 | struct svc_xprt *xprt = rqstp->rq_xprt; | ||
376 | |||
377 | rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp); | ||
378 | |||
379 | svc_free_res_pages(rqstp); | ||
380 | rqstp->rq_res.page_len = 0; | ||
381 | rqstp->rq_res.page_base = 0; | ||
382 | |||
383 | /* Reset response buffer and release | ||
384 | * the reservation. | ||
385 | * But first, check that enough space was reserved | ||
386 | * for the reply, otherwise we have a bug! | ||
387 | */ | ||
388 | if ((rqstp->rq_res.len) > rqstp->rq_reserved) | ||
389 | printk(KERN_ERR "RPC request reserved %d but used %d\n", | ||
390 | rqstp->rq_reserved, | ||
391 | rqstp->rq_res.len); | ||
392 | |||
393 | rqstp->rq_res.head[0].iov_len = 0; | ||
394 | svc_reserve(rqstp, 0); | ||
395 | rqstp->rq_xprt = NULL; | ||
396 | |||
397 | svc_xprt_put(xprt); | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * External function to wake up a server waiting for data | ||
402 | * This really only makes sense for services like lockd | ||
403 | * which have exactly one thread anyway. | ||
404 | */ | ||
405 | void | ||
406 | svc_wake_up(struct svc_serv *serv) | ||
407 | { | ||
408 | struct svc_rqst *rqstp; | ||
409 | unsigned int i; | ||
410 | struct svc_pool *pool; | ||
411 | |||
412 | for (i = 0; i < serv->sv_nrpools; i++) { | ||
413 | pool = &serv->sv_pools[i]; | ||
414 | |||
415 | spin_lock_bh(&pool->sp_lock); | ||
416 | if (!list_empty(&pool->sp_threads)) { | ||
417 | rqstp = list_entry(pool->sp_threads.next, | ||
418 | struct svc_rqst, | ||
419 | rq_list); | ||
420 | dprintk("svc: daemon %p woken up.\n", rqstp); | ||
421 | /* | ||
422 | svc_thread_dequeue(pool, rqstp); | ||
423 | rqstp->rq_xprt = NULL; | ||
424 | */ | ||
425 | wake_up(&rqstp->rq_wait); | ||
426 | } | ||
427 | spin_unlock_bh(&pool->sp_lock); | ||
428 | } | ||
429 | } | ||
430 | |||
431 | union svc_pktinfo_u { | 119 | union svc_pktinfo_u { |
432 | struct in_pktinfo pkti; | 120 | struct in_pktinfo pkti; |
433 | struct in6_pktinfo pkti6; | 121 | struct in6_pktinfo pkti6; |
@@ -469,8 +157,7 @@ static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh) | |||
469 | /* | 157 | /* |
470 | * Generic sendto routine | 158 | * Generic sendto routine |
471 | */ | 159 | */ |
472 | static int | 160 | static int svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) |
473 | svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) | ||
474 | { | 161 | { |
475 | struct svc_sock *svsk = | 162 | struct svc_sock *svsk = |
476 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); | 163 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); |
@@ -605,8 +292,7 @@ EXPORT_SYMBOL(svc_sock_names); | |||
605 | /* | 292 | /* |
606 | * Check input queue length | 293 | * Check input queue length |
607 | */ | 294 | */ |
608 | static int | 295 | static int svc_recv_available(struct svc_sock *svsk) |
609 | svc_recv_available(struct svc_sock *svsk) | ||
610 | { | 296 | { |
611 | struct socket *sock = svsk->sk_sock; | 297 | struct socket *sock = svsk->sk_sock; |
612 | int avail, err; | 298 | int avail, err; |
@@ -619,8 +305,8 @@ svc_recv_available(struct svc_sock *svsk) | |||
619 | /* | 305 | /* |
620 | * Generic recvfrom routine. | 306 | * Generic recvfrom routine. |
621 | */ | 307 | */ |
622 | static int | 308 | static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, |
623 | svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen) | 309 | int buflen) |
624 | { | 310 | { |
625 | struct svc_sock *svsk = | 311 | struct svc_sock *svsk = |
626 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); | 312 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); |
@@ -640,8 +326,8 @@ svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen) | |||
640 | /* | 326 | /* |
641 | * Set socket snd and rcv buffer lengths | 327 | * Set socket snd and rcv buffer lengths |
642 | */ | 328 | */ |
643 | static inline void | 329 | static void svc_sock_setbufsize(struct socket *sock, unsigned int snd, |
644 | svc_sock_setbufsize(struct socket *sock, unsigned int snd, unsigned int rcv) | 330 | unsigned int rcv) |
645 | { | 331 | { |
646 | #if 0 | 332 | #if 0 |
647 | mm_segment_t oldfs; | 333 | mm_segment_t oldfs; |
@@ -666,8 +352,7 @@ svc_sock_setbufsize(struct socket *sock, unsigned int snd, unsigned int rcv) | |||
666 | /* | 352 | /* |
667 | * INET callback when data has been received on the socket. | 353 | * INET callback when data has been received on the socket. |
668 | */ | 354 | */ |
669 | static void | 355 | static void svc_udp_data_ready(struct sock *sk, int count) |
670 | svc_udp_data_ready(struct sock *sk, int count) | ||
671 | { | 356 | { |
672 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; | 357 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
673 | 358 | ||
@@ -685,8 +370,7 @@ svc_udp_data_ready(struct sock *sk, int count) | |||
685 | /* | 370 | /* |
686 | * INET callback when space is newly available on the socket. | 371 | * INET callback when space is newly available on the socket. |
687 | */ | 372 | */ |
688 | static void | 373 | static void svc_write_space(struct sock *sk) |
689 | svc_write_space(struct sock *sk) | ||
690 | { | 374 | { |
691 | struct svc_sock *svsk = (struct svc_sock *)(sk->sk_user_data); | 375 | struct svc_sock *svsk = (struct svc_sock *)(sk->sk_user_data); |
692 | 376 | ||
@@ -732,8 +416,7 @@ static void svc_udp_get_dest_address(struct svc_rqst *rqstp, | |||
732 | /* | 416 | /* |
733 | * Receive a datagram from a UDP socket. | 417 | * Receive a datagram from a UDP socket. |
734 | */ | 418 | */ |
735 | static int | 419 | static int svc_udp_recvfrom(struct svc_rqst *rqstp) |
736 | svc_udp_recvfrom(struct svc_rqst *rqstp) | ||
737 | { | 420 | { |
738 | struct svc_sock *svsk = | 421 | struct svc_sock *svsk = |
739 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); | 422 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); |
@@ -827,7 +510,8 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
827 | skb_free_datagram(svsk->sk_sk, skb); | 510 | skb_free_datagram(svsk->sk_sk, skb); |
828 | } else { | 511 | } else { |
829 | /* we can use it in-place */ | 512 | /* we can use it in-place */ |
830 | rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); | 513 | rqstp->rq_arg.head[0].iov_base = skb->data + |
514 | sizeof(struct udphdr); | ||
831 | rqstp->rq_arg.head[0].iov_len = len; | 515 | rqstp->rq_arg.head[0].iov_len = len; |
832 | if (skb_checksum_complete(skb)) { | 516 | if (skb_checksum_complete(skb)) { |
833 | skb_free_datagram(svsk->sk_sk, skb); | 517 | skb_free_datagram(svsk->sk_sk, skb); |
@@ -938,7 +622,8 @@ static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv) | |||
938 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg, | 622 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg, |
939 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg); | 623 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg); |
940 | 624 | ||
941 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* might have come in before data_ready set up */ | 625 | /* data might have come in before data_ready set up */ |
626 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | ||
942 | set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); | 627 | set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); |
943 | 628 | ||
944 | oldfs = get_fs(); | 629 | oldfs = get_fs(); |
@@ -953,8 +638,7 @@ static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv) | |||
953 | * A data_ready event on a listening socket means there's a connection | 638 | * A data_ready event on a listening socket means there's a connection |
954 | * pending. Do not use state_change as a substitute for it. | 639 | * pending. Do not use state_change as a substitute for it. |
955 | */ | 640 | */ |
956 | static void | 641 | static void svc_tcp_listen_data_ready(struct sock *sk, int count_unused) |
957 | svc_tcp_listen_data_ready(struct sock *sk, int count_unused) | ||
958 | { | 642 | { |
959 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; | 643 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
960 | 644 | ||
@@ -986,8 +670,7 @@ svc_tcp_listen_data_ready(struct sock *sk, int count_unused) | |||
986 | /* | 670 | /* |
987 | * A state change on a connected socket means it's dying or dead. | 671 | * A state change on a connected socket means it's dying or dead. |
988 | */ | 672 | */ |
989 | static void | 673 | static void svc_tcp_state_change(struct sock *sk) |
990 | svc_tcp_state_change(struct sock *sk) | ||
991 | { | 674 | { |
992 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; | 675 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
993 | 676 | ||
@@ -1004,8 +687,7 @@ svc_tcp_state_change(struct sock *sk) | |||
1004 | wake_up_interruptible_all(sk->sk_sleep); | 687 | wake_up_interruptible_all(sk->sk_sleep); |
1005 | } | 688 | } |
1006 | 689 | ||
1007 | static void | 690 | static void svc_tcp_data_ready(struct sock *sk, int count) |
1008 | svc_tcp_data_ready(struct sock *sk, int count) | ||
1009 | { | 691 | { |
1010 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; | 692 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
1011 | 693 | ||
@@ -1019,20 +701,6 @@ svc_tcp_data_ready(struct sock *sk, int count) | |||
1019 | wake_up_interruptible(sk->sk_sleep); | 701 | wake_up_interruptible(sk->sk_sleep); |
1020 | } | 702 | } |
1021 | 703 | ||
1022 | static inline int svc_port_is_privileged(struct sockaddr *sin) | ||
1023 | { | ||
1024 | switch (sin->sa_family) { | ||
1025 | case AF_INET: | ||
1026 | return ntohs(((struct sockaddr_in *)sin)->sin_port) | ||
1027 | < PROT_SOCK; | ||
1028 | case AF_INET6: | ||
1029 | return ntohs(((struct sockaddr_in6 *)sin)->sin6_port) | ||
1030 | < PROT_SOCK; | ||
1031 | default: | ||
1032 | return 0; | ||
1033 | } | ||
1034 | } | ||
1035 | |||
1036 | /* | 704 | /* |
1037 | * Accept a TCP connection | 705 | * Accept a TCP connection |
1038 | */ | 706 | */ |
@@ -1115,8 +783,7 @@ failed: | |||
1115 | /* | 783 | /* |
1116 | * Receive data from a TCP socket. | 784 | * Receive data from a TCP socket. |
1117 | */ | 785 | */ |
1118 | static int | 786 | static int svc_tcp_recvfrom(struct svc_rqst *rqstp) |
1119 | svc_tcp_recvfrom(struct svc_rqst *rqstp) | ||
1120 | { | 787 | { |
1121 | struct svc_sock *svsk = | 788 | struct svc_sock *svsk = |
1122 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); | 789 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); |
@@ -1269,8 +936,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1269 | /* | 936 | /* |
1270 | * Send out data on TCP socket. | 937 | * Send out data on TCP socket. |
1271 | */ | 938 | */ |
1272 | static int | 939 | static int svc_tcp_sendto(struct svc_rqst *rqstp) |
1273 | svc_tcp_sendto(struct svc_rqst *rqstp) | ||
1274 | { | 940 | { |
1275 | struct xdr_buf *xbufp = &rqstp->rq_res; | 941 | struct xdr_buf *xbufp = &rqstp->rq_res; |
1276 | int sent; | 942 | int sent; |
@@ -1288,7 +954,9 @@ svc_tcp_sendto(struct svc_rqst *rqstp) | |||
1288 | 954 | ||
1289 | sent = svc_sendto(rqstp, &rqstp->rq_res); | 955 | sent = svc_sendto(rqstp, &rqstp->rq_res); |
1290 | if (sent != xbufp->len) { | 956 | if (sent != xbufp->len) { |
1291 | printk(KERN_NOTICE "rpc-srv/tcp: %s: %s %d when sending %d bytes - shutting down socket\n", | 957 | printk(KERN_NOTICE |
958 | "rpc-srv/tcp: %s: %s %d when sending %d bytes " | ||
959 | "- shutting down socket\n", | ||
1292 | rqstp->rq_xprt->xpt_server->sv_name, | 960 | rqstp->rq_xprt->xpt_server->sv_name, |
1293 | (sent<0)?"got error":"sent only", | 961 | (sent<0)?"got error":"sent only", |
1294 | sent, xbufp->len); | 962 | sent, xbufp->len); |
@@ -1410,8 +1078,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) | |||
1410 | } | 1078 | } |
1411 | } | 1079 | } |
1412 | 1080 | ||
1413 | void | 1081 | void svc_sock_update_bufs(struct svc_serv *serv) |
1414 | svc_sock_update_bufs(struct svc_serv *serv) | ||
1415 | { | 1082 | { |
1416 | /* | 1083 | /* |
1417 | * The number of server threads has changed. Update | 1084 | * The number of server threads has changed. Update |
@@ -1434,302 +1101,6 @@ svc_sock_update_bufs(struct svc_serv *serv) | |||
1434 | } | 1101 | } |
1435 | 1102 | ||
1436 | /* | 1103 | /* |
1437 | * Make sure that we don't have too many active connections. If we | ||
1438 | * have, something must be dropped. | ||
1439 | * | ||
1440 | * There's no point in trying to do random drop here for DoS | ||
1441 | * prevention. The NFS clients does 1 reconnect in 15 seconds. An | ||
1442 | * attacker can easily beat that. | ||
1443 | * | ||
1444 | * The only somewhat efficient mechanism would be if drop old | ||
1445 | * connections from the same IP first. But right now we don't even | ||
1446 | * record the client IP in svc_sock. | ||
1447 | */ | ||
1448 | static void svc_check_conn_limits(struct svc_serv *serv) | ||
1449 | { | ||
1450 | if (serv->sv_tmpcnt > (serv->sv_nrthreads+3)*20) { | ||
1451 | struct svc_xprt *xprt = NULL; | ||
1452 | spin_lock_bh(&serv->sv_lock); | ||
1453 | if (!list_empty(&serv->sv_tempsocks)) { | ||
1454 | if (net_ratelimit()) { | ||
1455 | /* Try to help the admin */ | ||
1456 | printk(KERN_NOTICE "%s: too many open " | ||
1457 | "connections, consider increasing the " | ||
1458 | "number of nfsd threads\n", | ||
1459 | serv->sv_name); | ||
1460 | } | ||
1461 | /* | ||
1462 | * Always select the oldest connection. It's not fair, | ||
1463 | * but so is life | ||
1464 | */ | ||
1465 | xprt = list_entry(serv->sv_tempsocks.prev, | ||
1466 | struct svc_xprt, | ||
1467 | xpt_list); | ||
1468 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
1469 | svc_xprt_get(xprt); | ||
1470 | } | ||
1471 | spin_unlock_bh(&serv->sv_lock); | ||
1472 | |||
1473 | if (xprt) { | ||
1474 | svc_xprt_enqueue(xprt); | ||
1475 | svc_xprt_put(xprt); | ||
1476 | } | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1480 | /* | ||
1481 | * Receive the next request on any socket. This code is carefully | ||
1482 | * organised not to touch any cachelines in the shared svc_serv | ||
1483 | * structure, only cachelines in the local svc_pool. | ||
1484 | */ | ||
1485 | int | ||
1486 | svc_recv(struct svc_rqst *rqstp, long timeout) | ||
1487 | { | ||
1488 | struct svc_xprt *xprt = NULL; | ||
1489 | struct svc_serv *serv = rqstp->rq_server; | ||
1490 | struct svc_pool *pool = rqstp->rq_pool; | ||
1491 | int len, i; | ||
1492 | int pages; | ||
1493 | struct xdr_buf *arg; | ||
1494 | DECLARE_WAITQUEUE(wait, current); | ||
1495 | |||
1496 | dprintk("svc: server %p waiting for data (to = %ld)\n", | ||
1497 | rqstp, timeout); | ||
1498 | |||
1499 | if (rqstp->rq_xprt) | ||
1500 | printk(KERN_ERR | ||
1501 | "svc_recv: service %p, transport not NULL!\n", | ||
1502 | rqstp); | ||
1503 | if (waitqueue_active(&rqstp->rq_wait)) | ||
1504 | printk(KERN_ERR | ||
1505 | "svc_recv: service %p, wait queue active!\n", | ||
1506 | rqstp); | ||
1507 | |||
1508 | |||
1509 | /* now allocate needed pages. If we get a failure, sleep briefly */ | ||
1510 | pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; | ||
1511 | for (i=0; i < pages ; i++) | ||
1512 | while (rqstp->rq_pages[i] == NULL) { | ||
1513 | struct page *p = alloc_page(GFP_KERNEL); | ||
1514 | if (!p) | ||
1515 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); | ||
1516 | rqstp->rq_pages[i] = p; | ||
1517 | } | ||
1518 | rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ | ||
1519 | BUG_ON(pages >= RPCSVC_MAXPAGES); | ||
1520 | |||
1521 | /* Make arg->head point to first page and arg->pages point to rest */ | ||
1522 | arg = &rqstp->rq_arg; | ||
1523 | arg->head[0].iov_base = page_address(rqstp->rq_pages[0]); | ||
1524 | arg->head[0].iov_len = PAGE_SIZE; | ||
1525 | arg->pages = rqstp->rq_pages + 1; | ||
1526 | arg->page_base = 0; | ||
1527 | /* save at least one page for response */ | ||
1528 | arg->page_len = (pages-2)*PAGE_SIZE; | ||
1529 | arg->len = (pages-1)*PAGE_SIZE; | ||
1530 | arg->tail[0].iov_len = 0; | ||
1531 | |||
1532 | try_to_freeze(); | ||
1533 | cond_resched(); | ||
1534 | if (signalled()) | ||
1535 | return -EINTR; | ||
1536 | |||
1537 | spin_lock_bh(&pool->sp_lock); | ||
1538 | xprt = svc_xprt_dequeue(pool); | ||
1539 | if (xprt) { | ||
1540 | rqstp->rq_xprt = xprt; | ||
1541 | svc_xprt_get(xprt); | ||
1542 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
1543 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | ||
1544 | } else { | ||
1545 | /* No data pending. Go to sleep */ | ||
1546 | svc_thread_enqueue(pool, rqstp); | ||
1547 | |||
1548 | /* | ||
1549 | * We have to be able to interrupt this wait | ||
1550 | * to bring down the daemons ... | ||
1551 | */ | ||
1552 | set_current_state(TASK_INTERRUPTIBLE); | ||
1553 | add_wait_queue(&rqstp->rq_wait, &wait); | ||
1554 | spin_unlock_bh(&pool->sp_lock); | ||
1555 | |||
1556 | schedule_timeout(timeout); | ||
1557 | |||
1558 | try_to_freeze(); | ||
1559 | |||
1560 | spin_lock_bh(&pool->sp_lock); | ||
1561 | remove_wait_queue(&rqstp->rq_wait, &wait); | ||
1562 | |||
1563 | xprt = rqstp->rq_xprt; | ||
1564 | if (!xprt) { | ||
1565 | svc_thread_dequeue(pool, rqstp); | ||
1566 | spin_unlock_bh(&pool->sp_lock); | ||
1567 | dprintk("svc: server %p, no data yet\n", rqstp); | ||
1568 | return signalled()? -EINTR : -EAGAIN; | ||
1569 | } | ||
1570 | } | ||
1571 | spin_unlock_bh(&pool->sp_lock); | ||
1572 | |||
1573 | len = 0; | ||
1574 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | ||
1575 | dprintk("svc_recv: found XPT_CLOSE\n"); | ||
1576 | svc_delete_xprt(xprt); | ||
1577 | } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | ||
1578 | struct svc_xprt *newxpt; | ||
1579 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | ||
1580 | if (newxpt) { | ||
1581 | /* | ||
1582 | * We know this module_get will succeed because the | ||
1583 | * listener holds a reference too | ||
1584 | */ | ||
1585 | __module_get(newxpt->xpt_class->xcl_owner); | ||
1586 | svc_check_conn_limits(xprt->xpt_server); | ||
1587 | spin_lock_bh(&serv->sv_lock); | ||
1588 | set_bit(XPT_TEMP, &newxpt->xpt_flags); | ||
1589 | list_add(&newxpt->xpt_list, &serv->sv_tempsocks); | ||
1590 | serv->sv_tmpcnt++; | ||
1591 | if (serv->sv_temptimer.function == NULL) { | ||
1592 | /* setup timer to age temp sockets */ | ||
1593 | setup_timer(&serv->sv_temptimer, | ||
1594 | svc_age_temp_xprts, | ||
1595 | (unsigned long)serv); | ||
1596 | mod_timer(&serv->sv_temptimer, | ||
1597 | jiffies + svc_conn_age_period * HZ); | ||
1598 | } | ||
1599 | spin_unlock_bh(&serv->sv_lock); | ||
1600 | svc_xprt_received(newxpt); | ||
1601 | } | ||
1602 | svc_xprt_received(xprt); | ||
1603 | } else { | ||
1604 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | ||
1605 | rqstp, pool->sp_id, xprt, | ||
1606 | atomic_read(&xprt->xpt_ref.refcount)); | ||
1607 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); | ||
1608 | if (rqstp->rq_deferred) { | ||
1609 | svc_xprt_received(xprt); | ||
1610 | len = svc_deferred_recv(rqstp); | ||
1611 | } else | ||
1612 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); | ||
1613 | dprintk("svc: got len=%d\n", len); | ||
1614 | } | ||
1615 | |||
1616 | /* No data, incomplete (TCP) read, or accept() */ | ||
1617 | if (len == 0 || len == -EAGAIN) { | ||
1618 | rqstp->rq_res.len = 0; | ||
1619 | svc_xprt_release(rqstp); | ||
1620 | return -EAGAIN; | ||
1621 | } | ||
1622 | clear_bit(XPT_OLD, &xprt->xpt_flags); | ||
1623 | |||
1624 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); | ||
1625 | rqstp->rq_chandle.defer = svc_defer; | ||
1626 | |||
1627 | if (serv->sv_stats) | ||
1628 | serv->sv_stats->netcnt++; | ||
1629 | return len; | ||
1630 | } | ||
1631 | |||
1632 | /* | ||
1633 | * Drop request | ||
1634 | */ | ||
1635 | void | ||
1636 | svc_drop(struct svc_rqst *rqstp) | ||
1637 | { | ||
1638 | dprintk("svc: xprt %p dropped request\n", rqstp->rq_xprt); | ||
1639 | svc_xprt_release(rqstp); | ||
1640 | } | ||
1641 | |||
1642 | /* | ||
1643 | * Return reply to client. | ||
1644 | */ | ||
1645 | int | ||
1646 | svc_send(struct svc_rqst *rqstp) | ||
1647 | { | ||
1648 | struct svc_xprt *xprt; | ||
1649 | int len; | ||
1650 | struct xdr_buf *xb; | ||
1651 | |||
1652 | xprt = rqstp->rq_xprt; | ||
1653 | if (!xprt) | ||
1654 | return -EFAULT; | ||
1655 | |||
1656 | /* release the receive skb before sending the reply */ | ||
1657 | rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp); | ||
1658 | |||
1659 | /* calculate over-all length */ | ||
1660 | xb = & rqstp->rq_res; | ||
1661 | xb->len = xb->head[0].iov_len + | ||
1662 | xb->page_len + | ||
1663 | xb->tail[0].iov_len; | ||
1664 | |||
1665 | /* Grab mutex to serialize outgoing data. */ | ||
1666 | mutex_lock(&xprt->xpt_mutex); | ||
1667 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) | ||
1668 | len = -ENOTCONN; | ||
1669 | else | ||
1670 | len = xprt->xpt_ops->xpo_sendto(rqstp); | ||
1671 | mutex_unlock(&xprt->xpt_mutex); | ||
1672 | svc_xprt_release(rqstp); | ||
1673 | |||
1674 | if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN) | ||
1675 | return 0; | ||
1676 | return len; | ||
1677 | } | ||
1678 | |||
1679 | /* | ||
1680 | * Timer function to close old temporary sockets, using | ||
1681 | * a mark-and-sweep algorithm. | ||
1682 | */ | ||
1683 | static void svc_age_temp_xprts(unsigned long closure) | ||
1684 | { | ||
1685 | struct svc_serv *serv = (struct svc_serv *)closure; | ||
1686 | struct svc_xprt *xprt; | ||
1687 | struct list_head *le, *next; | ||
1688 | LIST_HEAD(to_be_aged); | ||
1689 | |||
1690 | dprintk("svc_age_temp_xprts\n"); | ||
1691 | |||
1692 | if (!spin_trylock_bh(&serv->sv_lock)) { | ||
1693 | /* busy, try again 1 sec later */ | ||
1694 | dprintk("svc_age_temp_xprts: busy\n"); | ||
1695 | mod_timer(&serv->sv_temptimer, jiffies + HZ); | ||
1696 | return; | ||
1697 | } | ||
1698 | |||
1699 | list_for_each_safe(le, next, &serv->sv_tempsocks) { | ||
1700 | xprt = list_entry(le, struct svc_xprt, xpt_list); | ||
1701 | |||
1702 | /* First time through, just mark it OLD. Second time | ||
1703 | * through, close it. */ | ||
1704 | if (!test_and_set_bit(XPT_OLD, &xprt->xpt_flags)) | ||
1705 | continue; | ||
1706 | if (atomic_read(&xprt->xpt_ref.refcount) > 1 | ||
1707 | || test_bit(XPT_BUSY, &xprt->xpt_flags)) | ||
1708 | continue; | ||
1709 | svc_xprt_get(xprt); | ||
1710 | list_move(le, &to_be_aged); | ||
1711 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
1712 | set_bit(XPT_DETACHED, &xprt->xpt_flags); | ||
1713 | } | ||
1714 | spin_unlock_bh(&serv->sv_lock); | ||
1715 | |||
1716 | while (!list_empty(&to_be_aged)) { | ||
1717 | le = to_be_aged.next; | ||
1718 | /* fiddling the xpt_list node is safe 'cos we're XPT_DETACHED */ | ||
1719 | list_del_init(le); | ||
1720 | xprt = list_entry(le, struct svc_xprt, xpt_list); | ||
1721 | |||
1722 | dprintk("queuing xprt %p for closing\n", xprt); | ||
1723 | |||
1724 | /* a thread will dequeue and close it soon */ | ||
1725 | svc_xprt_enqueue(xprt); | ||
1726 | svc_xprt_put(xprt); | ||
1727 | } | ||
1728 | |||
1729 | mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); | ||
1730 | } | ||
1731 | |||
1732 | /* | ||
1733 | * Initialize socket for RPC use and create svc_sock struct | 1104 | * Initialize socket for RPC use and create svc_sock struct |
1734 | * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF. | 1105 | * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF. |
1735 | */ | 1106 | */ |
@@ -1913,160 +1284,3 @@ static void svc_sock_free(struct svc_xprt *xprt) | |||
1913 | sock_release(svsk->sk_sock); | 1284 | sock_release(svsk->sk_sock); |
1914 | kfree(svsk); | 1285 | kfree(svsk); |
1915 | } | 1286 | } |
1916 | |||
1917 | /* | ||
1918 | * Remove a dead transport | ||
1919 | */ | ||
1920 | static void svc_delete_xprt(struct svc_xprt *xprt) | ||
1921 | { | ||
1922 | struct svc_serv *serv = xprt->xpt_server; | ||
1923 | |||
1924 | dprintk("svc: svc_delete_xprt(%p)\n", xprt); | ||
1925 | xprt->xpt_ops->xpo_detach(xprt); | ||
1926 | |||
1927 | spin_lock_bh(&serv->sv_lock); | ||
1928 | if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags)) | ||
1929 | list_del_init(&xprt->xpt_list); | ||
1930 | /* | ||
1931 | * We used to delete the transport from whichever list | ||
1932 | * it's sk_xprt.xpt_ready node was on, but we don't actually | ||
1933 | * need to. This is because the only time we're called | ||
1934 | * while still attached to a queue, the queue itself | ||
1935 | * is about to be destroyed (in svc_destroy). | ||
1936 | */ | ||
1937 | if (!test_and_set_bit(XPT_DEAD, &xprt->xpt_flags)) { | ||
1938 | BUG_ON(atomic_read(&xprt->xpt_ref.refcount) < 2); | ||
1939 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) | ||
1940 | serv->sv_tmpcnt--; | ||
1941 | svc_xprt_put(xprt); | ||
1942 | } | ||
1943 | spin_unlock_bh(&serv->sv_lock); | ||
1944 | } | ||
1945 | |||
1946 | static void svc_close_xprt(struct svc_xprt *xprt) | ||
1947 | { | ||
1948 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
1949 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) | ||
1950 | /* someone else will have to effect the close */ | ||
1951 | return; | ||
1952 | |||
1953 | svc_xprt_get(xprt); | ||
1954 | svc_delete_xprt(xprt); | ||
1955 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
1956 | svc_xprt_put(xprt); | ||
1957 | } | ||
1958 | |||
1959 | void svc_close_all(struct list_head *xprt_list) | ||
1960 | { | ||
1961 | struct svc_xprt *xprt; | ||
1962 | struct svc_xprt *tmp; | ||
1963 | |||
1964 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { | ||
1965 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
1966 | if (test_bit(XPT_BUSY, &xprt->xpt_flags)) { | ||
1967 | /* Waiting to be processed, but no threads left, | ||
1968 | * So just remove it from the waiting list | ||
1969 | */ | ||
1970 | list_del_init(&xprt->xpt_ready); | ||
1971 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
1972 | } | ||
1973 | svc_close_xprt(xprt); | ||
1974 | } | ||
1975 | } | ||
1976 | |||
1977 | /* | ||
1978 | * Handle defer and revisit of requests | ||
1979 | */ | ||
1980 | |||
1981 | static void svc_revisit(struct cache_deferred_req *dreq, int too_many) | ||
1982 | { | ||
1983 | struct svc_deferred_req *dr = container_of(dreq, struct svc_deferred_req, handle); | ||
1984 | struct svc_xprt *xprt = dr->xprt; | ||
1985 | |||
1986 | if (too_many) { | ||
1987 | svc_xprt_put(xprt); | ||
1988 | kfree(dr); | ||
1989 | return; | ||
1990 | } | ||
1991 | dprintk("revisit queued\n"); | ||
1992 | dr->xprt = NULL; | ||
1993 | spin_lock(&xprt->xpt_lock); | ||
1994 | list_add(&dr->handle.recent, &xprt->xpt_deferred); | ||
1995 | spin_unlock(&xprt->xpt_lock); | ||
1996 | set_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
1997 | svc_xprt_enqueue(xprt); | ||
1998 | svc_xprt_put(xprt); | ||
1999 | } | ||
2000 | |||
2001 | static struct cache_deferred_req * | ||
2002 | svc_defer(struct cache_req *req) | ||
2003 | { | ||
2004 | struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle); | ||
2005 | int size = sizeof(struct svc_deferred_req) + (rqstp->rq_arg.len); | ||
2006 | struct svc_deferred_req *dr; | ||
2007 | |||
2008 | if (rqstp->rq_arg.page_len) | ||
2009 | return NULL; /* if more than a page, give up FIXME */ | ||
2010 | if (rqstp->rq_deferred) { | ||
2011 | dr = rqstp->rq_deferred; | ||
2012 | rqstp->rq_deferred = NULL; | ||
2013 | } else { | ||
2014 | int skip = rqstp->rq_arg.len - rqstp->rq_arg.head[0].iov_len; | ||
2015 | /* FIXME maybe discard if size too large */ | ||
2016 | dr = kmalloc(size, GFP_KERNEL); | ||
2017 | if (dr == NULL) | ||
2018 | return NULL; | ||
2019 | |||
2020 | dr->handle.owner = rqstp->rq_server; | ||
2021 | dr->prot = rqstp->rq_prot; | ||
2022 | memcpy(&dr->addr, &rqstp->rq_addr, rqstp->rq_addrlen); | ||
2023 | dr->addrlen = rqstp->rq_addrlen; | ||
2024 | dr->daddr = rqstp->rq_daddr; | ||
2025 | dr->argslen = rqstp->rq_arg.len >> 2; | ||
2026 | memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2); | ||
2027 | } | ||
2028 | svc_xprt_get(rqstp->rq_xprt); | ||
2029 | dr->xprt = rqstp->rq_xprt; | ||
2030 | |||
2031 | dr->handle.revisit = svc_revisit; | ||
2032 | return &dr->handle; | ||
2033 | } | ||
2034 | |||
2035 | /* | ||
2036 | * recv data from a deferred request into an active one | ||
2037 | */ | ||
2038 | static int svc_deferred_recv(struct svc_rqst *rqstp) | ||
2039 | { | ||
2040 | struct svc_deferred_req *dr = rqstp->rq_deferred; | ||
2041 | |||
2042 | rqstp->rq_arg.head[0].iov_base = dr->args; | ||
2043 | rqstp->rq_arg.head[0].iov_len = dr->argslen<<2; | ||
2044 | rqstp->rq_arg.page_len = 0; | ||
2045 | rqstp->rq_arg.len = dr->argslen<<2; | ||
2046 | rqstp->rq_prot = dr->prot; | ||
2047 | memcpy(&rqstp->rq_addr, &dr->addr, dr->addrlen); | ||
2048 | rqstp->rq_addrlen = dr->addrlen; | ||
2049 | rqstp->rq_daddr = dr->daddr; | ||
2050 | rqstp->rq_respages = rqstp->rq_pages; | ||
2051 | return dr->argslen<<2; | ||
2052 | } | ||
2053 | |||
2054 | |||
2055 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) | ||
2056 | { | ||
2057 | struct svc_deferred_req *dr = NULL; | ||
2058 | |||
2059 | if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags)) | ||
2060 | return NULL; | ||
2061 | spin_lock(&xprt->xpt_lock); | ||
2062 | clear_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
2063 | if (!list_empty(&xprt->xpt_deferred)) { | ||
2064 | dr = list_entry(xprt->xpt_deferred.next, | ||
2065 | struct svc_deferred_req, | ||
2066 | handle.recent); | ||
2067 | list_del_init(&dr->handle.recent); | ||
2068 | set_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
2069 | } | ||
2070 | spin_unlock(&xprt->xpt_lock); | ||
2071 | return dr; | ||
2072 | } | ||