diff options
| -rw-r--r-- | include/linux/sunrpc/svc_xprt.h | 27 | ||||
| -rw-r--r-- | net/sunrpc/svc_xprt.c | 753 | ||||
| -rw-r--r-- | net/sunrpc/svcsock.c | 834 |
3 files changed, 804 insertions, 810 deletions
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index 09de12b63c1d..405281e745d1 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h | |||
| @@ -72,9 +72,14 @@ void svc_unreg_xprt_class(struct svc_xprt_class *); | |||
| 72 | void svc_xprt_init(struct svc_xprt_class *, struct svc_xprt *, | 72 | void svc_xprt_init(struct svc_xprt_class *, struct svc_xprt *, |
| 73 | struct svc_serv *); | 73 | struct svc_serv *); |
| 74 | int svc_create_xprt(struct svc_serv *, char *, unsigned short, int); | 74 | int svc_create_xprt(struct svc_serv *, char *, unsigned short, int); |
| 75 | void svc_xprt_enqueue(struct svc_xprt *xprt); | ||
| 75 | void svc_xprt_received(struct svc_xprt *); | 76 | void svc_xprt_received(struct svc_xprt *); |
| 76 | void svc_xprt_put(struct svc_xprt *xprt); | 77 | void svc_xprt_put(struct svc_xprt *xprt); |
| 77 | void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt); | 78 | void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt); |
| 79 | void svc_close_xprt(struct svc_xprt *xprt); | ||
| 80 | void svc_delete_xprt(struct svc_xprt *xprt); | ||
| 81 | int svc_port_is_privileged(struct sockaddr *sin); | ||
| 82 | |||
| 78 | static inline void svc_xprt_get(struct svc_xprt *xprt) | 83 | static inline void svc_xprt_get(struct svc_xprt *xprt) |
| 79 | { | 84 | { |
| 80 | kref_get(&xprt->xpt_ref); | 85 | kref_get(&xprt->xpt_ref); |
| @@ -126,4 +131,26 @@ static inline unsigned short svc_xprt_remote_port(struct svc_xprt *xprt) | |||
| 126 | return svc_addr_port((struct sockaddr *)&xprt->xpt_remote); | 131 | return svc_addr_port((struct sockaddr *)&xprt->xpt_remote); |
| 127 | } | 132 | } |
| 128 | 133 | ||
| 134 | static inline char *__svc_print_addr(struct sockaddr *addr, | ||
| 135 | char *buf, size_t len) | ||
| 136 | { | ||
| 137 | switch (addr->sa_family) { | ||
| 138 | case AF_INET: | ||
| 139 | snprintf(buf, len, "%u.%u.%u.%u, port=%u", | ||
| 140 | NIPQUAD(((struct sockaddr_in *) addr)->sin_addr), | ||
| 141 | ntohs(((struct sockaddr_in *) addr)->sin_port)); | ||
| 142 | break; | ||
| 143 | |||
| 144 | case AF_INET6: | ||
| 145 | snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x, port=%u", | ||
| 146 | NIP6(((struct sockaddr_in6 *) addr)->sin6_addr), | ||
| 147 | ntohs(((struct sockaddr_in6 *) addr)->sin6_port)); | ||
| 148 | break; | ||
| 149 | |||
| 150 | default: | ||
| 151 | snprintf(buf, len, "unknown address type: %d", addr->sa_family); | ||
| 152 | break; | ||
| 153 | } | ||
| 154 | return buf; | ||
| 155 | } | ||
| 129 | #endif /* SUNRPC_SVC_XPRT_H */ | 156 | #endif /* SUNRPC_SVC_XPRT_H */ |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 271467c5138d..23165aef59d9 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
| @@ -35,10 +35,53 @@ | |||
| 35 | 35 | ||
| 36 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | 36 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT |
| 37 | 37 | ||
| 38 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); | ||
| 39 | static int svc_deferred_recv(struct svc_rqst *rqstp); | ||
| 40 | static struct cache_deferred_req *svc_defer(struct cache_req *req); | ||
| 41 | static void svc_age_temp_xprts(unsigned long closure); | ||
| 42 | |||
| 43 | /* apparently the "standard" is that clients close | ||
| 44 | * idle connections after 5 minutes, servers after | ||
| 45 | * 6 minutes | ||
| 46 | * http://www.connectathon.org/talks96/nfstcp.pdf | ||
| 47 | */ | ||
| 48 | static int svc_conn_age_period = 6*60; | ||
| 49 | |||
| 38 | /* List of registered transport classes */ | 50 | /* List of registered transport classes */ |
| 39 | static DEFINE_SPINLOCK(svc_xprt_class_lock); | 51 | static DEFINE_SPINLOCK(svc_xprt_class_lock); |
| 40 | static LIST_HEAD(svc_xprt_class_list); | 52 | static LIST_HEAD(svc_xprt_class_list); |
| 41 | 53 | ||
| 54 | /* SMP locking strategy: | ||
| 55 | * | ||
| 56 | * svc_pool->sp_lock protects most of the fields of that pool. | ||
| 57 | * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt. | ||
| 58 | * when both need to be taken (rare), svc_serv->sv_lock is first. | ||
| 59 | * BKL protects svc_serv->sv_nrthread. | ||
| 60 | * svc_sock->sk_lock protects the svc_sock->sk_deferred list | ||
| 61 | * and the ->sk_info_authunix cache. | ||
| 62 | * | ||
| 63 | * The XPT_BUSY bit in xprt->xpt_flags prevents a transport being | ||
| 64 | * enqueued multiply. During normal transport processing this bit | ||
| 65 | * is set by svc_xprt_enqueue and cleared by svc_xprt_received. | ||
| 66 | * Providers should not manipulate this bit directly. | ||
| 67 | * | ||
| 68 | * Some flags can be set to certain values at any time | ||
| 69 | * providing that certain rules are followed: | ||
| 70 | * | ||
| 71 | * XPT_CONN, XPT_DATA: | ||
| 72 | * - Can be set or cleared at any time. | ||
| 73 | * - After a set, svc_xprt_enqueue must be called to enqueue | ||
| 74 | * the transport for processing. | ||
| 75 | * - After a clear, the transport must be read/accepted. | ||
| 76 | * If this succeeds, it must be set again. | ||
| 77 | * XPT_CLOSE: | ||
| 78 | * - Can set at any time. It is never cleared. | ||
| 79 | * XPT_DEAD: | ||
| 80 | * - Can only be set while XPT_BUSY is held which ensures | ||
| 81 | * that no other thread will be using the transport or will | ||
| 82 | * try to set XPT_DEAD. | ||
| 83 | */ | ||
| 84 | |||
| 42 | int svc_reg_xprt_class(struct svc_xprt_class *xcl) | 85 | int svc_reg_xprt_class(struct svc_xprt_class *xcl) |
| 43 | { | 86 | { |
| 44 | struct svc_xprt_class *cl; | 87 | struct svc_xprt_class *cl; |
| @@ -178,3 +221,713 @@ void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt) | |||
| 178 | } | 221 | } |
| 179 | EXPORT_SYMBOL_GPL(svc_xprt_copy_addrs); | 222 | EXPORT_SYMBOL_GPL(svc_xprt_copy_addrs); |
| 180 | 223 | ||
| 224 | /** | ||
| 225 | * svc_print_addr - Format rq_addr field for printing | ||
| 226 | * @rqstp: svc_rqst struct containing address to print | ||
| 227 | * @buf: target buffer for formatted address | ||
| 228 | * @len: length of target buffer | ||
| 229 | * | ||
| 230 | */ | ||
| 231 | char *svc_print_addr(struct svc_rqst *rqstp, char *buf, size_t len) | ||
| 232 | { | ||
| 233 | return __svc_print_addr(svc_addr(rqstp), buf, len); | ||
| 234 | } | ||
| 235 | EXPORT_SYMBOL_GPL(svc_print_addr); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * Queue up an idle server thread. Must have pool->sp_lock held. | ||
| 239 | * Note: this is really a stack rather than a queue, so that we only | ||
| 240 | * use as many different threads as we need, and the rest don't pollute | ||
| 241 | * the cache. | ||
| 242 | */ | ||
| 243 | static void svc_thread_enqueue(struct svc_pool *pool, struct svc_rqst *rqstp) | ||
| 244 | { | ||
| 245 | list_add(&rqstp->rq_list, &pool->sp_threads); | ||
| 246 | } | ||
| 247 | |||
| 248 | /* | ||
| 249 | * Dequeue an nfsd thread. Must have pool->sp_lock held. | ||
| 250 | */ | ||
| 251 | static void svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp) | ||
| 252 | { | ||
| 253 | list_del(&rqstp->rq_list); | ||
| 254 | } | ||
| 255 | |||
| 256 | /* | ||
| 257 | * Queue up a transport with data pending. If there are idle nfsd | ||
| 258 | * processes, wake 'em up. | ||
| 259 | * | ||
| 260 | */ | ||
| 261 | void svc_xprt_enqueue(struct svc_xprt *xprt) | ||
| 262 | { | ||
| 263 | struct svc_serv *serv = xprt->xpt_server; | ||
| 264 | struct svc_pool *pool; | ||
| 265 | struct svc_rqst *rqstp; | ||
| 266 | int cpu; | ||
| 267 | |||
| 268 | if (!(xprt->xpt_flags & | ||
| 269 | ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) | ||
| 270 | return; | ||
| 271 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) | ||
| 272 | return; | ||
| 273 | |||
| 274 | cpu = get_cpu(); | ||
| 275 | pool = svc_pool_for_cpu(xprt->xpt_server, cpu); | ||
| 276 | put_cpu(); | ||
| 277 | |||
| 278 | spin_lock_bh(&pool->sp_lock); | ||
| 279 | |||
| 280 | if (!list_empty(&pool->sp_threads) && | ||
| 281 | !list_empty(&pool->sp_sockets)) | ||
| 282 | printk(KERN_ERR | ||
| 283 | "svc_xprt_enqueue: " | ||
| 284 | "threads and transports both waiting??\n"); | ||
| 285 | |||
| 286 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) { | ||
| 287 | /* Don't enqueue dead transports */ | ||
| 288 | dprintk("svc: transport %p is dead, not enqueued\n", xprt); | ||
| 289 | goto out_unlock; | ||
| 290 | } | ||
| 291 | |||
| 292 | /* Mark transport as busy. It will remain in this state until | ||
| 293 | * the provider calls svc_xprt_received. We update XPT_BUSY | ||
| 294 | * atomically because it also guards against trying to enqueue | ||
| 295 | * the transport twice. | ||
| 296 | */ | ||
| 297 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) { | ||
| 298 | /* Don't enqueue transport while already enqueued */ | ||
| 299 | dprintk("svc: transport %p busy, not enqueued\n", xprt); | ||
| 300 | goto out_unlock; | ||
| 301 | } | ||
| 302 | BUG_ON(xprt->xpt_pool != NULL); | ||
| 303 | xprt->xpt_pool = pool; | ||
| 304 | |||
| 305 | /* Handle pending connection */ | ||
| 306 | if (test_bit(XPT_CONN, &xprt->xpt_flags)) | ||
| 307 | goto process; | ||
| 308 | |||
| 309 | /* Handle close in-progress */ | ||
| 310 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) | ||
| 311 | goto process; | ||
| 312 | |||
| 313 | /* Check if we have space to reply to a request */ | ||
| 314 | if (!xprt->xpt_ops->xpo_has_wspace(xprt)) { | ||
| 315 | /* Don't enqueue while not enough space for reply */ | ||
| 316 | dprintk("svc: no write space, transport %p not enqueued\n", | ||
| 317 | xprt); | ||
| 318 | xprt->xpt_pool = NULL; | ||
| 319 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
| 320 | goto out_unlock; | ||
| 321 | } | ||
| 322 | |||
| 323 | process: | ||
| 324 | if (!list_empty(&pool->sp_threads)) { | ||
| 325 | rqstp = list_entry(pool->sp_threads.next, | ||
| 326 | struct svc_rqst, | ||
| 327 | rq_list); | ||
| 328 | dprintk("svc: transport %p served by daemon %p\n", | ||
| 329 | xprt, rqstp); | ||
| 330 | svc_thread_dequeue(pool, rqstp); | ||
| 331 | if (rqstp->rq_xprt) | ||
| 332 | printk(KERN_ERR | ||
| 333 | "svc_xprt_enqueue: server %p, rq_xprt=%p!\n", | ||
| 334 | rqstp, rqstp->rq_xprt); | ||
| 335 | rqstp->rq_xprt = xprt; | ||
| 336 | svc_xprt_get(xprt); | ||
| 337 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
| 338 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | ||
| 339 | BUG_ON(xprt->xpt_pool != pool); | ||
| 340 | wake_up(&rqstp->rq_wait); | ||
| 341 | } else { | ||
| 342 | dprintk("svc: transport %p put into queue\n", xprt); | ||
| 343 | list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); | ||
| 344 | BUG_ON(xprt->xpt_pool != pool); | ||
| 345 | } | ||
| 346 | |||
| 347 | out_unlock: | ||
| 348 | spin_unlock_bh(&pool->sp_lock); | ||
| 349 | } | ||
| 350 | EXPORT_SYMBOL_GPL(svc_xprt_enqueue); | ||
| 351 | |||
| 352 | /* | ||
| 353 | * Dequeue the first transport. Must be called with the pool->sp_lock held. | ||
| 354 | */ | ||
| 355 | static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool) | ||
| 356 | { | ||
| 357 | struct svc_xprt *xprt; | ||
| 358 | |||
| 359 | if (list_empty(&pool->sp_sockets)) | ||
| 360 | return NULL; | ||
| 361 | |||
| 362 | xprt = list_entry(pool->sp_sockets.next, | ||
| 363 | struct svc_xprt, xpt_ready); | ||
| 364 | list_del_init(&xprt->xpt_ready); | ||
| 365 | |||
| 366 | dprintk("svc: transport %p dequeued, inuse=%d\n", | ||
| 367 | xprt, atomic_read(&xprt->xpt_ref.refcount)); | ||
| 368 | |||
| 369 | return xprt; | ||
| 370 | } | ||
| 371 | |||
| 372 | /* | ||
| 373 | * svc_xprt_received conditionally queues the transport for processing | ||
| 374 | * by another thread. The caller must hold the XPT_BUSY bit and must | ||
| 375 | * not thereafter touch transport data. | ||
| 376 | * | ||
| 377 | * Note: XPT_DATA only gets cleared when a read-attempt finds no (or | ||
| 378 | * insufficient) data. | ||
| 379 | */ | ||
| 380 | void svc_xprt_received(struct svc_xprt *xprt) | ||
| 381 | { | ||
| 382 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | ||
| 383 | xprt->xpt_pool = NULL; | ||
| 384 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
| 385 | svc_xprt_enqueue(xprt); | ||
| 386 | } | ||
| 387 | EXPORT_SYMBOL_GPL(svc_xprt_received); | ||
| 388 | |||
| 389 | /** | ||
| 390 | * svc_reserve - change the space reserved for the reply to a request. | ||
| 391 | * @rqstp: The request in question | ||
| 392 | * @space: new max space to reserve | ||
| 393 | * | ||
| 394 | * Each request reserves some space on the output queue of the transport | ||
| 395 | * to make sure the reply fits. This function reduces that reserved | ||
| 396 | * space to be the amount of space used already, plus @space. | ||
| 397 | * | ||
| 398 | */ | ||
| 399 | void svc_reserve(struct svc_rqst *rqstp, int space) | ||
| 400 | { | ||
| 401 | space += rqstp->rq_res.head[0].iov_len; | ||
| 402 | |||
| 403 | if (space < rqstp->rq_reserved) { | ||
| 404 | struct svc_xprt *xprt = rqstp->rq_xprt; | ||
| 405 | atomic_sub((rqstp->rq_reserved - space), &xprt->xpt_reserved); | ||
| 406 | rqstp->rq_reserved = space; | ||
| 407 | |||
| 408 | svc_xprt_enqueue(xprt); | ||
| 409 | } | ||
| 410 | } | ||
| 411 | |||
| 412 | static void svc_xprt_release(struct svc_rqst *rqstp) | ||
| 413 | { | ||
| 414 | struct svc_xprt *xprt = rqstp->rq_xprt; | ||
| 415 | |||
| 416 | rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp); | ||
| 417 | |||
| 418 | svc_free_res_pages(rqstp); | ||
| 419 | rqstp->rq_res.page_len = 0; | ||
| 420 | rqstp->rq_res.page_base = 0; | ||
| 421 | |||
| 422 | /* Reset response buffer and release | ||
| 423 | * the reservation. | ||
| 424 | * But first, check that enough space was reserved | ||
| 425 | * for the reply, otherwise we have a bug! | ||
| 426 | */ | ||
| 427 | if ((rqstp->rq_res.len) > rqstp->rq_reserved) | ||
| 428 | printk(KERN_ERR "RPC request reserved %d but used %d\n", | ||
| 429 | rqstp->rq_reserved, | ||
| 430 | rqstp->rq_res.len); | ||
| 431 | |||
| 432 | rqstp->rq_res.head[0].iov_len = 0; | ||
| 433 | svc_reserve(rqstp, 0); | ||
| 434 | rqstp->rq_xprt = NULL; | ||
| 435 | |||
| 436 | svc_xprt_put(xprt); | ||
| 437 | } | ||
| 438 | |||
| 439 | /* | ||
| 440 | * External function to wake up a server waiting for data | ||
| 441 | * This really only makes sense for services like lockd | ||
| 442 | * which have exactly one thread anyway. | ||
| 443 | */ | ||
| 444 | void svc_wake_up(struct svc_serv *serv) | ||
| 445 | { | ||
| 446 | struct svc_rqst *rqstp; | ||
| 447 | unsigned int i; | ||
| 448 | struct svc_pool *pool; | ||
| 449 | |||
| 450 | for (i = 0; i < serv->sv_nrpools; i++) { | ||
| 451 | pool = &serv->sv_pools[i]; | ||
| 452 | |||
| 453 | spin_lock_bh(&pool->sp_lock); | ||
| 454 | if (!list_empty(&pool->sp_threads)) { | ||
| 455 | rqstp = list_entry(pool->sp_threads.next, | ||
| 456 | struct svc_rqst, | ||
| 457 | rq_list); | ||
| 458 | dprintk("svc: daemon %p woken up.\n", rqstp); | ||
| 459 | /* | ||
| 460 | svc_thread_dequeue(pool, rqstp); | ||
| 461 | rqstp->rq_xprt = NULL; | ||
| 462 | */ | ||
| 463 | wake_up(&rqstp->rq_wait); | ||
| 464 | } | ||
| 465 | spin_unlock_bh(&pool->sp_lock); | ||
| 466 | } | ||
| 467 | } | ||
| 468 | |||
| 469 | int svc_port_is_privileged(struct sockaddr *sin) | ||
| 470 | { | ||
| 471 | switch (sin->sa_family) { | ||
| 472 | case AF_INET: | ||
| 473 | return ntohs(((struct sockaddr_in *)sin)->sin_port) | ||
| 474 | < PROT_SOCK; | ||
| 475 | case AF_INET6: | ||
| 476 | return ntohs(((struct sockaddr_in6 *)sin)->sin6_port) | ||
| 477 | < PROT_SOCK; | ||
| 478 | default: | ||
| 479 | return 0; | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 483 | /* | ||
| 484 | * Make sure that we don't have too many active connections. If we | ||
| 485 | * have, something must be dropped. | ||
| 486 | * | ||
| 487 | * There's no point in trying to do random drop here for DoS | ||
| 488 | * prevention. The NFS clients does 1 reconnect in 15 seconds. An | ||
| 489 | * attacker can easily beat that. | ||
| 490 | * | ||
| 491 | * The only somewhat efficient mechanism would be if drop old | ||
| 492 | * connections from the same IP first. But right now we don't even | ||
| 493 | * record the client IP in svc_sock. | ||
| 494 | */ | ||
| 495 | static void svc_check_conn_limits(struct svc_serv *serv) | ||
| 496 | { | ||
| 497 | if (serv->sv_tmpcnt > (serv->sv_nrthreads+3)*20) { | ||
| 498 | struct svc_xprt *xprt = NULL; | ||
| 499 | spin_lock_bh(&serv->sv_lock); | ||
| 500 | if (!list_empty(&serv->sv_tempsocks)) { | ||
| 501 | if (net_ratelimit()) { | ||
| 502 | /* Try to help the admin */ | ||
| 503 | printk(KERN_NOTICE "%s: too many open " | ||
| 504 | "connections, consider increasing the " | ||
| 505 | "number of nfsd threads\n", | ||
| 506 | serv->sv_name); | ||
| 507 | } | ||
| 508 | /* | ||
| 509 | * Always select the oldest connection. It's not fair, | ||
| 510 | * but so is life | ||
| 511 | */ | ||
| 512 | xprt = list_entry(serv->sv_tempsocks.prev, | ||
| 513 | struct svc_xprt, | ||
| 514 | xpt_list); | ||
| 515 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
| 516 | svc_xprt_get(xprt); | ||
| 517 | } | ||
| 518 | spin_unlock_bh(&serv->sv_lock); | ||
| 519 | |||
| 520 | if (xprt) { | ||
| 521 | svc_xprt_enqueue(xprt); | ||
| 522 | svc_xprt_put(xprt); | ||
| 523 | } | ||
| 524 | } | ||
| 525 | } | ||
| 526 | |||
| 527 | /* | ||
| 528 | * Receive the next request on any transport. This code is carefully | ||
| 529 | * organised not to touch any cachelines in the shared svc_serv | ||
| 530 | * structure, only cachelines in the local svc_pool. | ||
| 531 | */ | ||
| 532 | int svc_recv(struct svc_rqst *rqstp, long timeout) | ||
| 533 | { | ||
| 534 | struct svc_xprt *xprt = NULL; | ||
| 535 | struct svc_serv *serv = rqstp->rq_server; | ||
| 536 | struct svc_pool *pool = rqstp->rq_pool; | ||
| 537 | int len, i; | ||
| 538 | int pages; | ||
| 539 | struct xdr_buf *arg; | ||
| 540 | DECLARE_WAITQUEUE(wait, current); | ||
| 541 | |||
| 542 | dprintk("svc: server %p waiting for data (to = %ld)\n", | ||
| 543 | rqstp, timeout); | ||
| 544 | |||
| 545 | if (rqstp->rq_xprt) | ||
| 546 | printk(KERN_ERR | ||
| 547 | "svc_recv: service %p, transport not NULL!\n", | ||
| 548 | rqstp); | ||
| 549 | if (waitqueue_active(&rqstp->rq_wait)) | ||
| 550 | printk(KERN_ERR | ||
| 551 | "svc_recv: service %p, wait queue active!\n", | ||
| 552 | rqstp); | ||
| 553 | |||
| 554 | /* now allocate needed pages. If we get a failure, sleep briefly */ | ||
| 555 | pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; | ||
| 556 | for (i = 0; i < pages ; i++) | ||
| 557 | while (rqstp->rq_pages[i] == NULL) { | ||
| 558 | struct page *p = alloc_page(GFP_KERNEL); | ||
| 559 | if (!p) { | ||
| 560 | int j = msecs_to_jiffies(500); | ||
| 561 | schedule_timeout_uninterruptible(j); | ||
| 562 | } | ||
| 563 | rqstp->rq_pages[i] = p; | ||
| 564 | } | ||
| 565 | rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ | ||
| 566 | BUG_ON(pages >= RPCSVC_MAXPAGES); | ||
| 567 | |||
| 568 | /* Make arg->head point to first page and arg->pages point to rest */ | ||
| 569 | arg = &rqstp->rq_arg; | ||
| 570 | arg->head[0].iov_base = page_address(rqstp->rq_pages[0]); | ||
| 571 | arg->head[0].iov_len = PAGE_SIZE; | ||
| 572 | arg->pages = rqstp->rq_pages + 1; | ||
| 573 | arg->page_base = 0; | ||
| 574 | /* save at least one page for response */ | ||
| 575 | arg->page_len = (pages-2)*PAGE_SIZE; | ||
| 576 | arg->len = (pages-1)*PAGE_SIZE; | ||
| 577 | arg->tail[0].iov_len = 0; | ||
| 578 | |||
| 579 | try_to_freeze(); | ||
| 580 | cond_resched(); | ||
| 581 | if (signalled()) | ||
| 582 | return -EINTR; | ||
| 583 | |||
| 584 | spin_lock_bh(&pool->sp_lock); | ||
| 585 | xprt = svc_xprt_dequeue(pool); | ||
| 586 | if (xprt) { | ||
| 587 | rqstp->rq_xprt = xprt; | ||
| 588 | svc_xprt_get(xprt); | ||
| 589 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
| 590 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | ||
| 591 | } else { | ||
| 592 | /* No data pending. Go to sleep */ | ||
| 593 | svc_thread_enqueue(pool, rqstp); | ||
| 594 | |||
| 595 | /* | ||
| 596 | * We have to be able to interrupt this wait | ||
| 597 | * to bring down the daemons ... | ||
| 598 | */ | ||
| 599 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 600 | add_wait_queue(&rqstp->rq_wait, &wait); | ||
| 601 | spin_unlock_bh(&pool->sp_lock); | ||
| 602 | |||
| 603 | schedule_timeout(timeout); | ||
| 604 | |||
| 605 | try_to_freeze(); | ||
| 606 | |||
| 607 | spin_lock_bh(&pool->sp_lock); | ||
| 608 | remove_wait_queue(&rqstp->rq_wait, &wait); | ||
| 609 | |||
| 610 | xprt = rqstp->rq_xprt; | ||
| 611 | if (!xprt) { | ||
| 612 | svc_thread_dequeue(pool, rqstp); | ||
| 613 | spin_unlock_bh(&pool->sp_lock); | ||
| 614 | dprintk("svc: server %p, no data yet\n", rqstp); | ||
| 615 | return signalled()? -EINTR : -EAGAIN; | ||
| 616 | } | ||
| 617 | } | ||
| 618 | spin_unlock_bh(&pool->sp_lock); | ||
| 619 | |||
| 620 | len = 0; | ||
| 621 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | ||
| 622 | dprintk("svc_recv: found XPT_CLOSE\n"); | ||
| 623 | svc_delete_xprt(xprt); | ||
| 624 | } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | ||
| 625 | struct svc_xprt *newxpt; | ||
| 626 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | ||
| 627 | if (newxpt) { | ||
| 628 | /* | ||
| 629 | * We know this module_get will succeed because the | ||
| 630 | * listener holds a reference too | ||
| 631 | */ | ||
| 632 | __module_get(newxpt->xpt_class->xcl_owner); | ||
| 633 | svc_check_conn_limits(xprt->xpt_server); | ||
| 634 | spin_lock_bh(&serv->sv_lock); | ||
| 635 | set_bit(XPT_TEMP, &newxpt->xpt_flags); | ||
| 636 | list_add(&newxpt->xpt_list, &serv->sv_tempsocks); | ||
| 637 | serv->sv_tmpcnt++; | ||
| 638 | if (serv->sv_temptimer.function == NULL) { | ||
| 639 | /* setup timer to age temp transports */ | ||
| 640 | setup_timer(&serv->sv_temptimer, | ||
| 641 | svc_age_temp_xprts, | ||
| 642 | (unsigned long)serv); | ||
| 643 | mod_timer(&serv->sv_temptimer, | ||
| 644 | jiffies + svc_conn_age_period * HZ); | ||
| 645 | } | ||
| 646 | spin_unlock_bh(&serv->sv_lock); | ||
| 647 | svc_xprt_received(newxpt); | ||
| 648 | } | ||
| 649 | svc_xprt_received(xprt); | ||
| 650 | } else { | ||
| 651 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | ||
| 652 | rqstp, pool->sp_id, xprt, | ||
| 653 | atomic_read(&xprt->xpt_ref.refcount)); | ||
| 654 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); | ||
| 655 | if (rqstp->rq_deferred) { | ||
| 656 | svc_xprt_received(xprt); | ||
| 657 | len = svc_deferred_recv(rqstp); | ||
| 658 | } else | ||
| 659 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); | ||
| 660 | dprintk("svc: got len=%d\n", len); | ||
| 661 | } | ||
| 662 | |||
| 663 | /* No data, incomplete (TCP) read, or accept() */ | ||
| 664 | if (len == 0 || len == -EAGAIN) { | ||
| 665 | rqstp->rq_res.len = 0; | ||
| 666 | svc_xprt_release(rqstp); | ||
| 667 | return -EAGAIN; | ||
| 668 | } | ||
| 669 | clear_bit(XPT_OLD, &xprt->xpt_flags); | ||
| 670 | |||
| 671 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); | ||
| 672 | rqstp->rq_chandle.defer = svc_defer; | ||
| 673 | |||
| 674 | if (serv->sv_stats) | ||
| 675 | serv->sv_stats->netcnt++; | ||
| 676 | return len; | ||
| 677 | } | ||
| 678 | |||
| 679 | /* | ||
| 680 | * Drop request | ||
| 681 | */ | ||
| 682 | void svc_drop(struct svc_rqst *rqstp) | ||
| 683 | { | ||
| 684 | dprintk("svc: xprt %p dropped request\n", rqstp->rq_xprt); | ||
| 685 | svc_xprt_release(rqstp); | ||
| 686 | } | ||
| 687 | |||
| 688 | /* | ||
| 689 | * Return reply to client. | ||
| 690 | */ | ||
| 691 | int svc_send(struct svc_rqst *rqstp) | ||
| 692 | { | ||
| 693 | struct svc_xprt *xprt; | ||
| 694 | int len; | ||
| 695 | struct xdr_buf *xb; | ||
| 696 | |||
| 697 | xprt = rqstp->rq_xprt; | ||
| 698 | if (!xprt) | ||
| 699 | return -EFAULT; | ||
| 700 | |||
| 701 | /* release the receive skb before sending the reply */ | ||
| 702 | rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp); | ||
| 703 | |||
| 704 | /* calculate over-all length */ | ||
| 705 | xb = &rqstp->rq_res; | ||
| 706 | xb->len = xb->head[0].iov_len + | ||
| 707 | xb->page_len + | ||
| 708 | xb->tail[0].iov_len; | ||
| 709 | |||
| 710 | /* Grab mutex to serialize outgoing data. */ | ||
| 711 | mutex_lock(&xprt->xpt_mutex); | ||
| 712 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) | ||
| 713 | len = -ENOTCONN; | ||
| 714 | else | ||
| 715 | len = xprt->xpt_ops->xpo_sendto(rqstp); | ||
| 716 | mutex_unlock(&xprt->xpt_mutex); | ||
| 717 | svc_xprt_release(rqstp); | ||
| 718 | |||
| 719 | if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN) | ||
| 720 | return 0; | ||
| 721 | return len; | ||
| 722 | } | ||
| 723 | |||
| 724 | /* | ||
| 725 | * Timer function to close old temporary transports, using | ||
| 726 | * a mark-and-sweep algorithm. | ||
| 727 | */ | ||
| 728 | static void svc_age_temp_xprts(unsigned long closure) | ||
| 729 | { | ||
| 730 | struct svc_serv *serv = (struct svc_serv *)closure; | ||
| 731 | struct svc_xprt *xprt; | ||
| 732 | struct list_head *le, *next; | ||
| 733 | LIST_HEAD(to_be_aged); | ||
| 734 | |||
| 735 | dprintk("svc_age_temp_xprts\n"); | ||
| 736 | |||
| 737 | if (!spin_trylock_bh(&serv->sv_lock)) { | ||
| 738 | /* busy, try again 1 sec later */ | ||
| 739 | dprintk("svc_age_temp_xprts: busy\n"); | ||
| 740 | mod_timer(&serv->sv_temptimer, jiffies + HZ); | ||
| 741 | return; | ||
| 742 | } | ||
| 743 | |||
| 744 | list_for_each_safe(le, next, &serv->sv_tempsocks) { | ||
| 745 | xprt = list_entry(le, struct svc_xprt, xpt_list); | ||
| 746 | |||
| 747 | /* First time through, just mark it OLD. Second time | ||
| 748 | * through, close it. */ | ||
| 749 | if (!test_and_set_bit(XPT_OLD, &xprt->xpt_flags)) | ||
| 750 | continue; | ||
| 751 | if (atomic_read(&xprt->xpt_ref.refcount) > 1 | ||
| 752 | || test_bit(XPT_BUSY, &xprt->xpt_flags)) | ||
| 753 | continue; | ||
| 754 | svc_xprt_get(xprt); | ||
| 755 | list_move(le, &to_be_aged); | ||
| 756 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
| 757 | set_bit(XPT_DETACHED, &xprt->xpt_flags); | ||
| 758 | } | ||
| 759 | spin_unlock_bh(&serv->sv_lock); | ||
| 760 | |||
| 761 | while (!list_empty(&to_be_aged)) { | ||
| 762 | le = to_be_aged.next; | ||
| 763 | /* fiddling the xpt_list node is safe 'cos we're XPT_DETACHED */ | ||
| 764 | list_del_init(le); | ||
| 765 | xprt = list_entry(le, struct svc_xprt, xpt_list); | ||
| 766 | |||
| 767 | dprintk("queuing xprt %p for closing\n", xprt); | ||
| 768 | |||
| 769 | /* a thread will dequeue and close it soon */ | ||
| 770 | svc_xprt_enqueue(xprt); | ||
| 771 | svc_xprt_put(xprt); | ||
| 772 | } | ||
| 773 | |||
| 774 | mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); | ||
| 775 | } | ||
| 776 | |||
| 777 | /* | ||
| 778 | * Remove a dead transport | ||
| 779 | */ | ||
| 780 | void svc_delete_xprt(struct svc_xprt *xprt) | ||
| 781 | { | ||
| 782 | struct svc_serv *serv = xprt->xpt_server; | ||
| 783 | |||
| 784 | dprintk("svc: svc_delete_xprt(%p)\n", xprt); | ||
| 785 | xprt->xpt_ops->xpo_detach(xprt); | ||
| 786 | |||
| 787 | spin_lock_bh(&serv->sv_lock); | ||
| 788 | if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags)) | ||
| 789 | list_del_init(&xprt->xpt_list); | ||
| 790 | /* | ||
| 791 | * We used to delete the transport from whichever list | ||
| 792 | * it's sk_xprt.xpt_ready node was on, but we don't actually | ||
| 793 | * need to. This is because the only time we're called | ||
| 794 | * while still attached to a queue, the queue itself | ||
| 795 | * is about to be destroyed (in svc_destroy). | ||
| 796 | */ | ||
| 797 | if (!test_and_set_bit(XPT_DEAD, &xprt->xpt_flags)) { | ||
| 798 | BUG_ON(atomic_read(&xprt->xpt_ref.refcount) < 2); | ||
| 799 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) | ||
| 800 | serv->sv_tmpcnt--; | ||
| 801 | svc_xprt_put(xprt); | ||
| 802 | } | ||
| 803 | spin_unlock_bh(&serv->sv_lock); | ||
| 804 | } | ||
| 805 | |||
| 806 | void svc_close_xprt(struct svc_xprt *xprt) | ||
| 807 | { | ||
| 808 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
| 809 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) | ||
| 810 | /* someone else will have to effect the close */ | ||
| 811 | return; | ||
| 812 | |||
| 813 | svc_xprt_get(xprt); | ||
| 814 | svc_delete_xprt(xprt); | ||
| 815 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
| 816 | svc_xprt_put(xprt); | ||
| 817 | } | ||
| 818 | |||
| 819 | void svc_close_all(struct list_head *xprt_list) | ||
| 820 | { | ||
| 821 | struct svc_xprt *xprt; | ||
| 822 | struct svc_xprt *tmp; | ||
| 823 | |||
| 824 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { | ||
| 825 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
| 826 | if (test_bit(XPT_BUSY, &xprt->xpt_flags)) { | ||
| 827 | /* Waiting to be processed, but no threads left, | ||
| 828 | * So just remove it from the waiting list | ||
| 829 | */ | ||
| 830 | list_del_init(&xprt->xpt_ready); | ||
| 831 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
| 832 | } | ||
| 833 | svc_close_xprt(xprt); | ||
| 834 | } | ||
| 835 | } | ||
| 836 | |||
| 837 | /* | ||
| 838 | * Handle defer and revisit of requests | ||
| 839 | */ | ||
| 840 | |||
| 841 | static void svc_revisit(struct cache_deferred_req *dreq, int too_many) | ||
| 842 | { | ||
| 843 | struct svc_deferred_req *dr = | ||
| 844 | container_of(dreq, struct svc_deferred_req, handle); | ||
| 845 | struct svc_xprt *xprt = dr->xprt; | ||
| 846 | |||
| 847 | if (too_many) { | ||
| 848 | svc_xprt_put(xprt); | ||
| 849 | kfree(dr); | ||
| 850 | return; | ||
| 851 | } | ||
| 852 | dprintk("revisit queued\n"); | ||
| 853 | dr->xprt = NULL; | ||
| 854 | spin_lock(&xprt->xpt_lock); | ||
| 855 | list_add(&dr->handle.recent, &xprt->xpt_deferred); | ||
| 856 | spin_unlock(&xprt->xpt_lock); | ||
| 857 | set_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
| 858 | svc_xprt_enqueue(xprt); | ||
| 859 | svc_xprt_put(xprt); | ||
| 860 | } | ||
| 861 | |||
| 862 | static struct cache_deferred_req *svc_defer(struct cache_req *req) | ||
| 863 | { | ||
| 864 | struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle); | ||
| 865 | int size = sizeof(struct svc_deferred_req) + (rqstp->rq_arg.len); | ||
| 866 | struct svc_deferred_req *dr; | ||
| 867 | |||
| 868 | if (rqstp->rq_arg.page_len) | ||
| 869 | return NULL; /* if more than a page, give up FIXME */ | ||
| 870 | if (rqstp->rq_deferred) { | ||
| 871 | dr = rqstp->rq_deferred; | ||
| 872 | rqstp->rq_deferred = NULL; | ||
| 873 | } else { | ||
| 874 | int skip = rqstp->rq_arg.len - rqstp->rq_arg.head[0].iov_len; | ||
| 875 | /* FIXME maybe discard if size too large */ | ||
| 876 | dr = kmalloc(size, GFP_KERNEL); | ||
| 877 | if (dr == NULL) | ||
| 878 | return NULL; | ||
| 879 | |||
| 880 | dr->handle.owner = rqstp->rq_server; | ||
| 881 | dr->prot = rqstp->rq_prot; | ||
| 882 | memcpy(&dr->addr, &rqstp->rq_addr, rqstp->rq_addrlen); | ||
| 883 | dr->addrlen = rqstp->rq_addrlen; | ||
| 884 | dr->daddr = rqstp->rq_daddr; | ||
| 885 | dr->argslen = rqstp->rq_arg.len >> 2; | ||
| 886 | memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, | ||
| 887 | dr->argslen<<2); | ||
| 888 | } | ||
| 889 | svc_xprt_get(rqstp->rq_xprt); | ||
| 890 | dr->xprt = rqstp->rq_xprt; | ||
| 891 | |||
| 892 | dr->handle.revisit = svc_revisit; | ||
| 893 | return &dr->handle; | ||
| 894 | } | ||
| 895 | |||
| 896 | /* | ||
| 897 | * recv data from a deferred request into an active one | ||
| 898 | */ | ||
| 899 | static int svc_deferred_recv(struct svc_rqst *rqstp) | ||
| 900 | { | ||
| 901 | struct svc_deferred_req *dr = rqstp->rq_deferred; | ||
| 902 | |||
| 903 | rqstp->rq_arg.head[0].iov_base = dr->args; | ||
| 904 | rqstp->rq_arg.head[0].iov_len = dr->argslen<<2; | ||
| 905 | rqstp->rq_arg.page_len = 0; | ||
| 906 | rqstp->rq_arg.len = dr->argslen<<2; | ||
| 907 | rqstp->rq_prot = dr->prot; | ||
| 908 | memcpy(&rqstp->rq_addr, &dr->addr, dr->addrlen); | ||
| 909 | rqstp->rq_addrlen = dr->addrlen; | ||
| 910 | rqstp->rq_daddr = dr->daddr; | ||
| 911 | rqstp->rq_respages = rqstp->rq_pages; | ||
| 912 | return dr->argslen<<2; | ||
| 913 | } | ||
| 914 | |||
| 915 | |||
| 916 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) | ||
| 917 | { | ||
| 918 | struct svc_deferred_req *dr = NULL; | ||
| 919 | |||
| 920 | if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags)) | ||
| 921 | return NULL; | ||
| 922 | spin_lock(&xprt->xpt_lock); | ||
| 923 | clear_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
| 924 | if (!list_empty(&xprt->xpt_deferred)) { | ||
| 925 | dr = list_entry(xprt->xpt_deferred.next, | ||
| 926 | struct svc_deferred_req, | ||
| 927 | handle.recent); | ||
| 928 | list_del_init(&dr->handle.recent); | ||
| 929 | set_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
| 930 | } | ||
| 931 | spin_unlock(&xprt->xpt_lock); | ||
| 932 | return dr; | ||
| 933 | } | ||
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 | } | ||
