]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
nfsd: allow passing in array of thread counts via netlink
authorJeff Layton <jlayton@kernel.org>
Thu, 13 Jun 2024 18:34:32 +0000 (14:34 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 8 Jul 2024 18:10:05 +0000 (14:10 -0400)
Now that nfsd_svc can handle an array of thread counts, fix up the
netlink threads interface to construct one from the netlink call
and pass it through so we can start a pooled server the same way we
would start a normal one.

Note that any unspecified values in the array are considered zeroes,
so it's possible to shut down a pooled server by passing in a short
array that has only zeros, or even an empty array.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfsctl.c
fs/nfsd/nfssvc.c

index 71015d0e3df25c15bb8c18c2e4fbc63d3f8d64d1..3da7e4b3e2c3e794fbbad0f898f0762273ef3e26 100644 (file)
@@ -1645,7 +1645,7 @@ out_unlock:
  */
 int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)
 {
-       int nthreads = 0, count = 0, nrpools, ret = -EOPNOTSUPP, rem;
+       int *nthreads, count = 0, nrpools, i, ret = -EOPNOTSUPP, rem;
        struct net *net = genl_info_net(info);
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
        const struct nlattr *attr;
@@ -1662,15 +1662,22 @@ int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)
 
        mutex_lock(&nfsd_mutex);
 
-       nrpools = nfsd_nrpools(net);
-       if (nrpools && count > nrpools)
-               count = nrpools;
-
-       /* XXX: make this handle non-global pool-modes */
-       if (count > 1)
+       nrpools = max(count, nfsd_nrpools(net));
+       nthreads = kcalloc(nrpools, sizeof(int), GFP_KERNEL);
+       if (!nthreads) {
+               ret = -ENOMEM;
                goto out_unlock;
+       }
+
+       i = 0;
+       nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) {
+               if (nla_type(attr) == NFSD_A_SERVER_THREADS) {
+                       nthreads[i++] = nla_get_u32(attr);
+                       if (i >= nrpools)
+                               break;
+               }
+       }
 
-       nthreads = nla_get_u32(info->attrs[NFSD_A_SERVER_THREADS]);
        if (info->attrs[NFSD_A_SERVER_GRACETIME] ||
            info->attrs[NFSD_A_SERVER_LEASETIME] ||
            info->attrs[NFSD_A_SERVER_SCOPE]) {
@@ -1704,12 +1711,13 @@ int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)
                        scope = nla_data(attr);
        }
 
-       ret = nfsd_svc(1, &nthreads, net, get_current_cred(), scope);
-
+       ret = nfsd_svc(nrpools, nthreads, net, get_current_cred(), scope);
+       if (ret > 0)
+               ret = 0;
 out_unlock:
        mutex_unlock(&nfsd_mutex);
-
-       return ret == nthreads ? 0 : ret;
+       kfree(nthreads);
+       return ret;
 }
 
 /**
index 9aa23762394bee2dfc8bce40c1f90e444dc53147..0bc8eaa5e0098eeb69133ee44e0577bd61c9e1ad 100644 (file)
@@ -769,8 +769,18 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
                                          &nn->nfsd_serv->sv_pools[i],
                                          nthreads[i]);
                if (err)
-                       break;
+                       goto out;
        }
+
+       /* Anything undefined in array is considered to be 0 */
+       for (i = n; i < nn->nfsd_serv->sv_nrpools; ++i) {
+               err = svc_set_num_threads(nn->nfsd_serv,
+                                         &nn->nfsd_serv->sv_pools[i],
+                                         0);
+               if (err)
+                       goto out;
+       }
+out:
        return err;
 }