struct svc_stat *       sv_stats;       /* RPC statistics */
        spinlock_t              sv_lock;
        unsigned int            sv_nrthreads;   /* # of server threads */
+       unsigned int            sv_maxconn;     /* max connections allowed or
+                                                * '0' causing max to be based
+                                                * on number of threads. */
+
        unsigned int            sv_max_payload; /* datagram payload size */
        unsigned int            sv_max_mesg;    /* max_payload + 1 page for overheads */
        unsigned int            sv_xdrsize;     /* XDR buffer size */
-
        struct list_head        sv_permsocks;   /* all permanent sockets */
        struct list_head        sv_tempsocks;   /* all temporary sockets */
        int                     sv_tmpcnt;      /* count of temporary sockets */
 
 }
 
 /*
- * Make sure that we don't have too many active connections.  If we
- * have, something must be dropped.
+ * Make sure that we don't have too many active connections. If we have,
+ * something must be dropped. It's not clear what will happen if we allow
+ * "too many" connections, but when dealing with network-facing software,
+ * we have to code defensively. Here we do that by imposing hard limits.
  *
  * There's no point in trying to do random drop here for DoS
  * prevention. The NFS clients does 1 reconnect in 15 seconds. An
  * The only somewhat efficient mechanism would be if drop old
  * connections from the same IP first. But right now we don't even
  * record the client IP in svc_sock.
+ *
+ * single-threaded services that expect a lot of clients will probably
+ * need to set sv_maxconn to override the default value which is based
+ * on the number of threads
  */
 static void svc_check_conn_limits(struct svc_serv *serv)
 {
-       if (serv->sv_tmpcnt > (serv->sv_nrthreads+3)*20) {
+       unsigned int limit = serv->sv_maxconn ? serv->sv_maxconn :
+                               (serv->sv_nrthreads+3) * 20;
+
+       if (serv->sv_tmpcnt > limit) {
                struct svc_xprt *xprt = NULL;
                spin_lock_bh(&serv->sv_lock);
                if (!list_empty(&serv->sv_tempsocks)) {
                        if (net_ratelimit()) {
                                /* Try to help the admin */
                                printk(KERN_NOTICE "%s: too many open  "
-                                      "connections, consider increasing the "
-                                      "number of nfsd threads\n",
-                                      serv->sv_name);
+                                      "connections, consider increasing %s\n",
+                                      serv->sv_name, serv->sv_maxconn ?
+                                      "the max number of connections." :
+                                      "the number of threads.");
                        }
                        /*
                         * Always select the oldest connection. It's not fair,