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