]> Git Repo - linux.git/blobdiff - net/sunrpc/svc_xprt.c
Merge tag 'nfsd-6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
[linux.git] / net / sunrpc / svc_xprt.c
index aebc0d8ddff5c7083c23f862340dd9b565bed22b..ae25405d8bd22672a361d1fd3adfdcebb403f90f 100644 (file)
@@ -606,7 +606,8 @@ int svc_port_is_privileged(struct sockaddr *sin)
 }
 
 /*
- * Make sure that we don't have too many active connections. If we have,
+ * Make sure that we don't have too many connections that have not yet
+ * demonstrated that they have access to the NFS server. 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.
@@ -618,34 +619,26 @@ int svc_port_is_privileged(struct sockaddr *sin)
  * 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)
 {
-       unsigned int limit = serv->sv_maxconn ? serv->sv_maxconn :
-                               (serv->sv_nrthreads+3) * 20;
-
-       if (serv->sv_tmpcnt > limit) {
-               struct svc_xprt *xprt = NULL;
+       if (serv->sv_tmpcnt > XPT_MAX_TMP_CONN) {
+               struct svc_xprt *xprt = NULL, *xprti;
                spin_lock_bh(&serv->sv_lock);
                if (!list_empty(&serv->sv_tempsocks)) {
-                       /* Try to help the admin */
-                       net_notice_ratelimited("%s: too many open connections, consider increasing the %s\n",
-                                              serv->sv_name, serv->sv_maxconn ?
-                                              "max number of connections" :
-                                              "number of threads");
                        /*
                         * Always select the oldest connection. It's not fair,
-                        * but so is life
+                        * but nor is life.
                         */
-                       xprt = list_entry(serv->sv_tempsocks.prev,
-                                         struct svc_xprt,
-                                         xpt_list);
-                       set_bit(XPT_CLOSE, &xprt->xpt_flags);
-                       svc_xprt_get(xprt);
+                       list_for_each_entry_reverse(xprti, &serv->sv_tempsocks,
+                                                   xpt_list) {
+                               if (!test_bit(XPT_PEER_VALID, &xprti->xpt_flags)) {
+                                       xprt = xprti;
+                                       set_bit(XPT_CLOSE, &xprt->xpt_flags);
+                                       svc_xprt_get(xprt);
+                                       break;
+                               }
+                       }
                }
                spin_unlock_bh(&serv->sv_lock);
 
@@ -1038,7 +1031,8 @@ static void svc_delete_xprt(struct svc_xprt *xprt)
 
        spin_lock_bh(&serv->sv_lock);
        list_del_init(&xprt->xpt_list);
-       if (test_bit(XPT_TEMP, &xprt->xpt_flags))
+       if (test_bit(XPT_TEMP, &xprt->xpt_flags) &&
+           !test_bit(XPT_PEER_VALID, &xprt->xpt_flags))
                serv->sv_tmpcnt--;
        spin_unlock_bh(&serv->sv_lock);
 
This page took 0.031158 seconds and 4 git commands to generate.