diff options
-rw-r--r-- | include/linux/sunrpc/svc.h | 5 | ||||
-rw-r--r-- | net/sunrpc/svc_xprt.c | 22 |
2 files changed, 20 insertions, 7 deletions
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 3afe7fb403b2..3435d24bfe55 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
@@ -58,10 +58,13 @@ struct svc_serv { | |||
58 | struct svc_stat * sv_stats; /* RPC statistics */ | 58 | struct svc_stat * sv_stats; /* RPC statistics */ |
59 | spinlock_t sv_lock; | 59 | spinlock_t sv_lock; |
60 | unsigned int sv_nrthreads; /* # of server threads */ | 60 | unsigned int sv_nrthreads; /* # of server threads */ |
61 | unsigned int sv_maxconn; /* max connections allowed or | ||
62 | * '0' causing max to be based | ||
63 | * on number of threads. */ | ||
64 | |||
61 | unsigned int sv_max_payload; /* datagram payload size */ | 65 | unsigned int sv_max_payload; /* datagram payload size */ |
62 | unsigned int sv_max_mesg; /* max_payload + 1 page for overheads */ | 66 | unsigned int sv_max_mesg; /* max_payload + 1 page for overheads */ |
63 | unsigned int sv_xdrsize; /* XDR buffer size */ | 67 | unsigned int sv_xdrsize; /* XDR buffer size */ |
64 | |||
65 | struct list_head sv_permsocks; /* all permanent sockets */ | 68 | struct list_head sv_permsocks; /* all permanent sockets */ |
66 | struct list_head sv_tempsocks; /* all temporary sockets */ | 69 | struct list_head sv_tempsocks; /* all temporary sockets */ |
67 | int sv_tmpcnt; /* count of temporary sockets */ | 70 | int sv_tmpcnt; /* count of temporary sockets */ |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index bf5b5cdafebf..3fe4f1004278 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -515,8 +515,10 @@ int svc_port_is_privileged(struct sockaddr *sin) | |||
515 | } | 515 | } |
516 | 516 | ||
517 | /* | 517 | /* |
518 | * Make sure that we don't have too many active connections. If we | 518 | * Make sure that we don't have too many active connections. If we have, |
519 | * have, something must be dropped. | 519 | * something must be dropped. It's not clear what will happen if we allow |
520 | * "too many" connections, but when dealing with network-facing software, | ||
521 | * we have to code defensively. Here we do that by imposing hard limits. | ||
520 | * | 522 | * |
521 | * There's no point in trying to do random drop here for DoS | 523 | * There's no point in trying to do random drop here for DoS |
522 | * prevention. The NFS clients does 1 reconnect in 15 seconds. An | 524 | * prevention. The NFS clients does 1 reconnect in 15 seconds. An |
@@ -525,19 +527,27 @@ int svc_port_is_privileged(struct sockaddr *sin) | |||
525 | * The only somewhat efficient mechanism would be if drop old | 527 | * The only somewhat efficient mechanism would be if drop old |
526 | * connections from the same IP first. But right now we don't even | 528 | * connections from the same IP first. But right now we don't even |
527 | * record the client IP in svc_sock. | 529 | * record the client IP in svc_sock. |
530 | * | ||
531 | * single-threaded services that expect a lot of clients will probably | ||
532 | * need to set sv_maxconn to override the default value which is based | ||
533 | * on the number of threads | ||
528 | */ | 534 | */ |
529 | static void svc_check_conn_limits(struct svc_serv *serv) | 535 | static void svc_check_conn_limits(struct svc_serv *serv) |
530 | { | 536 | { |
531 | if (serv->sv_tmpcnt > (serv->sv_nrthreads+3)*20) { | 537 | unsigned int limit = serv->sv_maxconn ? serv->sv_maxconn : |
538 | (serv->sv_nrthreads+3) * 20; | ||
539 | |||
540 | if (serv->sv_tmpcnt > limit) { | ||
532 | struct svc_xprt *xprt = NULL; | 541 | struct svc_xprt *xprt = NULL; |
533 | spin_lock_bh(&serv->sv_lock); | 542 | spin_lock_bh(&serv->sv_lock); |
534 | if (!list_empty(&serv->sv_tempsocks)) { | 543 | if (!list_empty(&serv->sv_tempsocks)) { |
535 | if (net_ratelimit()) { | 544 | if (net_ratelimit()) { |
536 | /* Try to help the admin */ | 545 | /* Try to help the admin */ |
537 | printk(KERN_NOTICE "%s: too many open " | 546 | printk(KERN_NOTICE "%s: too many open " |
538 | "connections, consider increasing the " | 547 | "connections, consider increasing %s\n", |
539 | "number of nfsd threads\n", | 548 | serv->sv_name, serv->sv_maxconn ? |
540 | serv->sv_name); | 549 | "the max number of connections." : |
550 | "the number of threads."); | ||
541 | } | 551 | } |
542 | /* | 552 | /* |
543 | * Always select the oldest connection. It's not fair, | 553 | * Always select the oldest connection. It's not fair, |