nfsd: fix race in nfsd_nrthreads()
[safe/jmp/linux-2.6] / fs / nfsd / nfssvc.c
1 /*
2  * linux/fs/nfsd/nfssvc.c
3  *
4  * Central processing for nfsd.
5  *
6  * Authors:     Olaf Kirch (okir@monad.swb.de)
7  *
8  * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
9  */
10
11 #include <linux/module.h>
12 #include <linux/sched.h>
13 #include <linux/time.h>
14 #include <linux/errno.h>
15 #include <linux/nfs.h>
16 #include <linux/in.h>
17 #include <linux/uio.h>
18 #include <linux/unistd.h>
19 #include <linux/slab.h>
20 #include <linux/smp.h>
21 #include <linux/smp_lock.h>
22 #include <linux/freezer.h>
23 #include <linux/fs_struct.h>
24 #include <linux/kthread.h>
25
26 #include <linux/sunrpc/types.h>
27 #include <linux/sunrpc/stats.h>
28 #include <linux/sunrpc/svc.h>
29 #include <linux/sunrpc/svcsock.h>
30 #include <linux/sunrpc/cache.h>
31 #include <linux/nfsd/nfsd.h>
32 #include <linux/nfsd/stats.h>
33 #include <linux/nfsd/cache.h>
34 #include <linux/nfsd/syscall.h>
35 #include <linux/lockd/bind.h>
36 #include <linux/nfsacl.h>
37
38 #define NFSDDBG_FACILITY        NFSDDBG_SVC
39
40 /* these signals will be delivered to an nfsd thread 
41  * when handling a request
42  */
43 #define ALLOWED_SIGS    (sigmask(SIGKILL))
44 /* these signals will be delivered to an nfsd thread
45  * when not handling a request. i.e. when waiting
46  */
47 #define SHUTDOWN_SIGS   (sigmask(SIGKILL) | sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGQUIT))
48
49 extern struct svc_program       nfsd_program;
50 static int                      nfsd(void *vrqstp);
51 struct timeval                  nfssvc_boot;
52 static atomic_t                 nfsd_busy;
53 static unsigned long            nfsd_last_call;
54 static DEFINE_SPINLOCK(nfsd_call_lock);
55
56 /*
57  * nfsd_mutex protects nfsd_serv -- both the pointer itself and the members
58  * of the svc_serv struct. In particular, ->sv_nrthreads but also to some
59  * extent ->sv_temp_socks and ->sv_permsocks. It also protects nfsdstats.th_cnt
60  *
61  * If (out side the lock) nfsd_serv is non-NULL, then it must point to a
62  * properly initialised 'struct svc_serv' with ->sv_nrthreads > 0. That number
63  * of nfsd threads must exist and each must listed in ->sp_all_threads in each
64  * entry of ->sv_pools[].
65  *
66  * Transitions of the thread count between zero and non-zero are of particular
67  * interest since the svc_serv needs to be created and initialized at that
68  * point, or freed.
69  *
70  * Finally, the nfsd_mutex also protects some of the global variables that are
71  * accessed when nfsd starts and that are settable via the write_* routines in
72  * nfsctl.c. In particular:
73  *
74  *      user_recovery_dirname
75  *      user_lease_time
76  *      nfsd_versions
77  */
78 DEFINE_MUTEX(nfsd_mutex);
79 struct svc_serv                 *nfsd_serv;
80
81 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
82 static struct svc_stat  nfsd_acl_svcstats;
83 static struct svc_version *     nfsd_acl_version[] = {
84         [2] = &nfsd_acl_version2,
85         [3] = &nfsd_acl_version3,
86 };
87
88 #define NFSD_ACL_MINVERS            2
89 #define NFSD_ACL_NRVERS         ARRAY_SIZE(nfsd_acl_version)
90 static struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS];
91
92 static struct svc_program       nfsd_acl_program = {
93         .pg_prog                = NFS_ACL_PROGRAM,
94         .pg_nvers               = NFSD_ACL_NRVERS,
95         .pg_vers                = nfsd_acl_versions,
96         .pg_name                = "nfsacl",
97         .pg_class               = "nfsd",
98         .pg_stats               = &nfsd_acl_svcstats,
99         .pg_authenticate        = &svc_set_client,
100 };
101
102 static struct svc_stat  nfsd_acl_svcstats = {
103         .program        = &nfsd_acl_program,
104 };
105 #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
106
107 static struct svc_version *     nfsd_version[] = {
108         [2] = &nfsd_version2,
109 #if defined(CONFIG_NFSD_V3)
110         [3] = &nfsd_version3,
111 #endif
112 #if defined(CONFIG_NFSD_V4)
113         [4] = &nfsd_version4,
114 #endif
115 };
116
117 #define NFSD_MINVERS            2
118 #define NFSD_NRVERS             ARRAY_SIZE(nfsd_version)
119 static struct svc_version *nfsd_versions[NFSD_NRVERS];
120
121 struct svc_program              nfsd_program = {
122 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
123         .pg_next                = &nfsd_acl_program,
124 #endif
125         .pg_prog                = NFS_PROGRAM,          /* program number */
126         .pg_nvers               = NFSD_NRVERS,          /* nr of entries in nfsd_version */
127         .pg_vers                = nfsd_versions,        /* version table */
128         .pg_name                = "nfsd",               /* program name */
129         .pg_class               = "nfsd",               /* authentication class */
130         .pg_stats               = &nfsd_svcstats,       /* version table */
131         .pg_authenticate        = &svc_set_client,      /* export authentication */
132
133 };
134
135 int nfsd_vers(int vers, enum vers_op change)
136 {
137         if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
138                 return -1;
139         switch(change) {
140         case NFSD_SET:
141                 nfsd_versions[vers] = nfsd_version[vers];
142 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
143                 if (vers < NFSD_ACL_NRVERS)
144                         nfsd_acl_versions[vers] = nfsd_acl_version[vers];
145 #endif
146                 break;
147         case NFSD_CLEAR:
148                 nfsd_versions[vers] = NULL;
149 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
150                 if (vers < NFSD_ACL_NRVERS)
151                         nfsd_acl_versions[vers] = NULL;
152 #endif
153                 break;
154         case NFSD_TEST:
155                 return nfsd_versions[vers] != NULL;
156         case NFSD_AVAIL:
157                 return nfsd_version[vers] != NULL;
158         }
159         return 0;
160 }
161 /*
162  * Maximum number of nfsd processes
163  */
164 #define NFSD_MAXSERVS           8192
165
166 int nfsd_nrthreads(void)
167 {
168         int rv = 0;
169         mutex_lock(&nfsd_mutex);
170         if (nfsd_serv)
171                 rv = nfsd_serv->sv_nrthreads;
172         mutex_unlock(&nfsd_mutex);
173         return rv;
174 }
175
176 static void nfsd_last_thread(struct svc_serv *serv)
177 {
178         /* When last nfsd thread exits we need to do some clean-up */
179         struct svc_xprt *xprt;
180         list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list)
181                 lockd_down();
182         nfsd_serv = NULL;
183         nfsd_racache_shutdown();
184         nfs4_state_shutdown();
185
186         printk(KERN_WARNING "nfsd: last server has exited, flushing export "
187                             "cache\n");
188         nfsd_export_flush();
189 }
190
191 void nfsd_reset_versions(void)
192 {
193         int found_one = 0;
194         int i;
195
196         for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
197                 if (nfsd_program.pg_vers[i])
198                         found_one = 1;
199         }
200
201         if (!found_one) {
202                 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
203                         nfsd_program.pg_vers[i] = nfsd_version[i];
204 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
205                 for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
206                         nfsd_acl_program.pg_vers[i] =
207                                 nfsd_acl_version[i];
208 #endif
209         }
210 }
211
212
213 int nfsd_create_serv(void)
214 {
215         int err = 0;
216
217         WARN_ON(!mutex_is_locked(&nfsd_mutex));
218         if (nfsd_serv) {
219                 svc_get(nfsd_serv);
220                 return 0;
221         }
222         if (nfsd_max_blksize == 0) {
223                 /* choose a suitable default */
224                 struct sysinfo i;
225                 si_meminfo(&i);
226                 /* Aim for 1/4096 of memory per thread
227                  * This gives 1MB on 4Gig machines
228                  * But only uses 32K on 128M machines.
229                  * Bottom out at 8K on 32M and smaller.
230                  * Of course, this is only a default.
231                  */
232                 nfsd_max_blksize = NFSSVC_MAXBLKSIZE;
233                 i.totalram <<= PAGE_SHIFT - 12;
234                 while (nfsd_max_blksize > i.totalram &&
235                        nfsd_max_blksize >= 8*1024*2)
236                         nfsd_max_blksize /= 2;
237         }
238
239         atomic_set(&nfsd_busy, 0);
240         nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
241                                       nfsd_last_thread, nfsd, THIS_MODULE);
242         if (nfsd_serv == NULL)
243                 err = -ENOMEM;
244
245         do_gettimeofday(&nfssvc_boot);          /* record boot time */
246         return err;
247 }
248
249 static int nfsd_init_socks(int port)
250 {
251         int error;
252         if (!list_empty(&nfsd_serv->sv_permsocks))
253                 return 0;
254
255         error = lockd_up(IPPROTO_UDP);
256         if (error >= 0) {
257                 error = svc_create_xprt(nfsd_serv, "udp", port,
258                                         SVC_SOCK_DEFAULTS);
259                 if (error < 0)
260                         lockd_down();
261         }
262         if (error < 0)
263                 return error;
264
265         error = lockd_up(IPPROTO_TCP);
266         if (error >= 0) {
267                 error = svc_create_xprt(nfsd_serv, "tcp", port,
268                                         SVC_SOCK_DEFAULTS);
269                 if (error < 0)
270                         lockd_down();
271         }
272         if (error < 0)
273                 return error;
274         return 0;
275 }
276
277 int nfsd_nrpools(void)
278 {
279         if (nfsd_serv == NULL)
280                 return 0;
281         else
282                 return nfsd_serv->sv_nrpools;
283 }
284
285 int nfsd_get_nrthreads(int n, int *nthreads)
286 {
287         int i = 0;
288
289         if (nfsd_serv != NULL) {
290                 for (i = 0; i < nfsd_serv->sv_nrpools && i < n; i++)
291                         nthreads[i] = nfsd_serv->sv_pools[i].sp_nrthreads;
292         }
293
294         return 0;
295 }
296
297 int nfsd_set_nrthreads(int n, int *nthreads)
298 {
299         int i = 0;
300         int tot = 0;
301         int err = 0;
302
303         WARN_ON(!mutex_is_locked(&nfsd_mutex));
304
305         if (nfsd_serv == NULL || n <= 0)
306                 return 0;
307
308         if (n > nfsd_serv->sv_nrpools)
309                 n = nfsd_serv->sv_nrpools;
310
311         /* enforce a global maximum number of threads */
312         tot = 0;
313         for (i = 0; i < n; i++) {
314                 if (nthreads[i] > NFSD_MAXSERVS)
315                         nthreads[i] = NFSD_MAXSERVS;
316                 tot += nthreads[i];
317         }
318         if (tot > NFSD_MAXSERVS) {
319                 /* total too large: scale down requested numbers */
320                 for (i = 0; i < n && tot > 0; i++) {
321                         int new = nthreads[i] * NFSD_MAXSERVS / tot;
322                         tot -= (nthreads[i] - new);
323                         nthreads[i] = new;
324                 }
325                 for (i = 0; i < n && tot > 0; i++) {
326                         nthreads[i]--;
327                         tot--;
328                 }
329         }
330
331         /*
332          * There must always be a thread in pool 0; the admin
333          * can't shut down NFS completely using pool_threads.
334          */
335         if (nthreads[0] == 0)
336                 nthreads[0] = 1;
337
338         /* apply the new numbers */
339         svc_get(nfsd_serv);
340         for (i = 0; i < n; i++) {
341                 err = svc_set_num_threads(nfsd_serv, &nfsd_serv->sv_pools[i],
342                                           nthreads[i]);
343                 if (err)
344                         break;
345         }
346         svc_destroy(nfsd_serv);
347
348         return err;
349 }
350
351 int
352 nfsd_svc(unsigned short port, int nrservs)
353 {
354         int     error;
355
356         mutex_lock(&nfsd_mutex);
357         dprintk("nfsd: creating service\n");
358         error = -EINVAL;
359         if (nrservs <= 0)
360                 nrservs = 0;
361         if (nrservs > NFSD_MAXSERVS)
362                 nrservs = NFSD_MAXSERVS;
363         
364         /* Readahead param cache - will no-op if it already exists */
365         error = nfsd_racache_init(2*nrservs);
366         if (error<0)
367                 goto out;
368         nfs4_state_start();
369
370         nfsd_reset_versions();
371
372         error = nfsd_create_serv();
373
374         if (error)
375                 goto out;
376         error = nfsd_init_socks(port);
377         if (error)
378                 goto failure;
379
380         error = svc_set_num_threads(nfsd_serv, NULL, nrservs);
381  failure:
382         svc_destroy(nfsd_serv);         /* Release server */
383  out:
384         mutex_unlock(&nfsd_mutex);
385         return error;
386 }
387
388 static inline void
389 update_thread_usage(int busy_threads)
390 {
391         unsigned long prev_call;
392         unsigned long diff;
393         int decile;
394
395         spin_lock(&nfsd_call_lock);
396         prev_call = nfsd_last_call;
397         nfsd_last_call = jiffies;
398         decile = busy_threads*10/nfsdstats.th_cnt;
399         if (decile>0 && decile <= 10) {
400                 diff = nfsd_last_call - prev_call;
401                 if ( (nfsdstats.th_usage[decile-1] += diff) >= NFSD_USAGE_WRAP)
402                         nfsdstats.th_usage[decile-1] -= NFSD_USAGE_WRAP;
403                 if (decile == 10)
404                         nfsdstats.th_fullcnt++;
405         }
406         spin_unlock(&nfsd_call_lock);
407 }
408
409 /*
410  * This is the NFS server kernel thread
411  */
412 static int
413 nfsd(void *vrqstp)
414 {
415         struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
416         struct fs_struct *fsp;
417         sigset_t shutdown_mask, allowed_mask;
418         int err, preverr = 0;
419         unsigned int signo;
420
421         /* Lock module and set up kernel thread */
422         mutex_lock(&nfsd_mutex);
423
424         /* At this point, the thread shares current->fs
425          * with the init process. We need to create files with a
426          * umask of 0 instead of init's umask. */
427         fsp = copy_fs_struct(current->fs);
428         if (!fsp) {
429                 printk("Unable to start nfsd thread: out of memory\n");
430                 goto out;
431         }
432         exit_fs(current);
433         current->fs = fsp;
434         current->fs->umask = 0;
435
436         siginitsetinv(&shutdown_mask, SHUTDOWN_SIGS);
437         siginitsetinv(&allowed_mask, ALLOWED_SIGS);
438
439         /*
440          * thread is spawned with all signals set to SIG_IGN, re-enable
441          * the ones that matter
442          */
443         for (signo = 1; signo <= _NSIG; signo++) {
444                 if (!sigismember(&shutdown_mask, signo))
445                         allow_signal(signo);
446         }
447
448         nfsdstats.th_cnt++;
449         mutex_unlock(&nfsd_mutex);
450
451         /*
452          * We want less throttling in balance_dirty_pages() so that nfs to
453          * localhost doesn't cause nfsd to lock up due to all the client's
454          * dirty pages.
455          */
456         current->flags |= PF_LESS_THROTTLE;
457         set_freezable();
458
459         /*
460          * The main request loop
461          */
462         for (;;) {
463                 /* Block all but the shutdown signals */
464                 sigprocmask(SIG_SETMASK, &shutdown_mask, NULL);
465
466                 /*
467                  * Find a socket with data available and call its
468                  * recvfrom routine.
469                  */
470                 while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
471                         ;
472                 if (err == -EINTR)
473                         break;
474                 else if (err < 0) {
475                         if (err != preverr) {
476                                 printk(KERN_WARNING "%s: unexpected error "
477                                         "from svc_recv (%d)\n", __func__, -err);
478                                 preverr = err;
479                         }
480                         schedule_timeout_uninterruptible(HZ);
481                         continue;
482                 }
483
484                 update_thread_usage(atomic_read(&nfsd_busy));
485                 atomic_inc(&nfsd_busy);
486
487                 /* Lock the export hash tables for reading. */
488                 exp_readlock();
489
490                 /* Process request with signals blocked. */
491                 sigprocmask(SIG_SETMASK, &allowed_mask, NULL);
492
493                 svc_process(rqstp);
494
495                 /* Unlock export hash tables */
496                 exp_readunlock();
497                 update_thread_usage(atomic_read(&nfsd_busy));
498                 atomic_dec(&nfsd_busy);
499         }
500
501         /* Clear signals before calling svc_exit_thread() */
502         flush_signals(current);
503
504         mutex_lock(&nfsd_mutex);
505         nfsdstats.th_cnt --;
506
507 out:
508         /* Release the thread */
509         svc_exit_thread(rqstp);
510
511         /* Release module */
512         mutex_unlock(&nfsd_mutex);
513         module_put_and_exit(0);
514         return 0;
515 }
516
517 static __be32 map_new_errors(u32 vers, __be32 nfserr)
518 {
519         if (nfserr == nfserr_jukebox && vers == 2)
520                 return nfserr_dropit;
521         if (nfserr == nfserr_wrongsec && vers < 4)
522                 return nfserr_acces;
523         return nfserr;
524 }
525
526 int
527 nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
528 {
529         struct svc_procedure    *proc;
530         kxdrproc_t              xdr;
531         __be32                  nfserr;
532         __be32                  *nfserrp;
533
534         dprintk("nfsd_dispatch: vers %d proc %d\n",
535                                 rqstp->rq_vers, rqstp->rq_proc);
536         proc = rqstp->rq_procinfo;
537
538         /* Check whether we have this call in the cache. */
539         switch (nfsd_cache_lookup(rqstp, proc->pc_cachetype)) {
540         case RC_INTR:
541         case RC_DROPIT:
542                 return 0;
543         case RC_REPLY:
544                 return 1;
545         case RC_DOIT:;
546                 /* do it */
547         }
548
549         /* Decode arguments */
550         xdr = proc->pc_decode;
551         if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base,
552                         rqstp->rq_argp)) {
553                 dprintk("nfsd: failed to decode arguments!\n");
554                 nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
555                 *statp = rpc_garbage_args;
556                 return 1;
557         }
558
559         /* need to grab the location to store the status, as
560          * nfsv4 does some encoding while processing 
561          */
562         nfserrp = rqstp->rq_res.head[0].iov_base
563                 + rqstp->rq_res.head[0].iov_len;
564         rqstp->rq_res.head[0].iov_len += sizeof(__be32);
565
566         /* Now call the procedure handler, and encode NFS status. */
567         nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
568         nfserr = map_new_errors(rqstp->rq_vers, nfserr);
569         if (nfserr == nfserr_dropit) {
570                 dprintk("nfsd: Dropping request; may be revisited later\n");
571                 nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
572                 return 0;
573         }
574
575         if (rqstp->rq_proc != 0)
576                 *nfserrp++ = nfserr;
577
578         /* Encode result.
579          * For NFSv2, additional info is never returned in case of an error.
580          */
581         if (!(nfserr && rqstp->rq_vers == 2)) {
582                 xdr = proc->pc_encode;
583                 if (xdr && !xdr(rqstp, nfserrp,
584                                 rqstp->rq_resp)) {
585                         /* Failed to encode result. Release cache entry */
586                         dprintk("nfsd: failed to encode result!\n");
587                         nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
588                         *statp = rpc_system_err;
589                         return 1;
590                 }
591         }
592
593         /* Store reply in cache. */
594         nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
595         return 1;
596 }