0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/module.h>
0017 #include <linux/init.h>
0018 #include <linux/sysctl.h>
0019 #include <linux/moduleparam.h>
0020
0021 #include <linux/sched/signal.h>
0022 #include <linux/errno.h>
0023 #include <linux/in.h>
0024 #include <linux/uio.h>
0025 #include <linux/smp.h>
0026 #include <linux/mutex.h>
0027 #include <linux/kthread.h>
0028 #include <linux/freezer.h>
0029 #include <linux/inetdevice.h>
0030
0031 #include <linux/sunrpc/types.h>
0032 #include <linux/sunrpc/stats.h>
0033 #include <linux/sunrpc/clnt.h>
0034 #include <linux/sunrpc/svc.h>
0035 #include <linux/sunrpc/svcsock.h>
0036 #include <linux/sunrpc/svc_xprt.h>
0037 #include <net/ip.h>
0038 #include <net/addrconf.h>
0039 #include <net/ipv6.h>
0040 #include <linux/lockd/lockd.h>
0041 #include <linux/nfs.h>
0042
0043 #include "netns.h"
0044 #include "procfs.h"
0045
0046 #define NLMDBG_FACILITY NLMDBG_SVC
0047 #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE)
0048 #define ALLOWED_SIGS (sigmask(SIGKILL))
0049
0050 static struct svc_program nlmsvc_program;
0051
0052 const struct nlmsvc_binding *nlmsvc_ops;
0053 EXPORT_SYMBOL_GPL(nlmsvc_ops);
0054
0055 static DEFINE_MUTEX(nlmsvc_mutex);
0056 static unsigned int nlmsvc_users;
0057 static struct svc_serv *nlmsvc_serv;
0058 unsigned long nlmsvc_timeout;
0059
0060 unsigned int lockd_net_id;
0061
0062
0063
0064
0065
0066 static unsigned long nlm_grace_period;
0067 static unsigned long nlm_timeout = LOCKD_DFLT_TIMEO;
0068 static int nlm_udpport, nlm_tcpport;
0069
0070
0071 static unsigned int nlm_max_connections = 1024;
0072
0073
0074
0075
0076 static const unsigned long nlm_grace_period_min = 0;
0077 static const unsigned long nlm_grace_period_max = 240;
0078 static const unsigned long nlm_timeout_min = 3;
0079 static const unsigned long nlm_timeout_max = 20;
0080 static const int nlm_port_min = 0, nlm_port_max = 65535;
0081
0082 #ifdef CONFIG_SYSCTL
0083 static struct ctl_table_header * nlm_sysctl_table;
0084 #endif
0085
0086 static unsigned long get_lockd_grace_period(void)
0087 {
0088
0089 if (nlm_grace_period)
0090 return roundup(nlm_grace_period, nlm_timeout) * HZ;
0091 else
0092 return nlm_timeout * 5 * HZ;
0093 }
0094
0095 static void grace_ender(struct work_struct *grace)
0096 {
0097 struct delayed_work *dwork = to_delayed_work(grace);
0098 struct lockd_net *ln = container_of(dwork, struct lockd_net,
0099 grace_period_end);
0100
0101 locks_end_grace(&ln->lockd_manager);
0102 }
0103
0104 static void set_grace_period(struct net *net)
0105 {
0106 unsigned long grace_period = get_lockd_grace_period();
0107 struct lockd_net *ln = net_generic(net, lockd_net_id);
0108
0109 locks_start_grace(net, &ln->lockd_manager);
0110 cancel_delayed_work_sync(&ln->grace_period_end);
0111 schedule_delayed_work(&ln->grace_period_end, grace_period);
0112 }
0113
0114 static void restart_grace(void)
0115 {
0116 if (nlmsvc_ops) {
0117 struct net *net = &init_net;
0118 struct lockd_net *ln = net_generic(net, lockd_net_id);
0119
0120 cancel_delayed_work_sync(&ln->grace_period_end);
0121 locks_end_grace(&ln->lockd_manager);
0122 nlmsvc_invalidate_all();
0123 set_grace_period(net);
0124 }
0125 }
0126
0127
0128
0129
0130 static int
0131 lockd(void *vrqstp)
0132 {
0133 int err = 0;
0134 struct svc_rqst *rqstp = vrqstp;
0135 struct net *net = &init_net;
0136 struct lockd_net *ln = net_generic(net, lockd_net_id);
0137
0138
0139 set_freezable();
0140
0141
0142 allow_signal(SIGKILL);
0143
0144 dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n");
0145
0146
0147
0148
0149
0150 while (!kthread_should_stop()) {
0151 long timeout = MAX_SCHEDULE_TIMEOUT;
0152 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
0153
0154
0155 rqstp->rq_server->sv_maxconn = nlm_max_connections;
0156
0157 if (signalled()) {
0158 flush_signals(current);
0159 restart_grace();
0160 continue;
0161 }
0162
0163 timeout = nlmsvc_retry_blocked();
0164
0165
0166
0167
0168
0169 err = svc_recv(rqstp, timeout);
0170 if (err == -EAGAIN || err == -EINTR)
0171 continue;
0172 dprintk("lockd: request from %s\n",
0173 svc_print_addr(rqstp, buf, sizeof(buf)));
0174
0175 svc_process(rqstp);
0176 }
0177 flush_signals(current);
0178 if (nlmsvc_ops)
0179 nlmsvc_invalidate_all();
0180 nlm_shutdown_hosts();
0181 cancel_delayed_work_sync(&ln->grace_period_end);
0182 locks_end_grace(&ln->lockd_manager);
0183
0184 dprintk("lockd_down: service stopped\n");
0185
0186 svc_exit_thread(rqstp);
0187 return 0;
0188 }
0189
0190 static int create_lockd_listener(struct svc_serv *serv, const char *name,
0191 struct net *net, const int family,
0192 const unsigned short port,
0193 const struct cred *cred)
0194 {
0195 struct svc_xprt *xprt;
0196
0197 xprt = svc_find_xprt(serv, name, net, family, 0);
0198 if (xprt == NULL)
0199 return svc_xprt_create(serv, name, net, family, port,
0200 SVC_SOCK_DEFAULTS, cred);
0201 svc_xprt_put(xprt);
0202 return 0;
0203 }
0204
0205 static int create_lockd_family(struct svc_serv *serv, struct net *net,
0206 const int family, const struct cred *cred)
0207 {
0208 int err;
0209
0210 err = create_lockd_listener(serv, "udp", net, family, nlm_udpport,
0211 cred);
0212 if (err < 0)
0213 return err;
0214
0215 return create_lockd_listener(serv, "tcp", net, family, nlm_tcpport,
0216 cred);
0217 }
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229 static int make_socks(struct svc_serv *serv, struct net *net,
0230 const struct cred *cred)
0231 {
0232 static int warned;
0233 int err;
0234
0235 err = create_lockd_family(serv, net, PF_INET, cred);
0236 if (err < 0)
0237 goto out_err;
0238
0239 err = create_lockd_family(serv, net, PF_INET6, cred);
0240 if (err < 0 && err != -EAFNOSUPPORT)
0241 goto out_err;
0242
0243 warned = 0;
0244 return 0;
0245
0246 out_err:
0247 if (warned++ == 0)
0248 printk(KERN_WARNING
0249 "lockd_up: makesock failed, error=%d\n", err);
0250 svc_xprt_destroy_all(serv, net);
0251 svc_rpcb_cleanup(serv, net);
0252 return err;
0253 }
0254
0255 static int lockd_up_net(struct svc_serv *serv, struct net *net,
0256 const struct cred *cred)
0257 {
0258 struct lockd_net *ln = net_generic(net, lockd_net_id);
0259 int error;
0260
0261 if (ln->nlmsvc_users++)
0262 return 0;
0263
0264 error = svc_bind(serv, net);
0265 if (error)
0266 goto err_bind;
0267
0268 error = make_socks(serv, net, cred);
0269 if (error < 0)
0270 goto err_bind;
0271 set_grace_period(net);
0272 dprintk("%s: per-net data created; net=%x\n", __func__, net->ns.inum);
0273 return 0;
0274
0275 err_bind:
0276 ln->nlmsvc_users--;
0277 return error;
0278 }
0279
0280 static void lockd_down_net(struct svc_serv *serv, struct net *net)
0281 {
0282 struct lockd_net *ln = net_generic(net, lockd_net_id);
0283
0284 if (ln->nlmsvc_users) {
0285 if (--ln->nlmsvc_users == 0) {
0286 nlm_shutdown_hosts_net(net);
0287 cancel_delayed_work_sync(&ln->grace_period_end);
0288 locks_end_grace(&ln->lockd_manager);
0289 svc_xprt_destroy_all(serv, net);
0290 svc_rpcb_cleanup(serv, net);
0291 }
0292 } else {
0293 pr_err("%s: no users! net=%x\n",
0294 __func__, net->ns.inum);
0295 BUG();
0296 }
0297 }
0298
0299 static int lockd_inetaddr_event(struct notifier_block *this,
0300 unsigned long event, void *ptr)
0301 {
0302 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
0303 struct sockaddr_in sin;
0304
0305 if (event != NETDEV_DOWN)
0306 goto out;
0307
0308 if (nlmsvc_serv) {
0309 dprintk("lockd_inetaddr_event: removed %pI4\n",
0310 &ifa->ifa_local);
0311 sin.sin_family = AF_INET;
0312 sin.sin_addr.s_addr = ifa->ifa_local;
0313 svc_age_temp_xprts_now(nlmsvc_serv, (struct sockaddr *)&sin);
0314 }
0315
0316 out:
0317 return NOTIFY_DONE;
0318 }
0319
0320 static struct notifier_block lockd_inetaddr_notifier = {
0321 .notifier_call = lockd_inetaddr_event,
0322 };
0323
0324 #if IS_ENABLED(CONFIG_IPV6)
0325 static int lockd_inet6addr_event(struct notifier_block *this,
0326 unsigned long event, void *ptr)
0327 {
0328 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
0329 struct sockaddr_in6 sin6;
0330
0331 if (event != NETDEV_DOWN)
0332 goto out;
0333
0334 if (nlmsvc_serv) {
0335 dprintk("lockd_inet6addr_event: removed %pI6\n", &ifa->addr);
0336 sin6.sin6_family = AF_INET6;
0337 sin6.sin6_addr = ifa->addr;
0338 if (ipv6_addr_type(&sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
0339 sin6.sin6_scope_id = ifa->idev->dev->ifindex;
0340 svc_age_temp_xprts_now(nlmsvc_serv, (struct sockaddr *)&sin6);
0341 }
0342
0343 out:
0344 return NOTIFY_DONE;
0345 }
0346
0347 static struct notifier_block lockd_inet6addr_notifier = {
0348 .notifier_call = lockd_inet6addr_event,
0349 };
0350 #endif
0351
0352 static int lockd_get(void)
0353 {
0354 struct svc_serv *serv;
0355 int error;
0356
0357 if (nlmsvc_serv) {
0358 svc_get(nlmsvc_serv);
0359 nlmsvc_users++;
0360 return 0;
0361 }
0362
0363
0364
0365
0366
0367 if (nlmsvc_users)
0368 printk(KERN_WARNING
0369 "lockd_up: no pid, %d users??\n", nlmsvc_users);
0370
0371 if (!nlm_timeout)
0372 nlm_timeout = LOCKD_DFLT_TIMEO;
0373 nlmsvc_timeout = nlm_timeout * HZ;
0374
0375 serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, lockd);
0376 if (!serv) {
0377 printk(KERN_WARNING "lockd_up: create service failed\n");
0378 return -ENOMEM;
0379 }
0380
0381 serv->sv_maxconn = nlm_max_connections;
0382 error = svc_set_num_threads(serv, NULL, 1);
0383
0384 svc_put(serv);
0385 if (error < 0)
0386 return error;
0387
0388 nlmsvc_serv = serv;
0389 register_inetaddr_notifier(&lockd_inetaddr_notifier);
0390 #if IS_ENABLED(CONFIG_IPV6)
0391 register_inet6addr_notifier(&lockd_inet6addr_notifier);
0392 #endif
0393 dprintk("lockd_up: service created\n");
0394 nlmsvc_users++;
0395 return 0;
0396 }
0397
0398 static void lockd_put(void)
0399 {
0400 if (WARN(nlmsvc_users <= 0, "lockd_down: no users!\n"))
0401 return;
0402 if (--nlmsvc_users)
0403 return;
0404
0405 unregister_inetaddr_notifier(&lockd_inetaddr_notifier);
0406 #if IS_ENABLED(CONFIG_IPV6)
0407 unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
0408 #endif
0409
0410 svc_set_num_threads(nlmsvc_serv, NULL, 0);
0411 nlmsvc_serv = NULL;
0412 dprintk("lockd_down: service destroyed\n");
0413 }
0414
0415
0416
0417
0418 int lockd_up(struct net *net, const struct cred *cred)
0419 {
0420 int error;
0421
0422 mutex_lock(&nlmsvc_mutex);
0423
0424 error = lockd_get();
0425 if (error)
0426 goto err;
0427
0428 error = lockd_up_net(nlmsvc_serv, net, cred);
0429 if (error < 0) {
0430 lockd_put();
0431 goto err;
0432 }
0433
0434 err:
0435 mutex_unlock(&nlmsvc_mutex);
0436 return error;
0437 }
0438 EXPORT_SYMBOL_GPL(lockd_up);
0439
0440
0441
0442
0443 void
0444 lockd_down(struct net *net)
0445 {
0446 mutex_lock(&nlmsvc_mutex);
0447 lockd_down_net(nlmsvc_serv, net);
0448 lockd_put();
0449 mutex_unlock(&nlmsvc_mutex);
0450 }
0451 EXPORT_SYMBOL_GPL(lockd_down);
0452
0453 #ifdef CONFIG_SYSCTL
0454
0455
0456
0457
0458
0459 static struct ctl_table nlm_sysctls[] = {
0460 {
0461 .procname = "nlm_grace_period",
0462 .data = &nlm_grace_period,
0463 .maxlen = sizeof(unsigned long),
0464 .mode = 0644,
0465 .proc_handler = proc_doulongvec_minmax,
0466 .extra1 = (unsigned long *) &nlm_grace_period_min,
0467 .extra2 = (unsigned long *) &nlm_grace_period_max,
0468 },
0469 {
0470 .procname = "nlm_timeout",
0471 .data = &nlm_timeout,
0472 .maxlen = sizeof(unsigned long),
0473 .mode = 0644,
0474 .proc_handler = proc_doulongvec_minmax,
0475 .extra1 = (unsigned long *) &nlm_timeout_min,
0476 .extra2 = (unsigned long *) &nlm_timeout_max,
0477 },
0478 {
0479 .procname = "nlm_udpport",
0480 .data = &nlm_udpport,
0481 .maxlen = sizeof(int),
0482 .mode = 0644,
0483 .proc_handler = proc_dointvec_minmax,
0484 .extra1 = (int *) &nlm_port_min,
0485 .extra2 = (int *) &nlm_port_max,
0486 },
0487 {
0488 .procname = "nlm_tcpport",
0489 .data = &nlm_tcpport,
0490 .maxlen = sizeof(int),
0491 .mode = 0644,
0492 .proc_handler = proc_dointvec_minmax,
0493 .extra1 = (int *) &nlm_port_min,
0494 .extra2 = (int *) &nlm_port_max,
0495 },
0496 {
0497 .procname = "nsm_use_hostnames",
0498 .data = &nsm_use_hostnames,
0499 .maxlen = sizeof(int),
0500 .mode = 0644,
0501 .proc_handler = proc_dobool,
0502 },
0503 {
0504 .procname = "nsm_local_state",
0505 .data = &nsm_local_state,
0506 .maxlen = sizeof(int),
0507 .mode = 0644,
0508 .proc_handler = proc_dointvec,
0509 },
0510 { }
0511 };
0512
0513 static struct ctl_table nlm_sysctl_dir[] = {
0514 {
0515 .procname = "nfs",
0516 .mode = 0555,
0517 .child = nlm_sysctls,
0518 },
0519 { }
0520 };
0521
0522 static struct ctl_table nlm_sysctl_root[] = {
0523 {
0524 .procname = "fs",
0525 .mode = 0555,
0526 .child = nlm_sysctl_dir,
0527 },
0528 { }
0529 };
0530
0531 #endif
0532
0533
0534
0535
0536
0537 #define param_set_min_max(name, type, which_strtol, min, max) \
0538 static int param_set_##name(const char *val, const struct kernel_param *kp) \
0539 { \
0540 char *endp; \
0541 __typeof__(type) num = which_strtol(val, &endp, 0); \
0542 if (endp == val || *endp || num < (min) || num > (max)) \
0543 return -EINVAL; \
0544 *((type *) kp->arg) = num; \
0545 return 0; \
0546 }
0547
0548 static inline int is_callback(u32 proc)
0549 {
0550 return proc == NLMPROC_GRANTED
0551 || proc == NLMPROC_GRANTED_MSG
0552 || proc == NLMPROC_TEST_RES
0553 || proc == NLMPROC_LOCK_RES
0554 || proc == NLMPROC_CANCEL_RES
0555 || proc == NLMPROC_UNLOCK_RES
0556 || proc == NLMPROC_NSM_NOTIFY;
0557 }
0558
0559
0560 static int lockd_authenticate(struct svc_rqst *rqstp)
0561 {
0562 rqstp->rq_client = NULL;
0563 switch (rqstp->rq_authop->flavour) {
0564 case RPC_AUTH_NULL:
0565 case RPC_AUTH_UNIX:
0566 rqstp->rq_auth_stat = rpc_auth_ok;
0567 if (rqstp->rq_proc == 0)
0568 return SVC_OK;
0569 if (is_callback(rqstp->rq_proc)) {
0570
0571
0572
0573 return SVC_OK;
0574 }
0575 return svc_set_client(rqstp);
0576 }
0577 rqstp->rq_auth_stat = rpc_autherr_badcred;
0578 return SVC_DENIED;
0579 }
0580
0581
0582 param_set_min_max(port, int, simple_strtol, 0, 65535)
0583 param_set_min_max(grace_period, unsigned long, simple_strtoul,
0584 nlm_grace_period_min, nlm_grace_period_max)
0585 param_set_min_max(timeout, unsigned long, simple_strtoul,
0586 nlm_timeout_min, nlm_timeout_max)
0587
0588 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
0589 MODULE_DESCRIPTION("NFS file locking service version " LOCKD_VERSION ".");
0590 MODULE_LICENSE("GPL");
0591
0592 module_param_call(nlm_grace_period, param_set_grace_period, param_get_ulong,
0593 &nlm_grace_period, 0644);
0594 module_param_call(nlm_timeout, param_set_timeout, param_get_ulong,
0595 &nlm_timeout, 0644);
0596 module_param_call(nlm_udpport, param_set_port, param_get_int,
0597 &nlm_udpport, 0644);
0598 module_param_call(nlm_tcpport, param_set_port, param_get_int,
0599 &nlm_tcpport, 0644);
0600 module_param(nsm_use_hostnames, bool, 0644);
0601 module_param(nlm_max_connections, uint, 0644);
0602
0603 static int lockd_init_net(struct net *net)
0604 {
0605 struct lockd_net *ln = net_generic(net, lockd_net_id);
0606
0607 INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
0608 INIT_LIST_HEAD(&ln->lockd_manager.list);
0609 ln->lockd_manager.block_opens = false;
0610 INIT_LIST_HEAD(&ln->nsm_handles);
0611 return 0;
0612 }
0613
0614 static void lockd_exit_net(struct net *net)
0615 {
0616 struct lockd_net *ln = net_generic(net, lockd_net_id);
0617
0618 WARN_ONCE(!list_empty(&ln->lockd_manager.list),
0619 "net %x %s: lockd_manager.list is not empty\n",
0620 net->ns.inum, __func__);
0621 WARN_ONCE(!list_empty(&ln->nsm_handles),
0622 "net %x %s: nsm_handles list is not empty\n",
0623 net->ns.inum, __func__);
0624 WARN_ONCE(delayed_work_pending(&ln->grace_period_end),
0625 "net %x %s: grace_period_end was not cancelled\n",
0626 net->ns.inum, __func__);
0627 }
0628
0629 static struct pernet_operations lockd_net_ops = {
0630 .init = lockd_init_net,
0631 .exit = lockd_exit_net,
0632 .id = &lockd_net_id,
0633 .size = sizeof(struct lockd_net),
0634 };
0635
0636
0637
0638
0639
0640
0641 static int __init init_nlm(void)
0642 {
0643 int err;
0644
0645 #ifdef CONFIG_SYSCTL
0646 err = -ENOMEM;
0647 nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root);
0648 if (nlm_sysctl_table == NULL)
0649 goto err_sysctl;
0650 #endif
0651 err = register_pernet_subsys(&lockd_net_ops);
0652 if (err)
0653 goto err_pernet;
0654
0655 err = lockd_create_procfs();
0656 if (err)
0657 goto err_procfs;
0658
0659 return 0;
0660
0661 err_procfs:
0662 unregister_pernet_subsys(&lockd_net_ops);
0663 err_pernet:
0664 #ifdef CONFIG_SYSCTL
0665 unregister_sysctl_table(nlm_sysctl_table);
0666 err_sysctl:
0667 #endif
0668 return err;
0669 }
0670
0671 static void __exit exit_nlm(void)
0672 {
0673
0674 nlm_shutdown_hosts();
0675 lockd_remove_procfs();
0676 unregister_pernet_subsys(&lockd_net_ops);
0677 #ifdef CONFIG_SYSCTL
0678 unregister_sysctl_table(nlm_sysctl_table);
0679 #endif
0680 }
0681
0682 module_init(init_nlm);
0683 module_exit(exit_nlm);
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694 static int nlmsvc_dispatch(struct svc_rqst *rqstp, __be32 *statp)
0695 {
0696 const struct svc_procedure *procp = rqstp->rq_procinfo;
0697
0698 svcxdr_init_decode(rqstp);
0699 if (!procp->pc_decode(rqstp, &rqstp->rq_arg_stream))
0700 goto out_decode_err;
0701
0702 *statp = procp->pc_func(rqstp);
0703 if (*statp == rpc_drop_reply)
0704 return 0;
0705 if (*statp != rpc_success)
0706 return 1;
0707
0708 svcxdr_init_encode(rqstp);
0709 if (!procp->pc_encode(rqstp, &rqstp->rq_res_stream))
0710 goto out_encode_err;
0711
0712 return 1;
0713
0714 out_decode_err:
0715 *statp = rpc_garbage_args;
0716 return 1;
0717
0718 out_encode_err:
0719 *statp = rpc_system_err;
0720 return 1;
0721 }
0722
0723
0724
0725
0726 static unsigned int nlmsvc_version1_count[17];
0727 static const struct svc_version nlmsvc_version1 = {
0728 .vs_vers = 1,
0729 .vs_nproc = 17,
0730 .vs_proc = nlmsvc_procedures,
0731 .vs_count = nlmsvc_version1_count,
0732 .vs_dispatch = nlmsvc_dispatch,
0733 .vs_xdrsize = NLMSVC_XDRSIZE,
0734 };
0735 static unsigned int nlmsvc_version3_count[24];
0736 static const struct svc_version nlmsvc_version3 = {
0737 .vs_vers = 3,
0738 .vs_nproc = 24,
0739 .vs_proc = nlmsvc_procedures,
0740 .vs_count = nlmsvc_version3_count,
0741 .vs_dispatch = nlmsvc_dispatch,
0742 .vs_xdrsize = NLMSVC_XDRSIZE,
0743 };
0744 #ifdef CONFIG_LOCKD_V4
0745 static unsigned int nlmsvc_version4_count[24];
0746 static const struct svc_version nlmsvc_version4 = {
0747 .vs_vers = 4,
0748 .vs_nproc = 24,
0749 .vs_proc = nlmsvc_procedures4,
0750 .vs_count = nlmsvc_version4_count,
0751 .vs_dispatch = nlmsvc_dispatch,
0752 .vs_xdrsize = NLMSVC_XDRSIZE,
0753 };
0754 #endif
0755 static const struct svc_version *nlmsvc_version[] = {
0756 [1] = &nlmsvc_version1,
0757 [3] = &nlmsvc_version3,
0758 #ifdef CONFIG_LOCKD_V4
0759 [4] = &nlmsvc_version4,
0760 #endif
0761 };
0762
0763 static struct svc_stat nlmsvc_stats;
0764
0765 #define NLM_NRVERS ARRAY_SIZE(nlmsvc_version)
0766 static struct svc_program nlmsvc_program = {
0767 .pg_prog = NLM_PROGRAM,
0768 .pg_nvers = NLM_NRVERS,
0769 .pg_vers = nlmsvc_version,
0770 .pg_name = "lockd",
0771 .pg_class = "nfsd",
0772 .pg_stats = &nlmsvc_stats,
0773 .pg_authenticate = &lockd_authenticate,
0774 .pg_init_request = svc_generic_init_request,
0775 .pg_rpcbind_set = svc_generic_rpcbind_set,
0776 };