~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/nfsd/nfssvc.c

Version: ~ [ linux-5.13-rc5 ] ~ [ linux-5.12.9 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.42 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.124 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.193 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.235 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.271 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.271 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * Central processing for nfsd.
  4  *
  5  * Authors:     Olaf Kirch (okir@monad.swb.de)
  6  *
  7  * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
  8  */
  9 
 10 #include <linux/sched/signal.h>
 11 #include <linux/freezer.h>
 12 #include <linux/module.h>
 13 #include <linux/fs_struct.h>
 14 #include <linux/swap.h>
 15 
 16 #include <linux/sunrpc/stats.h>
 17 #include <linux/sunrpc/svcsock.h>
 18 #include <linux/sunrpc/svc_xprt.h>
 19 #include <linux/lockd/bind.h>
 20 #include <linux/nfsacl.h>
 21 #include <linux/seq_file.h>
 22 #include <linux/inetdevice.h>
 23 #include <net/addrconf.h>
 24 #include <net/ipv6.h>
 25 #include <net/net_namespace.h>
 26 #include "nfsd.h"
 27 #include "cache.h"
 28 #include "vfs.h"
 29 #include "netns.h"
 30 
 31 #define NFSDDBG_FACILITY        NFSDDBG_SVC
 32 
 33 extern struct svc_program       nfsd_program;
 34 static int                      nfsd(void *vrqstp);
 35 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
 36 static int                      nfsd_acl_rpcbind_set(struct net *,
 37                                                      const struct svc_program *,
 38                                                      u32, int,
 39                                                      unsigned short,
 40                                                      unsigned short);
 41 static __be32                   nfsd_acl_init_request(struct svc_rqst *,
 42                                                 const struct svc_program *,
 43                                                 struct svc_process_info *);
 44 #endif
 45 static int                      nfsd_rpcbind_set(struct net *,
 46                                                  const struct svc_program *,
 47                                                  u32, int,
 48                                                  unsigned short,
 49                                                  unsigned short);
 50 static __be32                   nfsd_init_request(struct svc_rqst *,
 51                                                 const struct svc_program *,
 52                                                 struct svc_process_info *);
 53 
 54 /*
 55  * nfsd_mutex protects nn->nfsd_serv -- both the pointer itself and the members
 56  * of the svc_serv struct. In particular, ->sv_nrthreads but also to some
 57  * extent ->sv_temp_socks and ->sv_permsocks. It also protects nfsdstats.th_cnt
 58  *
 59  * If (out side the lock) nn->nfsd_serv is non-NULL, then it must point to a
 60  * properly initialised 'struct svc_serv' with ->sv_nrthreads > 0. That number
 61  * of nfsd threads must exist and each must listed in ->sp_all_threads in each
 62  * entry of ->sv_pools[].
 63  *
 64  * Transitions of the thread count between zero and non-zero are of particular
 65  * interest since the svc_serv needs to be created and initialized at that
 66  * point, or freed.
 67  *
 68  * Finally, the nfsd_mutex also protects some of the global variables that are
 69  * accessed when nfsd starts and that are settable via the write_* routines in
 70  * nfsctl.c. In particular:
 71  *
 72  *      user_recovery_dirname
 73  *      user_lease_time
 74  *      nfsd_versions
 75  */
 76 DEFINE_MUTEX(nfsd_mutex);
 77 
 78 /*
 79  * nfsd_drc_lock protects nfsd_drc_max_pages and nfsd_drc_pages_used.
 80  * nfsd_drc_max_pages limits the total amount of memory available for
 81  * version 4.1 DRC caches.
 82  * nfsd_drc_pages_used tracks the current version 4.1 DRC memory usage.
 83  */
 84 spinlock_t      nfsd_drc_lock;
 85 unsigned long   nfsd_drc_max_mem;
 86 unsigned long   nfsd_drc_mem_used;
 87 
 88 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
 89 static struct svc_stat  nfsd_acl_svcstats;
 90 static const struct svc_version *nfsd_acl_version[] = {
 91         [2] = &nfsd_acl_version2,
 92         [3] = &nfsd_acl_version3,
 93 };
 94 
 95 #define NFSD_ACL_MINVERS            2
 96 #define NFSD_ACL_NRVERS         ARRAY_SIZE(nfsd_acl_version)
 97 
 98 static struct svc_program       nfsd_acl_program = {
 99         .pg_prog                = NFS_ACL_PROGRAM,
100         .pg_nvers               = NFSD_ACL_NRVERS,
101         .pg_vers                = nfsd_acl_version,
102         .pg_name                = "nfsacl",
103         .pg_class               = "nfsd",
104         .pg_stats               = &nfsd_acl_svcstats,
105         .pg_authenticate        = &svc_set_client,
106         .pg_init_request        = nfsd_acl_init_request,
107         .pg_rpcbind_set         = nfsd_acl_rpcbind_set,
108 };
109 
110 static struct svc_stat  nfsd_acl_svcstats = {
111         .program        = &nfsd_acl_program,
112 };
113 #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
114 
115 static const struct svc_version *nfsd_version[] = {
116         [2] = &nfsd_version2,
117 #if defined(CONFIG_NFSD_V3)
118         [3] = &nfsd_version3,
119 #endif
120 #if defined(CONFIG_NFSD_V4)
121         [4] = &nfsd_version4,
122 #endif
123 };
124 
125 #define NFSD_MINVERS            2
126 #define NFSD_NRVERS             ARRAY_SIZE(nfsd_version)
127 
128 struct svc_program              nfsd_program = {
129 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
130         .pg_next                = &nfsd_acl_program,
131 #endif
132         .pg_prog                = NFS_PROGRAM,          /* program number */
133         .pg_nvers               = NFSD_NRVERS,          /* nr of entries in nfsd_version */
134         .pg_vers                = nfsd_version,         /* version table */
135         .pg_name                = "nfsd",               /* program name */
136         .pg_class               = "nfsd",               /* authentication class */
137         .pg_stats               = &nfsd_svcstats,       /* version table */
138         .pg_authenticate        = &svc_set_client,      /* export authentication */
139         .pg_init_request        = nfsd_init_request,
140         .pg_rpcbind_set         = nfsd_rpcbind_set,
141 };
142 
143 static bool
144 nfsd_support_version(int vers)
145 {
146         if (vers >= NFSD_MINVERS && vers < NFSD_NRVERS)
147                 return nfsd_version[vers] != NULL;
148         return false;
149 }
150 
151 static bool *
152 nfsd_alloc_versions(void)
153 {
154         bool *vers = kmalloc_array(NFSD_NRVERS, sizeof(bool), GFP_KERNEL);
155         unsigned i;
156 
157         if (vers) {
158                 /* All compiled versions are enabled by default */
159                 for (i = 0; i < NFSD_NRVERS; i++)
160                         vers[i] = nfsd_support_version(i);
161         }
162         return vers;
163 }
164 
165 static bool *
166 nfsd_alloc_minorversions(void)
167 {
168         bool *vers = kmalloc_array(NFSD_SUPPORTED_MINOR_VERSION + 1,
169                         sizeof(bool), GFP_KERNEL);
170         unsigned i;
171 
172         if (vers) {
173                 /* All minor versions are enabled by default */
174                 for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++)
175                         vers[i] = nfsd_support_version(4);
176         }
177         return vers;
178 }
179 
180 void
181 nfsd_netns_free_versions(struct nfsd_net *nn)
182 {
183         kfree(nn->nfsd_versions);
184         kfree(nn->nfsd4_minorversions);
185         nn->nfsd_versions = NULL;
186         nn->nfsd4_minorversions = NULL;
187 }
188 
189 static void
190 nfsd_netns_init_versions(struct nfsd_net *nn)
191 {
192         if (!nn->nfsd_versions) {
193                 nn->nfsd_versions = nfsd_alloc_versions();
194                 nn->nfsd4_minorversions = nfsd_alloc_minorversions();
195                 if (!nn->nfsd_versions || !nn->nfsd4_minorversions)
196                         nfsd_netns_free_versions(nn);
197         }
198 }
199 
200 int nfsd_vers(struct nfsd_net *nn, int vers, enum vers_op change)
201 {
202         if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
203                 return 0;
204         switch(change) {
205         case NFSD_SET:
206                 if (nn->nfsd_versions)
207                         nn->nfsd_versions[vers] = nfsd_support_version(vers);
208                 break;
209         case NFSD_CLEAR:
210                 nfsd_netns_init_versions(nn);
211                 if (nn->nfsd_versions)
212                         nn->nfsd_versions[vers] = false;
213                 break;
214         case NFSD_TEST:
215                 if (nn->nfsd_versions)
216                         return nn->nfsd_versions[vers];
217                 /* Fallthrough */
218         case NFSD_AVAIL:
219                 return nfsd_support_version(vers);
220         }
221         return 0;
222 }
223 
224 static void
225 nfsd_adjust_nfsd_versions4(struct nfsd_net *nn)
226 {
227         unsigned i;
228 
229         for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++) {
230                 if (nn->nfsd4_minorversions[i])
231                         return;
232         }
233         nfsd_vers(nn, 4, NFSD_CLEAR);
234 }
235 
236 int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change)
237 {
238         if (minorversion > NFSD_SUPPORTED_MINOR_VERSION &&
239             change != NFSD_AVAIL)
240                 return -1;
241 
242         switch(change) {
243         case NFSD_SET:
244                 if (nn->nfsd4_minorversions) {
245                         nfsd_vers(nn, 4, NFSD_SET);
246                         nn->nfsd4_minorversions[minorversion] =
247                                 nfsd_vers(nn, 4, NFSD_TEST);
248                 }
249                 break;
250         case NFSD_CLEAR:
251                 nfsd_netns_init_versions(nn);
252                 if (nn->nfsd4_minorversions) {
253                         nn->nfsd4_minorversions[minorversion] = false;
254                         nfsd_adjust_nfsd_versions4(nn);
255                 }
256                 break;
257         case NFSD_TEST:
258                 if (nn->nfsd4_minorversions)
259                         return nn->nfsd4_minorversions[minorversion];
260                 return nfsd_vers(nn, 4, NFSD_TEST);
261         case NFSD_AVAIL:
262                 return minorversion <= NFSD_SUPPORTED_MINOR_VERSION &&
263                         nfsd_vers(nn, 4, NFSD_AVAIL);
264         }
265         return 0;
266 }
267 
268 /*
269  * Maximum number of nfsd processes
270  */
271 #define NFSD_MAXSERVS           8192
272 
273 int nfsd_nrthreads(struct net *net)
274 {
275         int rv = 0;
276         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
277 
278         mutex_lock(&nfsd_mutex);
279         if (nn->nfsd_serv)
280                 rv = nn->nfsd_serv->sv_nrthreads;
281         mutex_unlock(&nfsd_mutex);
282         return rv;
283 }
284 
285 static int nfsd_init_socks(struct net *net, const struct cred *cred)
286 {
287         int error;
288         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
289 
290         if (!list_empty(&nn->nfsd_serv->sv_permsocks))
291                 return 0;
292 
293         error = svc_create_xprt(nn->nfsd_serv, "udp", net, PF_INET, NFS_PORT,
294                                         SVC_SOCK_DEFAULTS, cred);
295         if (error < 0)
296                 return error;
297 
298         error = svc_create_xprt(nn->nfsd_serv, "tcp", net, PF_INET, NFS_PORT,
299                                         SVC_SOCK_DEFAULTS, cred);
300         if (error < 0)
301                 return error;
302 
303         return 0;
304 }
305 
306 static int nfsd_users = 0;
307 
308 static int nfsd_startup_generic(int nrservs)
309 {
310         int ret;
311 
312         if (nfsd_users++)
313                 return 0;
314 
315         /*
316          * Readahead param cache - will no-op if it already exists.
317          * (Note therefore results will be suboptimal if number of
318          * threads is modified after nfsd start.)
319          */
320         ret = nfsd_racache_init(2*nrservs);
321         if (ret)
322                 goto dec_users;
323 
324         ret = nfs4_state_start();
325         if (ret)
326                 goto out_racache;
327         return 0;
328 
329 out_racache:
330         nfsd_racache_shutdown();
331 dec_users:
332         nfsd_users--;
333         return ret;
334 }
335 
336 static void nfsd_shutdown_generic(void)
337 {
338         if (--nfsd_users)
339                 return;
340 
341         nfs4_state_shutdown();
342         nfsd_racache_shutdown();
343 }
344 
345 static bool nfsd_needs_lockd(struct nfsd_net *nn)
346 {
347         return nfsd_vers(nn, 2, NFSD_TEST) || nfsd_vers(nn, 3, NFSD_TEST);
348 }
349 
350 static int nfsd_startup_net(int nrservs, struct net *net, const struct cred *cred)
351 {
352         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
353         int ret;
354 
355         if (nn->nfsd_net_up)
356                 return 0;
357 
358         ret = nfsd_startup_generic(nrservs);
359         if (ret)
360                 return ret;
361         ret = nfsd_init_socks(net, cred);
362         if (ret)
363                 goto out_socks;
364 
365         if (nfsd_needs_lockd(nn) && !nn->lockd_up) {
366                 ret = lockd_up(net, cred);
367                 if (ret)
368                         goto out_socks;
369                 nn->lockd_up = 1;
370         }
371 
372         ret = nfs4_state_start_net(net);
373         if (ret)
374                 goto out_lockd;
375 
376         nn->nfsd_net_up = true;
377         return 0;
378 
379 out_lockd:
380         if (nn->lockd_up) {
381                 lockd_down(net);
382                 nn->lockd_up = 0;
383         }
384 out_socks:
385         nfsd_shutdown_generic();
386         return ret;
387 }
388 
389 static void nfsd_shutdown_net(struct net *net)
390 {
391         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
392 
393         nfs4_state_shutdown_net(net);
394         if (nn->lockd_up) {
395                 lockd_down(net);
396                 nn->lockd_up = 0;
397         }
398         nn->nfsd_net_up = false;
399         nfsd_shutdown_generic();
400 }
401 
402 static int nfsd_inetaddr_event(struct notifier_block *this, unsigned long event,
403         void *ptr)
404 {
405         struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
406         struct net_device *dev = ifa->ifa_dev->dev;
407         struct net *net = dev_net(dev);
408         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
409         struct sockaddr_in sin;
410 
411         if ((event != NETDEV_DOWN) ||
412             !atomic_inc_not_zero(&nn->ntf_refcnt))
413                 goto out;
414 
415         if (nn->nfsd_serv) {
416                 dprintk("nfsd_inetaddr_event: removed %pI4\n", &ifa->ifa_local);
417                 sin.sin_family = AF_INET;
418                 sin.sin_addr.s_addr = ifa->ifa_local;
419                 svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin);
420         }
421         atomic_dec(&nn->ntf_refcnt);
422         wake_up(&nn->ntf_wq);
423 
424 out:
425         return NOTIFY_DONE;
426 }
427 
428 static struct notifier_block nfsd_inetaddr_notifier = {
429         .notifier_call = nfsd_inetaddr_event,
430 };
431 
432 #if IS_ENABLED(CONFIG_IPV6)
433 static int nfsd_inet6addr_event(struct notifier_block *this,
434         unsigned long event, void *ptr)
435 {
436         struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
437         struct net_device *dev = ifa->idev->dev;
438         struct net *net = dev_net(dev);
439         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
440         struct sockaddr_in6 sin6;
441 
442         if ((event != NETDEV_DOWN) ||
443             !atomic_inc_not_zero(&nn->ntf_refcnt))
444                 goto out;
445 
446         if (nn->nfsd_serv) {
447                 dprintk("nfsd_inet6addr_event: removed %pI6\n", &ifa->addr);
448                 sin6.sin6_family = AF_INET6;
449                 sin6.sin6_addr = ifa->addr;
450                 if (ipv6_addr_type(&sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
451                         sin6.sin6_scope_id = ifa->idev->dev->ifindex;
452                 svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin6);
453         }
454         atomic_dec(&nn->ntf_refcnt);
455         wake_up(&nn->ntf_wq);
456 out:
457         return NOTIFY_DONE;
458 }
459 
460 static struct notifier_block nfsd_inet6addr_notifier = {
461         .notifier_call = nfsd_inet6addr_event,
462 };
463 #endif
464 
465 /* Only used under nfsd_mutex, so this atomic may be overkill: */
466 static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0);
467 
468 static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
469 {
470         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
471 
472         atomic_dec(&nn->ntf_refcnt);
473         /* check if the notifier still has clients */
474         if (atomic_dec_return(&nfsd_notifier_refcount) == 0) {
475                 unregister_inetaddr_notifier(&nfsd_inetaddr_notifier);
476 #if IS_ENABLED(CONFIG_IPV6)
477                 unregister_inet6addr_notifier(&nfsd_inet6addr_notifier);
478 #endif
479         }
480         wait_event(nn->ntf_wq, atomic_read(&nn->ntf_refcnt) == 0);
481 
482         /*
483          * write_ports can create the server without actually starting
484          * any threads--if we get shut down before any threads are
485          * started, then nfsd_last_thread will be run before any of this
486          * other initialization has been done except the rpcb information.
487          */
488         svc_rpcb_cleanup(serv, net);
489         if (!nn->nfsd_net_up)
490                 return;
491 
492         nfsd_shutdown_net(net);
493         printk(KERN_WARNING "nfsd: last server has exited, flushing export "
494                             "cache\n");
495         nfsd_export_flush(net);
496 }
497 
498 void nfsd_reset_versions(struct nfsd_net *nn)
499 {
500         int i;
501 
502         for (i = 0; i < NFSD_NRVERS; i++)
503                 if (nfsd_vers(nn, i, NFSD_TEST))
504                         return;
505 
506         for (i = 0; i < NFSD_NRVERS; i++)
507                 if (i != 4)
508                         nfsd_vers(nn, i, NFSD_SET);
509                 else {
510                         int minor = 0;
511                         while (nfsd_minorversion(nn, minor, NFSD_SET) >= 0)
512                                 minor++;
513                 }
514 }
515 
516 /*
517  * Each session guarantees a negotiated per slot memory cache for replies
518  * which in turn consumes memory beyond the v2/v3/v4.0 server. A dedicated
519  * NFSv4.1 server might want to use more memory for a DRC than a machine
520  * with mutiple services.
521  *
522  * Impose a hard limit on the number of pages for the DRC which varies
523  * according to the machines free pages. This is of course only a default.
524  *
525  * For now this is a #defined shift which could be under admin control
526  * in the future.
527  */
528 static void set_max_drc(void)
529 {
530         #define NFSD_DRC_SIZE_SHIFT     7
531         nfsd_drc_max_mem = (nr_free_buffer_pages()
532                                         >> NFSD_DRC_SIZE_SHIFT) * PAGE_SIZE;
533         nfsd_drc_mem_used = 0;
534         spin_lock_init(&nfsd_drc_lock);
535         dprintk("%s nfsd_drc_max_mem %lu \n", __func__, nfsd_drc_max_mem);
536 }
537 
538 static int nfsd_get_default_max_blksize(void)
539 {
540         struct sysinfo i;
541         unsigned long long target;
542         unsigned long ret;
543 
544         si_meminfo(&i);
545         target = (i.totalram - i.totalhigh) << PAGE_SHIFT;
546         /*
547          * Aim for 1/4096 of memory per thread This gives 1MB on 4Gig
548          * machines, but only uses 32K on 128M machines.  Bottom out at
549          * 8K on 32M and smaller.  Of course, this is only a default.
550          */
551         target >>= 12;
552 
553         ret = NFSSVC_MAXBLKSIZE;
554         while (ret > target && ret >= 8*1024*2)
555                 ret /= 2;
556         return ret;
557 }
558 
559 static const struct svc_serv_ops nfsd_thread_sv_ops = {
560         .svo_shutdown           = nfsd_last_thread,
561         .svo_function           = nfsd,
562         .svo_enqueue_xprt       = svc_xprt_do_enqueue,
563         .svo_setup              = svc_set_num_threads,
564         .svo_module             = THIS_MODULE,
565 };
566 
567 int nfsd_create_serv(struct net *net)
568 {
569         int error;
570         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
571 
572         WARN_ON(!mutex_is_locked(&nfsd_mutex));
573         if (nn->nfsd_serv) {
574                 svc_get(nn->nfsd_serv);
575                 return 0;
576         }
577         if (nfsd_max_blksize == 0)
578                 nfsd_max_blksize = nfsd_get_default_max_blksize();
579         nfsd_reset_versions(nn);
580         nn->nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
581                                                 &nfsd_thread_sv_ops);
582         if (nn->nfsd_serv == NULL)
583                 return -ENOMEM;
584 
585         nn->nfsd_serv->sv_maxconn = nn->max_connections;
586         error = svc_bind(nn->nfsd_serv, net);
587         if (error < 0) {
588                 svc_destroy(nn->nfsd_serv);
589                 return error;
590         }
591 
592         set_max_drc();
593         /* check if the notifier is already set */
594         if (atomic_inc_return(&nfsd_notifier_refcount) == 1) {
595                 register_inetaddr_notifier(&nfsd_inetaddr_notifier);
596 #if IS_ENABLED(CONFIG_IPV6)
597                 register_inet6addr_notifier(&nfsd_inet6addr_notifier);
598 #endif
599         }
600         atomic_inc(&nn->ntf_refcnt);
601         ktime_get_real_ts64(&nn->nfssvc_boot); /* record boot time */
602         return 0;
603 }
604 
605 int nfsd_nrpools(struct net *net)
606 {
607         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
608 
609         if (nn->nfsd_serv == NULL)
610                 return 0;
611         else
612                 return nn->nfsd_serv->sv_nrpools;
613 }
614 
615 int nfsd_get_nrthreads(int n, int *nthreads, struct net *net)
616 {
617         int i = 0;
618         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
619 
620         if (nn->nfsd_serv != NULL) {
621                 for (i = 0; i < nn->nfsd_serv->sv_nrpools && i < n; i++)
622                         nthreads[i] = nn->nfsd_serv->sv_pools[i].sp_nrthreads;
623         }
624 
625         return 0;
626 }
627 
628 void nfsd_destroy(struct net *net)
629 {
630         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
631         int destroy = (nn->nfsd_serv->sv_nrthreads == 1);
632 
633         if (destroy)
634                 svc_shutdown_net(nn->nfsd_serv, net);
635         svc_destroy(nn->nfsd_serv);
636         if (destroy)
637                 nn->nfsd_serv = NULL;
638 }
639 
640 int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
641 {
642         int i = 0;
643         int tot = 0;
644         int err = 0;
645         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
646 
647         WARN_ON(!mutex_is_locked(&nfsd_mutex));
648 
649         if (nn->nfsd_serv == NULL || n <= 0)
650                 return 0;
651 
652         if (n > nn->nfsd_serv->sv_nrpools)
653                 n = nn->nfsd_serv->sv_nrpools;
654 
655         /* enforce a global maximum number of threads */
656         tot = 0;
657         for (i = 0; i < n; i++) {
658                 nthreads[i] = min(nthreads[i], NFSD_MAXSERVS);
659                 tot += nthreads[i];
660         }
661         if (tot > NFSD_MAXSERVS) {
662                 /* total too large: scale down requested numbers */
663                 for (i = 0; i < n && tot > 0; i++) {
664                         int new = nthreads[i] * NFSD_MAXSERVS / tot;
665                         tot -= (nthreads[i] - new);
666                         nthreads[i] = new;
667                 }
668                 for (i = 0; i < n && tot > 0; i++) {
669                         nthreads[i]--;
670                         tot--;
671                 }
672         }
673 
674         /*
675          * There must always be a thread in pool 0; the admin
676          * can't shut down NFS completely using pool_threads.
677          */
678         if (nthreads[0] == 0)
679                 nthreads[0] = 1;
680 
681         /* apply the new numbers */
682         svc_get(nn->nfsd_serv);
683         for (i = 0; i < n; i++) {
684                 err = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv,
685                                 &nn->nfsd_serv->sv_pools[i], nthreads[i]);
686                 if (err)
687                         break;
688         }
689         nfsd_destroy(net);
690         return err;
691 }
692 
693 /*
694  * Adjust the number of threads and return the new number of threads.
695  * This is also the function that starts the server if necessary, if
696  * this is the first time nrservs is nonzero.
697  */
698 int
699 nfsd_svc(int nrservs, struct net *net, const struct cred *cred)
700 {
701         int     error;
702         bool    nfsd_up_before;
703         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
704 
705         mutex_lock(&nfsd_mutex);
706         dprintk("nfsd: creating service\n");
707 
708         nrservs = max(nrservs, 0);
709         nrservs = min(nrservs, NFSD_MAXSERVS);
710         error = 0;
711 
712         if (nrservs == 0 && nn->nfsd_serv == NULL)
713                 goto out;
714 
715         error = nfsd_create_serv(net);
716         if (error)
717                 goto out;
718 
719         nfsd_up_before = nn->nfsd_net_up;
720 
721         error = nfsd_startup_net(nrservs, net, cred);
722         if (error)
723                 goto out_destroy;
724         error = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv,
725                         NULL, nrservs);
726         if (error)
727                 goto out_shutdown;
728         /* We are holding a reference to nn->nfsd_serv which
729          * we don't want to count in the return value,
730          * so subtract 1
731          */
732         error = nn->nfsd_serv->sv_nrthreads - 1;
733 out_shutdown:
734         if (error < 0 && !nfsd_up_before)
735                 nfsd_shutdown_net(net);
736 out_destroy:
737         nfsd_destroy(net);              /* Release server */
738 out:
739         mutex_unlock(&nfsd_mutex);
740         return error;
741 }
742 
743 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
744 static bool
745 nfsd_support_acl_version(int vers)
746 {
747         if (vers >= NFSD_ACL_MINVERS && vers < NFSD_ACL_NRVERS)
748                 return nfsd_acl_version[vers] != NULL;
749         return false;
750 }
751 
752 static int
753 nfsd_acl_rpcbind_set(struct net *net, const struct svc_program *progp,
754                      u32 version, int family, unsigned short proto,
755                      unsigned short port)
756 {
757         if (!nfsd_support_acl_version(version) ||
758             !nfsd_vers(net_generic(net, nfsd_net_id), version, NFSD_TEST))
759                 return 0;
760         return svc_generic_rpcbind_set(net, progp, version, family,
761                         proto, port);
762 }
763 
764 static __be32
765 nfsd_acl_init_request(struct svc_rqst *rqstp,
766                       const struct svc_program *progp,
767                       struct svc_process_info *ret)
768 {
769         struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
770         int i;
771 
772         if (likely(nfsd_support_acl_version(rqstp->rq_vers) &&
773             nfsd_vers(nn, rqstp->rq_vers, NFSD_TEST)))
774                 return svc_generic_init_request(rqstp, progp, ret);
775 
776         ret->mismatch.lovers = NFSD_ACL_NRVERS;
777         for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) {
778                 if (nfsd_support_acl_version(rqstp->rq_vers) &&
779                     nfsd_vers(nn, i, NFSD_TEST)) {
780                         ret->mismatch.lovers = i;
781                         break;
782                 }
783         }
784         if (ret->mismatch.lovers == NFSD_ACL_NRVERS)
785                 return rpc_prog_unavail;
786         ret->mismatch.hivers = NFSD_ACL_MINVERS;
787         for (i = NFSD_ACL_NRVERS - 1; i >= NFSD_ACL_MINVERS; i--) {
788                 if (nfsd_support_acl_version(rqstp->rq_vers) &&
789                     nfsd_vers(nn, i, NFSD_TEST)) {
790                         ret->mismatch.hivers = i;
791                         break;
792                 }
793         }
794         return rpc_prog_mismatch;
795 }
796 #endif
797 
798 static int
799 nfsd_rpcbind_set(struct net *net, const struct svc_program *progp,
800                  u32 version, int family, unsigned short proto,
801                  unsigned short port)
802 {
803         if (!nfsd_vers(net_generic(net, nfsd_net_id), version, NFSD_TEST))
804                 return 0;
805         return svc_generic_rpcbind_set(net, progp, version, family,
806                         proto, port);
807 }
808 
809 static __be32
810 nfsd_init_request(struct svc_rqst *rqstp,
811                   const struct svc_program *progp,
812                   struct svc_process_info *ret)
813 {
814         struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
815         int i;
816 
817         if (likely(nfsd_vers(nn, rqstp->rq_vers, NFSD_TEST)))
818                 return svc_generic_init_request(rqstp, progp, ret);
819 
820         ret->mismatch.lovers = NFSD_NRVERS;
821         for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
822                 if (nfsd_vers(nn, i, NFSD_TEST)) {
823                         ret->mismatch.lovers = i;
824                         break;
825                 }
826         }
827         if (ret->mismatch.lovers == NFSD_NRVERS)
828                 return rpc_prog_unavail;
829         ret->mismatch.hivers = NFSD_MINVERS;
830         for (i = NFSD_NRVERS - 1; i >= NFSD_MINVERS; i--) {
831                 if (nfsd_vers(nn, i, NFSD_TEST)) {
832                         ret->mismatch.hivers = i;
833                         break;
834                 }
835         }
836         return rpc_prog_mismatch;
837 }
838 
839 /*
840  * This is the NFS server kernel thread
841  */
842 static int
843 nfsd(void *vrqstp)
844 {
845         struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
846         struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list);
847         struct net *net = perm_sock->xpt_net;
848         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
849         int err;
850 
851         /* Lock module and set up kernel thread */
852         mutex_lock(&nfsd_mutex);
853 
854         /* At this point, the thread shares current->fs
855          * with the init process. We need to create files with the
856          * umask as defined by the client instead of init's umask. */
857         if (unshare_fs_struct() < 0) {
858                 printk("Unable to start nfsd thread: out of memory\n");
859                 goto out;
860         }
861 
862         current->fs->umask = 0;
863 
864         /*
865          * thread is spawned with all signals set to SIG_IGN, re-enable
866          * the ones that will bring down the thread
867          */
868         allow_signal(SIGKILL);
869         allow_signal(SIGHUP);
870         allow_signal(SIGINT);
871         allow_signal(SIGQUIT);
872 
873         nfsdstats.th_cnt++;
874         mutex_unlock(&nfsd_mutex);
875 
876         set_freezable();
877 
878         /*
879          * The main request loop
880          */
881         for (;;) {
882                 /* Update sv_maxconn if it has changed */
883                 rqstp->rq_server->sv_maxconn = nn->max_connections;
884 
885                 /*
886                  * Find a socket with data available and call its
887                  * recvfrom routine.
888                  */
889                 while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
890                         ;
891                 if (err == -EINTR)
892                         break;
893                 validate_process_creds();
894                 svc_process(rqstp);
895                 validate_process_creds();
896         }
897 
898         /* Clear signals before calling svc_exit_thread() */
899         flush_signals(current);
900 
901         mutex_lock(&nfsd_mutex);
902         nfsdstats.th_cnt --;
903 
904 out:
905         rqstp->rq_server = NULL;
906 
907         /* Release the thread */
908         svc_exit_thread(rqstp);
909 
910         nfsd_destroy(net);
911 
912         /* Release module */
913         mutex_unlock(&nfsd_mutex);
914         module_put_and_exit(0);
915         return 0;
916 }
917 
918 static __be32 map_new_errors(u32 vers, __be32 nfserr)
919 {
920         if (nfserr == nfserr_jukebox && vers == 2)
921                 return nfserr_dropit;
922         if (nfserr == nfserr_wrongsec && vers < 4)
923                 return nfserr_acces;
924         return nfserr;
925 }
926 
927 /*
928  * A write procedure can have a large argument, and a read procedure can
929  * have a large reply, but no NFSv2 or NFSv3 procedure has argument and
930  * reply that can both be larger than a page.  The xdr code has taken
931  * advantage of this assumption to be a sloppy about bounds checking in
932  * some cases.  Pending a rewrite of the NFSv2/v3 xdr code to fix that
933  * problem, we enforce these assumptions here:
934  */
935 static bool nfs_request_too_big(struct svc_rqst *rqstp,
936                                 const struct svc_procedure *proc)
937 {
938         /*
939          * The ACL code has more careful bounds-checking and is not
940          * susceptible to this problem:
941          */
942         if (rqstp->rq_prog != NFS_PROGRAM)
943                 return false;
944         /*
945          * Ditto NFSv4 (which can in theory have argument and reply both
946          * more than a page):
947          */
948         if (rqstp->rq_vers >= 4)
949                 return false;
950         /* The reply will be small, we're OK: */
951         if (proc->pc_xdrressize > 0 &&
952             proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
953                 return false;
954 
955         return rqstp->rq_arg.len > PAGE_SIZE;
956 }
957 
958 int
959 nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
960 {
961         const struct svc_procedure *proc;
962         __be32                  nfserr;
963         __be32                  *nfserrp;
964 
965         dprintk("nfsd_dispatch: vers %d proc %d\n",
966                                 rqstp->rq_vers, rqstp->rq_proc);
967         proc = rqstp->rq_procinfo;
968 
969         if (nfs_request_too_big(rqstp, proc)) {
970                 dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
971                 *statp = rpc_garbage_args;
972                 return 1;
973         }
974         /*
975          * Give the xdr decoder a chance to change this if it wants
976          * (necessary in the NFSv4.0 compound case)
977          */
978         rqstp->rq_cachetype = proc->pc_cachetype;
979         /* Decode arguments */
980         if (proc->pc_decode &&
981             !proc->pc_decode(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base)) {
982                 dprintk("nfsd: failed to decode arguments!\n");
983                 *statp = rpc_garbage_args;
984                 return 1;
985         }
986 
987         /* Check whether we have this call in the cache. */
988         switch (nfsd_cache_lookup(rqstp)) {
989         case RC_DROPIT:
990                 return 0;
991         case RC_REPLY:
992                 return 1;
993         case RC_DOIT:;
994                 /* do it */
995         }
996 
997         /* need to grab the location to store the status, as
998          * nfsv4 does some encoding while processing 
999          */
1000         nfserrp = rqstp->rq_res.head[0].iov_base
1001                 + rqstp->rq_res.head[0].iov_len;
1002         rqstp->rq_res.head[0].iov_len += sizeof(__be32);
1003 
1004         /* Now call the procedure handler, and encode NFS status. */
1005         nfserr = proc->pc_func(rqstp);
1006         nfserr = map_new_errors(rqstp->rq_vers, nfserr);
1007         if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags)) {
1008                 dprintk("nfsd: Dropping request; may be revisited later\n");
1009                 nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
1010                 return 0;
1011         }
1012 
1013         if (rqstp->rq_proc != 0)
1014                 *nfserrp++ = nfserr;
1015 
1016         /* Encode result.
1017          * For NFSv2, additional info is never returned in case of an error.
1018          */
1019         if (!(nfserr && rqstp->rq_vers == 2)) {
1020                 if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp)) {
1021                         /* Failed to encode result. Release cache entry */
1022                         dprintk("nfsd: failed to encode result!\n");
1023                         nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
1024                         *statp = rpc_system_err;
1025                         return 1;
1026                 }
1027         }
1028 
1029         /* Store reply in cache. */
1030         nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
1031         return 1;
1032 }
1033 
1034 int nfsd_pool_stats_open(struct inode *inode, struct file *file)
1035 {
1036         int ret;
1037         struct nfsd_net *nn = net_generic(inode->i_sb->s_fs_info, nfsd_net_id);
1038 
1039         mutex_lock(&nfsd_mutex);
1040         if (nn->nfsd_serv == NULL) {
1041                 mutex_unlock(&nfsd_mutex);
1042                 return -ENODEV;
1043         }
1044         /* bump up the psudo refcount while traversing */
1045         svc_get(nn->nfsd_serv);
1046         ret = svc_pool_stats_open(nn->nfsd_serv, file);
1047         mutex_unlock(&nfsd_mutex);
1048         return ret;
1049 }
1050 
1051 int nfsd_pool_stats_release(struct inode *inode, struct file *file)
1052 {
1053         int ret = seq_release(inode, file);
1054         struct net *net = inode->i_sb->s_fs_info;
1055 
1056         mutex_lock(&nfsd_mutex);
1057         /* this function really, really should have been called svc_put() */
1058         nfsd_destroy(net);
1059         mutex_unlock(&nfsd_mutex);
1060         return ret;
1061 }
1062 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp