@@ -709,18 +709,38 @@ int nfsd_get_nrthreads(int n, int *nthreads, struct net *net)
709709 return 0 ;
710710}
711711
712+ /**
713+ * nfsd_set_nrthreads - set the number of running threads in the net's service
714+ * @n: number of array members in @nthreads
715+ * @nthreads: array of thread counts for each pool
716+ * @net: network namespace to operate within
717+ *
718+ * This function alters the number of running threads for the given network
719+ * namespace in each pool. If passed an array longer then the number of pools
720+ * the extra pool settings are ignored. If passed an array shorter than the
721+ * number of pools, the missing values are interpreted as 0's.
722+ *
723+ * Returns 0 on success or a negative errno on error.
724+ */
712725int nfsd_set_nrthreads (int n , int * nthreads , struct net * net )
713726{
714727 int i = 0 ;
715728 int tot = 0 ;
716729 int err = 0 ;
717730 struct nfsd_net * nn = net_generic (net , nfsd_net_id );
718731
719- WARN_ON (! mutex_is_locked ( & nfsd_mutex ) );
732+ lockdep_assert_held ( & nfsd_mutex );
720733
721734 if (nn -> nfsd_serv == NULL || n <= 0 )
722735 return 0 ;
723736
737+ /*
738+ * Special case: When n == 1, pass in NULL for the pool, so that the
739+ * change is distributed equally among them.
740+ */
741+ if (n == 1 )
742+ return svc_set_num_threads (nn -> nfsd_serv , NULL , nthreads [0 ]);
743+
724744 if (n > nn -> nfsd_serv -> sv_nrpools )
725745 n = nn -> nfsd_serv -> sv_nrpools ;
726746
@@ -743,13 +763,6 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
743763 }
744764 }
745765
746- /*
747- * There must always be a thread in pool 0; the admin
748- * can't shut down NFS completely using pool_threads.
749- */
750- if (nthreads [0 ] == 0 )
751- nthreads [0 ] = 1 ;
752-
753766 /* apply the new numbers */
754767 for (i = 0 ; i < n ; i ++ ) {
755768 err = svc_set_num_threads (nn -> nfsd_serv ,
@@ -761,13 +774,19 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
761774 return err ;
762775}
763776
764- /*
765- * Adjust the number of threads and return the new number of threads.
766- * This is also the function that starts the server if necessary, if
767- * this is the first time nrservs is nonzero.
777+ /**
778+ * nfsd_svc: start up or shut down the nfsd server
779+ * @n: number of array members in @nthreads
780+ * @nthreads: array of thread counts for each pool
781+ * @net: network namespace to operate within
782+ * @cred: credentials to use for xprt creation
783+ * @scope: server scope value (defaults to nodename)
784+ *
785+ * Adjust the number of threads in each pool and return the new
786+ * total number of threads in the service.
768787 */
769788int
770- nfsd_svc (int nrservs , struct net * net , const struct cred * cred , const char * scope )
789+ nfsd_svc (int n , int * nthreads , struct net * net , const struct cred * cred , const char * scope )
771790{
772791 int error ;
773792 struct nfsd_net * nn = net_generic (net , nfsd_net_id );
@@ -777,13 +796,6 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred, const char *scop
777796
778797 dprintk ("nfsd: creating service\n" );
779798
780- nrservs = max (nrservs , 0 );
781- nrservs = min (nrservs , NFSD_MAXSERVS );
782- error = 0 ;
783-
784- if (nrservs == 0 && nn -> nfsd_serv == NULL )
785- goto out ;
786-
787799 strscpy (nn -> nfsd_name , scope ? scope : utsname ()-> nodename ,
788800 sizeof (nn -> nfsd_name ));
789801
@@ -795,7 +807,7 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred, const char *scop
795807 error = nfsd_startup_net (net , cred );
796808 if (error )
797809 goto out_put ;
798- error = svc_set_num_threads ( serv , NULL , nrservs );
810+ error = nfsd_set_nrthreads ( n , nthreads , net );
799811 if (error )
800812 goto out_put ;
801813 error = serv -> sv_nrthreads ;
0 commit comments