diff options
author | Greg Banks <gnb@melbourne.sgi.com> | 2006-10-02 05:18:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 10:57:20 -0400 |
commit | eed2965af1bae30f746e936d80ad4fabb9e208c8 (patch) | |
tree | bcb8d2f435f612f6b0d3cc6eac8b39e8dd22f45b /fs/nfsd/nfssvc.c | |
parent | bfd241600a3b0db4fe43c859f1460d0a958d924a (diff) |
[PATCH] knfsd: allow admin to set nthreads per node
Add /proc/fs/nfsd/pool_threads which allows the sysadmin (or a userspace
daemon) to read and change the number of nfsd threads in each pool. The
format is a list of space-separated integers, one per pool.
Signed-off-by: Greg Banks <gnb@melbourne.sgi.com>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd/nfssvc.c')
-rw-r--r-- | fs/nfsd/nfssvc.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 0029cb290f18..19443056ec30 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -238,6 +238,80 @@ static int nfsd_init_socks(int port) | |||
238 | return 0; | 238 | return 0; |
239 | } | 239 | } |
240 | 240 | ||
241 | int nfsd_nrpools(void) | ||
242 | { | ||
243 | if (nfsd_serv == NULL) | ||
244 | return 0; | ||
245 | else | ||
246 | return nfsd_serv->sv_nrpools; | ||
247 | } | ||
248 | |||
249 | int nfsd_get_nrthreads(int n, int *nthreads) | ||
250 | { | ||
251 | int i = 0; | ||
252 | |||
253 | if (nfsd_serv != NULL) { | ||
254 | for (i = 0; i < nfsd_serv->sv_nrpools && i < n; i++) | ||
255 | nthreads[i] = nfsd_serv->sv_pools[i].sp_nrthreads; | ||
256 | } | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | int nfsd_set_nrthreads(int n, int *nthreads) | ||
262 | { | ||
263 | int i = 0; | ||
264 | int tot = 0; | ||
265 | int err = 0; | ||
266 | |||
267 | if (nfsd_serv == NULL || n <= 0) | ||
268 | return 0; | ||
269 | |||
270 | if (n > nfsd_serv->sv_nrpools) | ||
271 | n = nfsd_serv->sv_nrpools; | ||
272 | |||
273 | /* enforce a global maximum number of threads */ | ||
274 | tot = 0; | ||
275 | for (i = 0; i < n; i++) { | ||
276 | if (nthreads[i] > NFSD_MAXSERVS) | ||
277 | nthreads[i] = NFSD_MAXSERVS; | ||
278 | tot += nthreads[i]; | ||
279 | } | ||
280 | if (tot > NFSD_MAXSERVS) { | ||
281 | /* total too large: scale down requested numbers */ | ||
282 | for (i = 0; i < n && tot > 0; i++) { | ||
283 | int new = nthreads[i] * NFSD_MAXSERVS / tot; | ||
284 | tot -= (nthreads[i] - new); | ||
285 | nthreads[i] = new; | ||
286 | } | ||
287 | for (i = 0; i < n && tot > 0; i++) { | ||
288 | nthreads[i]--; | ||
289 | tot--; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * There must always be a thread in pool 0; the admin | ||
295 | * can't shut down NFS completely using pool_threads. | ||
296 | */ | ||
297 | if (nthreads[0] == 0) | ||
298 | nthreads[0] = 1; | ||
299 | |||
300 | /* apply the new numbers */ | ||
301 | lock_kernel(); | ||
302 | svc_get(nfsd_serv); | ||
303 | for (i = 0; i < n; i++) { | ||
304 | err = svc_set_num_threads(nfsd_serv, &nfsd_serv->sv_pools[i], | ||
305 | nthreads[i]); | ||
306 | if (err) | ||
307 | break; | ||
308 | } | ||
309 | svc_destroy(nfsd_serv); | ||
310 | unlock_kernel(); | ||
311 | |||
312 | return err; | ||
313 | } | ||
314 | |||
241 | int | 315 | int |
242 | nfsd_svc(unsigned short port, int nrservs) | 316 | nfsd_svc(unsigned short port, int nrservs) |
243 | { | 317 | { |