0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/sched/signal.h>
0011 #include <linux/freezer.h>
0012 #include <linux/module.h>
0013 #include <linux/fs_struct.h>
0014 #include <linux/swap.h>
0015 #include <linux/siphash.h>
0016
0017 #include <linux/sunrpc/stats.h>
0018 #include <linux/sunrpc/svcsock.h>
0019 #include <linux/sunrpc/svc_xprt.h>
0020 #include <linux/lockd/bind.h>
0021 #include <linux/nfsacl.h>
0022 #include <linux/seq_file.h>
0023 #include <linux/inetdevice.h>
0024 #include <net/addrconf.h>
0025 #include <net/ipv6.h>
0026 #include <net/net_namespace.h>
0027 #include "nfsd.h"
0028 #include "cache.h"
0029 #include "vfs.h"
0030 #include "netns.h"
0031 #include "filecache.h"
0032
0033 #include "trace.h"
0034
0035 #define NFSDDBG_FACILITY NFSDDBG_SVC
0036
0037 extern struct svc_program nfsd_program;
0038 static int nfsd(void *vrqstp);
0039 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
0040 static int nfsd_acl_rpcbind_set(struct net *,
0041 const struct svc_program *,
0042 u32, int,
0043 unsigned short,
0044 unsigned short);
0045 static __be32 nfsd_acl_init_request(struct svc_rqst *,
0046 const struct svc_program *,
0047 struct svc_process_info *);
0048 #endif
0049 static int nfsd_rpcbind_set(struct net *,
0050 const struct svc_program *,
0051 u32, int,
0052 unsigned short,
0053 unsigned short);
0054 static __be32 nfsd_init_request(struct svc_rqst *,
0055 const struct svc_program *,
0056 struct svc_process_info *);
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 DEFINE_MUTEX(nfsd_mutex);
0080
0081
0082
0083
0084
0085
0086
0087 DEFINE_SPINLOCK(nfsd_drc_lock);
0088 unsigned long nfsd_drc_max_mem;
0089 unsigned long nfsd_drc_mem_used;
0090
0091 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
0092 static struct svc_stat nfsd_acl_svcstats;
0093 static const struct svc_version *nfsd_acl_version[] = {
0094 [2] = &nfsd_acl_version2,
0095 [3] = &nfsd_acl_version3,
0096 };
0097
0098 #define NFSD_ACL_MINVERS 2
0099 #define NFSD_ACL_NRVERS ARRAY_SIZE(nfsd_acl_version)
0100
0101 static struct svc_program nfsd_acl_program = {
0102 .pg_prog = NFS_ACL_PROGRAM,
0103 .pg_nvers = NFSD_ACL_NRVERS,
0104 .pg_vers = nfsd_acl_version,
0105 .pg_name = "nfsacl",
0106 .pg_class = "nfsd",
0107 .pg_stats = &nfsd_acl_svcstats,
0108 .pg_authenticate = &svc_set_client,
0109 .pg_init_request = nfsd_acl_init_request,
0110 .pg_rpcbind_set = nfsd_acl_rpcbind_set,
0111 };
0112
0113 static struct svc_stat nfsd_acl_svcstats = {
0114 .program = &nfsd_acl_program,
0115 };
0116 #endif
0117
0118 static const struct svc_version *nfsd_version[] = {
0119 [2] = &nfsd_version2,
0120 [3] = &nfsd_version3,
0121 #if defined(CONFIG_NFSD_V4)
0122 [4] = &nfsd_version4,
0123 #endif
0124 };
0125
0126 #define NFSD_MINVERS 2
0127 #define NFSD_NRVERS ARRAY_SIZE(nfsd_version)
0128
0129 struct svc_program nfsd_program = {
0130 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
0131 .pg_next = &nfsd_acl_program,
0132 #endif
0133 .pg_prog = NFS_PROGRAM,
0134 .pg_nvers = NFSD_NRVERS,
0135 .pg_vers = nfsd_version,
0136 .pg_name = "nfsd",
0137 .pg_class = "nfsd",
0138 .pg_stats = &nfsd_svcstats,
0139 .pg_authenticate = &svc_set_client,
0140 .pg_init_request = nfsd_init_request,
0141 .pg_rpcbind_set = nfsd_rpcbind_set,
0142 };
0143
0144 static bool
0145 nfsd_support_version(int vers)
0146 {
0147 if (vers >= NFSD_MINVERS && vers < NFSD_NRVERS)
0148 return nfsd_version[vers] != NULL;
0149 return false;
0150 }
0151
0152 static bool *
0153 nfsd_alloc_versions(void)
0154 {
0155 bool *vers = kmalloc_array(NFSD_NRVERS, sizeof(bool), GFP_KERNEL);
0156 unsigned i;
0157
0158 if (vers) {
0159
0160 for (i = 0; i < NFSD_NRVERS; i++)
0161 vers[i] = nfsd_support_version(i);
0162 }
0163 return vers;
0164 }
0165
0166 static bool *
0167 nfsd_alloc_minorversions(void)
0168 {
0169 bool *vers = kmalloc_array(NFSD_SUPPORTED_MINOR_VERSION + 1,
0170 sizeof(bool), GFP_KERNEL);
0171 unsigned i;
0172
0173 if (vers) {
0174
0175 for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++)
0176 vers[i] = nfsd_support_version(4);
0177 }
0178 return vers;
0179 }
0180
0181 void
0182 nfsd_netns_free_versions(struct nfsd_net *nn)
0183 {
0184 kfree(nn->nfsd_versions);
0185 kfree(nn->nfsd4_minorversions);
0186 nn->nfsd_versions = NULL;
0187 nn->nfsd4_minorversions = NULL;
0188 }
0189
0190 static void
0191 nfsd_netns_init_versions(struct nfsd_net *nn)
0192 {
0193 if (!nn->nfsd_versions) {
0194 nn->nfsd_versions = nfsd_alloc_versions();
0195 nn->nfsd4_minorversions = nfsd_alloc_minorversions();
0196 if (!nn->nfsd_versions || !nn->nfsd4_minorversions)
0197 nfsd_netns_free_versions(nn);
0198 }
0199 }
0200
0201 int nfsd_vers(struct nfsd_net *nn, int vers, enum vers_op change)
0202 {
0203 if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
0204 return 0;
0205 switch(change) {
0206 case NFSD_SET:
0207 if (nn->nfsd_versions)
0208 nn->nfsd_versions[vers] = nfsd_support_version(vers);
0209 break;
0210 case NFSD_CLEAR:
0211 nfsd_netns_init_versions(nn);
0212 if (nn->nfsd_versions)
0213 nn->nfsd_versions[vers] = false;
0214 break;
0215 case NFSD_TEST:
0216 if (nn->nfsd_versions)
0217 return nn->nfsd_versions[vers];
0218 fallthrough;
0219 case NFSD_AVAIL:
0220 return nfsd_support_version(vers);
0221 }
0222 return 0;
0223 }
0224
0225 static void
0226 nfsd_adjust_nfsd_versions4(struct nfsd_net *nn)
0227 {
0228 unsigned i;
0229
0230 for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++) {
0231 if (nn->nfsd4_minorversions[i])
0232 return;
0233 }
0234 nfsd_vers(nn, 4, NFSD_CLEAR);
0235 }
0236
0237 int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change)
0238 {
0239 if (minorversion > NFSD_SUPPORTED_MINOR_VERSION &&
0240 change != NFSD_AVAIL)
0241 return -1;
0242
0243 switch(change) {
0244 case NFSD_SET:
0245 if (nn->nfsd4_minorversions) {
0246 nfsd_vers(nn, 4, NFSD_SET);
0247 nn->nfsd4_minorversions[minorversion] =
0248 nfsd_vers(nn, 4, NFSD_TEST);
0249 }
0250 break;
0251 case NFSD_CLEAR:
0252 nfsd_netns_init_versions(nn);
0253 if (nn->nfsd4_minorversions) {
0254 nn->nfsd4_minorversions[minorversion] = false;
0255 nfsd_adjust_nfsd_versions4(nn);
0256 }
0257 break;
0258 case NFSD_TEST:
0259 if (nn->nfsd4_minorversions)
0260 return nn->nfsd4_minorversions[minorversion];
0261 return nfsd_vers(nn, 4, NFSD_TEST);
0262 case NFSD_AVAIL:
0263 return minorversion <= NFSD_SUPPORTED_MINOR_VERSION &&
0264 nfsd_vers(nn, 4, NFSD_AVAIL);
0265 }
0266 return 0;
0267 }
0268
0269
0270
0271
0272 #define NFSD_MAXSERVS 8192
0273
0274 int nfsd_nrthreads(struct net *net)
0275 {
0276 int rv = 0;
0277 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0278
0279 mutex_lock(&nfsd_mutex);
0280 if (nn->nfsd_serv)
0281 rv = nn->nfsd_serv->sv_nrthreads;
0282 mutex_unlock(&nfsd_mutex);
0283 return rv;
0284 }
0285
0286 static int nfsd_init_socks(struct net *net, const struct cred *cred)
0287 {
0288 int error;
0289 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0290
0291 if (!list_empty(&nn->nfsd_serv->sv_permsocks))
0292 return 0;
0293
0294 error = svc_xprt_create(nn->nfsd_serv, "udp", net, PF_INET, NFS_PORT,
0295 SVC_SOCK_DEFAULTS, cred);
0296 if (error < 0)
0297 return error;
0298
0299 error = svc_xprt_create(nn->nfsd_serv, "tcp", net, PF_INET, NFS_PORT,
0300 SVC_SOCK_DEFAULTS, cred);
0301 if (error < 0)
0302 return error;
0303
0304 return 0;
0305 }
0306
0307 static int nfsd_users = 0;
0308
0309 static int nfsd_startup_generic(void)
0310 {
0311 int ret;
0312
0313 if (nfsd_users++)
0314 return 0;
0315
0316 ret = nfsd_file_cache_init();
0317 if (ret)
0318 goto dec_users;
0319
0320 ret = nfs4_state_start();
0321 if (ret)
0322 goto out_file_cache;
0323 return 0;
0324
0325 out_file_cache:
0326 nfsd_file_cache_shutdown();
0327 dec_users:
0328 nfsd_users--;
0329 return ret;
0330 }
0331
0332 static void nfsd_shutdown_generic(void)
0333 {
0334 if (--nfsd_users)
0335 return;
0336
0337 nfs4_state_shutdown();
0338 nfsd_file_cache_shutdown();
0339 }
0340
0341 static bool nfsd_needs_lockd(struct nfsd_net *nn)
0342 {
0343 return nfsd_vers(nn, 2, NFSD_TEST) || nfsd_vers(nn, 3, NFSD_TEST);
0344 }
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354 void nfsd_copy_write_verifier(__be32 verf[2], struct nfsd_net *nn)
0355 {
0356 int seq = 0;
0357
0358 do {
0359 read_seqbegin_or_lock(&nn->writeverf_lock, &seq);
0360 memcpy(verf, nn->writeverf, sizeof(*verf));
0361 } while (need_seqretry(&nn->writeverf_lock, seq));
0362 done_seqretry(&nn->writeverf_lock, seq);
0363 }
0364
0365 static void nfsd_reset_write_verifier_locked(struct nfsd_net *nn)
0366 {
0367 struct timespec64 now;
0368 u64 verf;
0369
0370
0371
0372
0373
0374 ktime_get_raw_ts64(&now);
0375 verf = siphash_2u64(now.tv_sec, now.tv_nsec, &nn->siphash_key);
0376 memcpy(nn->writeverf, &verf, sizeof(nn->writeverf));
0377 }
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 void nfsd_reset_write_verifier(struct nfsd_net *nn)
0393 {
0394 write_seqlock(&nn->writeverf_lock);
0395 nfsd_reset_write_verifier_locked(nn);
0396 write_sequnlock(&nn->writeverf_lock);
0397 }
0398
0399 static int nfsd_startup_net(struct net *net, const struct cred *cred)
0400 {
0401 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0402 int ret;
0403
0404 if (nn->nfsd_net_up)
0405 return 0;
0406
0407 ret = nfsd_startup_generic();
0408 if (ret)
0409 return ret;
0410 ret = nfsd_init_socks(net, cred);
0411 if (ret)
0412 goto out_socks;
0413
0414 if (nfsd_needs_lockd(nn) && !nn->lockd_up) {
0415 ret = lockd_up(net, cred);
0416 if (ret)
0417 goto out_socks;
0418 nn->lockd_up = true;
0419 }
0420
0421 ret = nfsd_file_cache_start_net(net);
0422 if (ret)
0423 goto out_lockd;
0424 ret = nfs4_state_start_net(net);
0425 if (ret)
0426 goto out_filecache;
0427
0428 #ifdef CONFIG_NFSD_V4_2_INTER_SSC
0429 nfsd4_ssc_init_umount_work(nn);
0430 #endif
0431 nn->nfsd_net_up = true;
0432 return 0;
0433
0434 out_filecache:
0435 nfsd_file_cache_shutdown_net(net);
0436 out_lockd:
0437 if (nn->lockd_up) {
0438 lockd_down(net);
0439 nn->lockd_up = false;
0440 }
0441 out_socks:
0442 nfsd_shutdown_generic();
0443 return ret;
0444 }
0445
0446 static void nfsd_shutdown_net(struct net *net)
0447 {
0448 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0449
0450 nfsd_file_cache_shutdown_net(net);
0451 nfs4_state_shutdown_net(net);
0452 if (nn->lockd_up) {
0453 lockd_down(net);
0454 nn->lockd_up = false;
0455 }
0456 nn->nfsd_net_up = false;
0457 nfsd_shutdown_generic();
0458 }
0459
0460 static DEFINE_SPINLOCK(nfsd_notifier_lock);
0461 static int nfsd_inetaddr_event(struct notifier_block *this, unsigned long event,
0462 void *ptr)
0463 {
0464 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
0465 struct net_device *dev = ifa->ifa_dev->dev;
0466 struct net *net = dev_net(dev);
0467 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0468 struct sockaddr_in sin;
0469
0470 if (event != NETDEV_DOWN || !nn->nfsd_serv)
0471 goto out;
0472
0473 spin_lock(&nfsd_notifier_lock);
0474 if (nn->nfsd_serv) {
0475 dprintk("nfsd_inetaddr_event: removed %pI4\n", &ifa->ifa_local);
0476 sin.sin_family = AF_INET;
0477 sin.sin_addr.s_addr = ifa->ifa_local;
0478 svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin);
0479 }
0480 spin_unlock(&nfsd_notifier_lock);
0481
0482 out:
0483 return NOTIFY_DONE;
0484 }
0485
0486 static struct notifier_block nfsd_inetaddr_notifier = {
0487 .notifier_call = nfsd_inetaddr_event,
0488 };
0489
0490 #if IS_ENABLED(CONFIG_IPV6)
0491 static int nfsd_inet6addr_event(struct notifier_block *this,
0492 unsigned long event, void *ptr)
0493 {
0494 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
0495 struct net_device *dev = ifa->idev->dev;
0496 struct net *net = dev_net(dev);
0497 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0498 struct sockaddr_in6 sin6;
0499
0500 if (event != NETDEV_DOWN || !nn->nfsd_serv)
0501 goto out;
0502
0503 spin_lock(&nfsd_notifier_lock);
0504 if (nn->nfsd_serv) {
0505 dprintk("nfsd_inet6addr_event: removed %pI6\n", &ifa->addr);
0506 sin6.sin6_family = AF_INET6;
0507 sin6.sin6_addr = ifa->addr;
0508 if (ipv6_addr_type(&sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
0509 sin6.sin6_scope_id = ifa->idev->dev->ifindex;
0510 svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin6);
0511 }
0512 spin_unlock(&nfsd_notifier_lock);
0513
0514 out:
0515 return NOTIFY_DONE;
0516 }
0517
0518 static struct notifier_block nfsd_inet6addr_notifier = {
0519 .notifier_call = nfsd_inet6addr_event,
0520 };
0521 #endif
0522
0523
0524 static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0);
0525
0526 static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
0527 {
0528 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0529
0530
0531 if (atomic_dec_return(&nfsd_notifier_refcount) == 0) {
0532 unregister_inetaddr_notifier(&nfsd_inetaddr_notifier);
0533 #if IS_ENABLED(CONFIG_IPV6)
0534 unregister_inet6addr_notifier(&nfsd_inet6addr_notifier);
0535 #endif
0536 }
0537
0538
0539
0540
0541
0542
0543
0544 svc_rpcb_cleanup(serv, net);
0545 if (!nn->nfsd_net_up)
0546 return;
0547
0548 nfsd_shutdown_net(net);
0549 pr_info("nfsd: last server has exited, flushing export cache\n");
0550 nfsd_export_flush(net);
0551 }
0552
0553 void nfsd_reset_versions(struct nfsd_net *nn)
0554 {
0555 int i;
0556
0557 for (i = 0; i < NFSD_NRVERS; i++)
0558 if (nfsd_vers(nn, i, NFSD_TEST))
0559 return;
0560
0561 for (i = 0; i < NFSD_NRVERS; i++)
0562 if (i != 4)
0563 nfsd_vers(nn, i, NFSD_SET);
0564 else {
0565 int minor = 0;
0566 while (nfsd_minorversion(nn, minor, NFSD_SET) >= 0)
0567 minor++;
0568 }
0569 }
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583 static void set_max_drc(void)
0584 {
0585 #define NFSD_DRC_SIZE_SHIFT 7
0586 nfsd_drc_max_mem = (nr_free_buffer_pages()
0587 >> NFSD_DRC_SIZE_SHIFT) * PAGE_SIZE;
0588 nfsd_drc_mem_used = 0;
0589 dprintk("%s nfsd_drc_max_mem %lu \n", __func__, nfsd_drc_max_mem);
0590 }
0591
0592 static int nfsd_get_default_max_blksize(void)
0593 {
0594 struct sysinfo i;
0595 unsigned long long target;
0596 unsigned long ret;
0597
0598 si_meminfo(&i);
0599 target = (i.totalram - i.totalhigh) << PAGE_SHIFT;
0600
0601
0602
0603
0604
0605 target >>= 12;
0606
0607 ret = NFSSVC_MAXBLKSIZE;
0608 while (ret > target && ret >= 8*1024*2)
0609 ret /= 2;
0610 return ret;
0611 }
0612
0613 void nfsd_shutdown_threads(struct net *net)
0614 {
0615 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0616 struct svc_serv *serv;
0617
0618 mutex_lock(&nfsd_mutex);
0619 serv = nn->nfsd_serv;
0620 if (serv == NULL) {
0621 mutex_unlock(&nfsd_mutex);
0622 return;
0623 }
0624
0625 svc_get(serv);
0626
0627 svc_set_num_threads(serv, NULL, 0);
0628 nfsd_put(net);
0629 mutex_unlock(&nfsd_mutex);
0630 }
0631
0632 bool i_am_nfsd(void)
0633 {
0634 return kthread_func(current) == nfsd;
0635 }
0636
0637 int nfsd_create_serv(struct net *net)
0638 {
0639 int error;
0640 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0641 struct svc_serv *serv;
0642
0643 WARN_ON(!mutex_is_locked(&nfsd_mutex));
0644 if (nn->nfsd_serv) {
0645 svc_get(nn->nfsd_serv);
0646 return 0;
0647 }
0648 if (nfsd_max_blksize == 0)
0649 nfsd_max_blksize = nfsd_get_default_max_blksize();
0650 nfsd_reset_versions(nn);
0651 serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize, nfsd);
0652 if (serv == NULL)
0653 return -ENOMEM;
0654
0655 serv->sv_maxconn = nn->max_connections;
0656 error = svc_bind(serv, net);
0657 if (error < 0) {
0658
0659
0660
0661 svc_put(serv);
0662 return error;
0663 }
0664 spin_lock(&nfsd_notifier_lock);
0665 nn->nfsd_serv = serv;
0666 spin_unlock(&nfsd_notifier_lock);
0667
0668 set_max_drc();
0669
0670 if (atomic_inc_return(&nfsd_notifier_refcount) == 1) {
0671 register_inetaddr_notifier(&nfsd_inetaddr_notifier);
0672 #if IS_ENABLED(CONFIG_IPV6)
0673 register_inet6addr_notifier(&nfsd_inet6addr_notifier);
0674 #endif
0675 }
0676 nfsd_reset_write_verifier(nn);
0677 return 0;
0678 }
0679
0680 int nfsd_nrpools(struct net *net)
0681 {
0682 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0683
0684 if (nn->nfsd_serv == NULL)
0685 return 0;
0686 else
0687 return nn->nfsd_serv->sv_nrpools;
0688 }
0689
0690 int nfsd_get_nrthreads(int n, int *nthreads, struct net *net)
0691 {
0692 int i = 0;
0693 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0694
0695 if (nn->nfsd_serv != NULL) {
0696 for (i = 0; i < nn->nfsd_serv->sv_nrpools && i < n; i++)
0697 nthreads[i] = nn->nfsd_serv->sv_pools[i].sp_nrthreads;
0698 }
0699
0700 return 0;
0701 }
0702
0703
0704
0705
0706
0707
0708 static void nfsd_noop(struct kref *ref)
0709 {
0710 }
0711
0712 void nfsd_put(struct net *net)
0713 {
0714 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0715
0716 if (kref_put(&nn->nfsd_serv->sv_refcnt, nfsd_noop)) {
0717 svc_xprt_destroy_all(nn->nfsd_serv, net);
0718 nfsd_last_thread(nn->nfsd_serv, net);
0719 svc_destroy(&nn->nfsd_serv->sv_refcnt);
0720 spin_lock(&nfsd_notifier_lock);
0721 nn->nfsd_serv = NULL;
0722 spin_unlock(&nfsd_notifier_lock);
0723 }
0724 }
0725
0726 int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
0727 {
0728 int i = 0;
0729 int tot = 0;
0730 int err = 0;
0731 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0732
0733 WARN_ON(!mutex_is_locked(&nfsd_mutex));
0734
0735 if (nn->nfsd_serv == NULL || n <= 0)
0736 return 0;
0737
0738 if (n > nn->nfsd_serv->sv_nrpools)
0739 n = nn->nfsd_serv->sv_nrpools;
0740
0741
0742 tot = 0;
0743 for (i = 0; i < n; i++) {
0744 nthreads[i] = min(nthreads[i], NFSD_MAXSERVS);
0745 tot += nthreads[i];
0746 }
0747 if (tot > NFSD_MAXSERVS) {
0748
0749 for (i = 0; i < n && tot > 0; i++) {
0750 int new = nthreads[i] * NFSD_MAXSERVS / tot;
0751 tot -= (nthreads[i] - new);
0752 nthreads[i] = new;
0753 }
0754 for (i = 0; i < n && tot > 0; i++) {
0755 nthreads[i]--;
0756 tot--;
0757 }
0758 }
0759
0760
0761
0762
0763
0764 if (nthreads[0] == 0)
0765 nthreads[0] = 1;
0766
0767
0768 svc_get(nn->nfsd_serv);
0769 for (i = 0; i < n; i++) {
0770 err = svc_set_num_threads(nn->nfsd_serv,
0771 &nn->nfsd_serv->sv_pools[i],
0772 nthreads[i]);
0773 if (err)
0774 break;
0775 }
0776 nfsd_put(net);
0777 return err;
0778 }
0779
0780
0781
0782
0783
0784
0785 int
0786 nfsd_svc(int nrservs, struct net *net, const struct cred *cred)
0787 {
0788 int error;
0789 bool nfsd_up_before;
0790 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0791
0792 mutex_lock(&nfsd_mutex);
0793 dprintk("nfsd: creating service\n");
0794
0795 nrservs = max(nrservs, 0);
0796 nrservs = min(nrservs, NFSD_MAXSERVS);
0797 error = 0;
0798
0799 if (nrservs == 0 && nn->nfsd_serv == NULL)
0800 goto out;
0801
0802 strlcpy(nn->nfsd_name, utsname()->nodename,
0803 sizeof(nn->nfsd_name));
0804
0805 error = nfsd_create_serv(net);
0806 if (error)
0807 goto out;
0808
0809 nfsd_up_before = nn->nfsd_net_up;
0810
0811 error = nfsd_startup_net(net, cred);
0812 if (error)
0813 goto out_put;
0814 error = svc_set_num_threads(nn->nfsd_serv, NULL, nrservs);
0815 if (error)
0816 goto out_shutdown;
0817 error = nn->nfsd_serv->sv_nrthreads;
0818 out_shutdown:
0819 if (error < 0 && !nfsd_up_before)
0820 nfsd_shutdown_net(net);
0821 out_put:
0822
0823 if (xchg(&nn->keep_active, 0))
0824 nfsd_put(net);
0825 nfsd_put(net);
0826 out:
0827 mutex_unlock(&nfsd_mutex);
0828 return error;
0829 }
0830
0831 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
0832 static bool
0833 nfsd_support_acl_version(int vers)
0834 {
0835 if (vers >= NFSD_ACL_MINVERS && vers < NFSD_ACL_NRVERS)
0836 return nfsd_acl_version[vers] != NULL;
0837 return false;
0838 }
0839
0840 static int
0841 nfsd_acl_rpcbind_set(struct net *net, const struct svc_program *progp,
0842 u32 version, int family, unsigned short proto,
0843 unsigned short port)
0844 {
0845 if (!nfsd_support_acl_version(version) ||
0846 !nfsd_vers(net_generic(net, nfsd_net_id), version, NFSD_TEST))
0847 return 0;
0848 return svc_generic_rpcbind_set(net, progp, version, family,
0849 proto, port);
0850 }
0851
0852 static __be32
0853 nfsd_acl_init_request(struct svc_rqst *rqstp,
0854 const struct svc_program *progp,
0855 struct svc_process_info *ret)
0856 {
0857 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
0858 int i;
0859
0860 if (likely(nfsd_support_acl_version(rqstp->rq_vers) &&
0861 nfsd_vers(nn, rqstp->rq_vers, NFSD_TEST)))
0862 return svc_generic_init_request(rqstp, progp, ret);
0863
0864 ret->mismatch.lovers = NFSD_ACL_NRVERS;
0865 for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) {
0866 if (nfsd_support_acl_version(rqstp->rq_vers) &&
0867 nfsd_vers(nn, i, NFSD_TEST)) {
0868 ret->mismatch.lovers = i;
0869 break;
0870 }
0871 }
0872 if (ret->mismatch.lovers == NFSD_ACL_NRVERS)
0873 return rpc_prog_unavail;
0874 ret->mismatch.hivers = NFSD_ACL_MINVERS;
0875 for (i = NFSD_ACL_NRVERS - 1; i >= NFSD_ACL_MINVERS; i--) {
0876 if (nfsd_support_acl_version(rqstp->rq_vers) &&
0877 nfsd_vers(nn, i, NFSD_TEST)) {
0878 ret->mismatch.hivers = i;
0879 break;
0880 }
0881 }
0882 return rpc_prog_mismatch;
0883 }
0884 #endif
0885
0886 static int
0887 nfsd_rpcbind_set(struct net *net, const struct svc_program *progp,
0888 u32 version, int family, unsigned short proto,
0889 unsigned short port)
0890 {
0891 if (!nfsd_vers(net_generic(net, nfsd_net_id), version, NFSD_TEST))
0892 return 0;
0893 return svc_generic_rpcbind_set(net, progp, version, family,
0894 proto, port);
0895 }
0896
0897 static __be32
0898 nfsd_init_request(struct svc_rqst *rqstp,
0899 const struct svc_program *progp,
0900 struct svc_process_info *ret)
0901 {
0902 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
0903 int i;
0904
0905 if (likely(nfsd_vers(nn, rqstp->rq_vers, NFSD_TEST)))
0906 return svc_generic_init_request(rqstp, progp, ret);
0907
0908 ret->mismatch.lovers = NFSD_NRVERS;
0909 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
0910 if (nfsd_vers(nn, i, NFSD_TEST)) {
0911 ret->mismatch.lovers = i;
0912 break;
0913 }
0914 }
0915 if (ret->mismatch.lovers == NFSD_NRVERS)
0916 return rpc_prog_unavail;
0917 ret->mismatch.hivers = NFSD_MINVERS;
0918 for (i = NFSD_NRVERS - 1; i >= NFSD_MINVERS; i--) {
0919 if (nfsd_vers(nn, i, NFSD_TEST)) {
0920 ret->mismatch.hivers = i;
0921 break;
0922 }
0923 }
0924 return rpc_prog_mismatch;
0925 }
0926
0927
0928
0929
0930 static int
0931 nfsd(void *vrqstp)
0932 {
0933 struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
0934 struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list);
0935 struct net *net = perm_sock->xpt_net;
0936 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0937 int err;
0938
0939
0940
0941
0942 if (unshare_fs_struct() < 0) {
0943 printk("Unable to start nfsd thread: out of memory\n");
0944 goto out;
0945 }
0946
0947 current->fs->umask = 0;
0948
0949
0950
0951
0952
0953 allow_signal(SIGKILL);
0954 allow_signal(SIGHUP);
0955 allow_signal(SIGINT);
0956 allow_signal(SIGQUIT);
0957
0958 atomic_inc(&nfsdstats.th_cnt);
0959
0960 set_freezable();
0961
0962
0963
0964
0965 for (;;) {
0966
0967 rqstp->rq_server->sv_maxconn = nn->max_connections;
0968
0969
0970
0971
0972
0973 while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
0974 ;
0975 if (err == -EINTR)
0976 break;
0977 validate_process_creds();
0978 svc_process(rqstp);
0979 validate_process_creds();
0980 }
0981
0982
0983 flush_signals(current);
0984
0985 atomic_dec(&nfsdstats.th_cnt);
0986
0987 out:
0988
0989
0990
0991 svc_get(nn->nfsd_serv);
0992
0993
0994 svc_exit_thread(rqstp);
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004 while (!svc_put_not_last(nn->nfsd_serv)) {
1005 if (mutex_trylock(&nfsd_mutex)) {
1006 nfsd_put(net);
1007 mutex_unlock(&nfsd_mutex);
1008 break;
1009 }
1010 msleep(20);
1011 }
1012
1013 return 0;
1014 }
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027 int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
1028 {
1029 const struct svc_procedure *proc = rqstp->rq_procinfo;
1030
1031
1032
1033
1034
1035 rqstp->rq_cachetype = proc->pc_cachetype;
1036
1037 svcxdr_init_decode(rqstp);
1038 if (!proc->pc_decode(rqstp, &rqstp->rq_arg_stream))
1039 goto out_decode_err;
1040
1041 switch (nfsd_cache_lookup(rqstp)) {
1042 case RC_DOIT:
1043 break;
1044 case RC_REPLY:
1045 goto out_cached_reply;
1046 case RC_DROPIT:
1047 goto out_dropit;
1048 }
1049
1050
1051
1052
1053
1054 svcxdr_init_encode(rqstp);
1055
1056 *statp = proc->pc_func(rqstp);
1057 if (*statp == rpc_drop_reply || test_bit(RQ_DROPME, &rqstp->rq_flags))
1058 goto out_update_drop;
1059
1060 if (!proc->pc_encode(rqstp, &rqstp->rq_res_stream))
1061 goto out_encode_err;
1062
1063 nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
1064 out_cached_reply:
1065 return 1;
1066
1067 out_decode_err:
1068 trace_nfsd_garbage_args_err(rqstp);
1069 *statp = rpc_garbage_args;
1070 return 1;
1071
1072 out_update_drop:
1073 nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
1074 out_dropit:
1075 return 0;
1076
1077 out_encode_err:
1078 trace_nfsd_cant_encode_err(rqstp);
1079 nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
1080 *statp = rpc_system_err;
1081 return 1;
1082 }
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093 bool nfssvc_decode_voidarg(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1094 {
1095 return true;
1096 }
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107 bool nfssvc_encode_voidres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1108 {
1109 return true;
1110 }
1111
1112 int nfsd_pool_stats_open(struct inode *inode, struct file *file)
1113 {
1114 int ret;
1115 struct nfsd_net *nn = net_generic(inode->i_sb->s_fs_info, nfsd_net_id);
1116
1117 mutex_lock(&nfsd_mutex);
1118 if (nn->nfsd_serv == NULL) {
1119 mutex_unlock(&nfsd_mutex);
1120 return -ENODEV;
1121 }
1122 svc_get(nn->nfsd_serv);
1123 ret = svc_pool_stats_open(nn->nfsd_serv, file);
1124 mutex_unlock(&nfsd_mutex);
1125 return ret;
1126 }
1127
1128 int nfsd_pool_stats_release(struct inode *inode, struct file *file)
1129 {
1130 int ret = seq_release(inode, file);
1131 struct net *net = inode->i_sb->s_fs_info;
1132
1133 mutex_lock(&nfsd_mutex);
1134 nfsd_put(net);
1135 mutex_unlock(&nfsd_mutex);
1136 return ret;
1137 }