1
2
3
4
5
6
7
8#include <linux/slab.h>
9#include <linux/namei.h>
10#include <linux/ctype.h>
11#include <linux/fs_context.h>
12
13#include <linux/sunrpc/svcsock.h>
14#include <linux/lockd/lockd.h>
15#include <linux/sunrpc/addr.h>
16#include <linux/sunrpc/gss_api.h>
17#include <linux/sunrpc/gss_krb5_enctypes.h>
18#include <linux/sunrpc/rpc_pipe_fs.h>
19#include <linux/module.h>
20#include <linux/fsnotify.h>
21
22#include "idmap.h"
23#include "nfsd.h"
24#include "cache.h"
25#include "state.h"
26#include "netns.h"
27#include "pnfs.h"
28
29
30
31
32enum {
33 NFSD_Root = 1,
34 NFSD_List,
35 NFSD_Export_Stats,
36 NFSD_Export_features,
37 NFSD_Fh,
38 NFSD_FO_UnlockIP,
39 NFSD_FO_UnlockFS,
40 NFSD_Threads,
41 NFSD_Pool_Threads,
42 NFSD_Pool_Stats,
43 NFSD_Reply_Cache_Stats,
44 NFSD_Versions,
45 NFSD_Ports,
46 NFSD_MaxBlkSize,
47 NFSD_MaxConnections,
48 NFSD_SupportedEnctypes,
49
50
51
52
53#ifdef CONFIG_NFSD_V4
54 NFSD_Leasetime,
55 NFSD_Gracetime,
56 NFSD_RecoveryDir,
57 NFSD_V4EndGrace,
58#endif
59 NFSD_MaxReserved
60};
61
62
63
64
65static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
66static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size);
67static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size);
68static ssize_t write_threads(struct file *file, char *buf, size_t size);
69static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
70static ssize_t write_versions(struct file *file, char *buf, size_t size);
71static ssize_t write_ports(struct file *file, char *buf, size_t size);
72static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
73static ssize_t write_maxconn(struct file *file, char *buf, size_t size);
74#ifdef CONFIG_NFSD_V4
75static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
76static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
77static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
78static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size);
79#endif
80
81static ssize_t (*const write_op[])(struct file *, char *, size_t) = {
82 [NFSD_Fh] = write_filehandle,
83 [NFSD_FO_UnlockIP] = write_unlock_ip,
84 [NFSD_FO_UnlockFS] = write_unlock_fs,
85 [NFSD_Threads] = write_threads,
86 [NFSD_Pool_Threads] = write_pool_threads,
87 [NFSD_Versions] = write_versions,
88 [NFSD_Ports] = write_ports,
89 [NFSD_MaxBlkSize] = write_maxblksize,
90 [NFSD_MaxConnections] = write_maxconn,
91#ifdef CONFIG_NFSD_V4
92 [NFSD_Leasetime] = write_leasetime,
93 [NFSD_Gracetime] = write_gracetime,
94 [NFSD_RecoveryDir] = write_recoverydir,
95 [NFSD_V4EndGrace] = write_v4_end_grace,
96#endif
97};
98
99static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
100{
101 ino_t ino = file_inode(file)->i_ino;
102 char *data;
103 ssize_t rv;
104
105 if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
106 return -EINVAL;
107
108 data = simple_transaction_get(file, buf, size);
109 if (IS_ERR(data))
110 return PTR_ERR(data);
111
112 rv = write_op[ino](file, data, size);
113 if (rv >= 0) {
114 simple_transaction_set(file, rv);
115 rv = size;
116 }
117 return rv;
118}
119
120static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
121{
122 if (! file->private_data) {
123
124
125
126
127 ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos);
128 if (rv < 0)
129 return rv;
130 }
131 return simple_transaction_read(file, buf, size, pos);
132}
133
134static const struct file_operations transaction_ops = {
135 .write = nfsctl_transaction_write,
136 .read = nfsctl_transaction_read,
137 .release = simple_transaction_release,
138 .llseek = default_llseek,
139};
140
141static int exports_net_open(struct net *net, struct file *file)
142{
143 int err;
144 struct seq_file *seq;
145 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
146
147 err = seq_open(file, &nfs_exports_op);
148 if (err)
149 return err;
150
151 seq = file->private_data;
152 seq->private = nn->svc_export_cache;
153 return 0;
154}
155
156static int exports_proc_open(struct inode *inode, struct file *file)
157{
158 return exports_net_open(current->nsproxy->net_ns, file);
159}
160
161static const struct proc_ops exports_proc_ops = {
162 .proc_open = exports_proc_open,
163 .proc_read = seq_read,
164 .proc_lseek = seq_lseek,
165 .proc_release = seq_release,
166};
167
168static int exports_nfsd_open(struct inode *inode, struct file *file)
169{
170 return exports_net_open(inode->i_sb->s_fs_info, file);
171}
172
173static const struct file_operations exports_nfsd_operations = {
174 .open = exports_nfsd_open,
175 .read = seq_read,
176 .llseek = seq_lseek,
177 .release = seq_release,
178};
179
180static int export_features_show(struct seq_file *m, void *v)
181{
182 seq_printf(m, "0x%x 0x%x\n", NFSEXP_ALLFLAGS, NFSEXP_SECINFO_FLAGS);
183 return 0;
184}
185
186static int export_features_open(struct inode *inode, struct file *file)
187{
188 return single_open(file, export_features_show, NULL);
189}
190
191static const struct file_operations export_features_operations = {
192 .open = export_features_open,
193 .read = seq_read,
194 .llseek = seq_lseek,
195 .release = single_release,
196};
197
198#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
199static int supported_enctypes_show(struct seq_file *m, void *v)
200{
201 seq_printf(m, KRB5_SUPPORTED_ENCTYPES);
202 return 0;
203}
204
205static int supported_enctypes_open(struct inode *inode, struct file *file)
206{
207 return single_open(file, supported_enctypes_show, NULL);
208}
209
210static const struct file_operations supported_enctypes_ops = {
211 .open = supported_enctypes_open,
212 .read = seq_read,
213 .llseek = seq_lseek,
214 .release = single_release,
215};
216#endif
217
218static const struct file_operations pool_stats_operations = {
219 .open = nfsd_pool_stats_open,
220 .read = seq_read,
221 .llseek = seq_lseek,
222 .release = nfsd_pool_stats_release,
223};
224
225static const struct file_operations reply_cache_stats_operations = {
226 .open = nfsd_reply_cache_stats_open,
227 .read = seq_read,
228 .llseek = seq_lseek,
229 .release = single_release,
230};
231
232
233
234
235
236
237static inline struct net *netns(struct file *file)
238{
239 return file_inode(file)->i_sb->s_fs_info;
240}
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
257{
258 struct sockaddr_storage address;
259 struct sockaddr *sap = (struct sockaddr *)&address;
260 size_t salen = sizeof(address);
261 char *fo_path;
262 struct net *net = netns(file);
263
264
265 if (size == 0)
266 return -EINVAL;
267
268 if (buf[size-1] != '\n')
269 return -EINVAL;
270
271 fo_path = buf;
272 if (qword_get(&buf, fo_path, size) < 0)
273 return -EINVAL;
274
275 if (rpc_pton(net, fo_path, size, sap, salen) == 0)
276 return -EINVAL;
277
278 return nlmsvc_unlock_all_by_ip(sap);
279}
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size)
296{
297 struct path path;
298 char *fo_path;
299 int error;
300
301
302 if (size == 0)
303 return -EINVAL;
304
305 if (buf[size-1] != '\n')
306 return -EINVAL;
307
308 fo_path = buf;
309 if (qword_get(&buf, fo_path, size) < 0)
310 return -EINVAL;
311
312 error = kern_path(fo_path, 0, &path);
313 if (error)
314 return error;
315
316
317
318
319
320
321
322
323
324
325 error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb);
326
327 path_put(&path);
328 return error;
329}
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
353{
354 char *dname, *path;
355 int maxsize;
356 char *mesg = buf;
357 int len;
358 struct auth_domain *dom;
359 struct knfsd_fh fh;
360
361 if (size == 0)
362 return -EINVAL;
363
364 if (buf[size-1] != '\n')
365 return -EINVAL;
366 buf[size-1] = 0;
367
368 dname = mesg;
369 len = qword_get(&mesg, dname, size);
370 if (len <= 0)
371 return -EINVAL;
372
373 path = dname+len+1;
374 len = qword_get(&mesg, path, size);
375 if (len <= 0)
376 return -EINVAL;
377
378 len = get_int(&mesg, &maxsize);
379 if (len)
380 return len;
381
382 if (maxsize < NFS_FHSIZE)
383 return -EINVAL;
384 maxsize = min(maxsize, NFS3_FHSIZE);
385
386 if (qword_get(&mesg, mesg, size)>0)
387 return -EINVAL;
388
389
390 dom = unix_domain_find(dname);
391 if (!dom)
392 return -ENOMEM;
393
394 len = exp_rootfh(netns(file), dom, path, &fh, maxsize);
395 auth_domain_put(dom);
396 if (len)
397 return len;
398
399 mesg = buf;
400 len = SIMPLE_TRANSACTION_LIMIT;
401 qword_addhex(&mesg, &len, (char*)&fh.fh_base, fh.fh_size);
402 mesg[-1] = '\n';
403 return mesg - buf;
404}
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434static ssize_t write_threads(struct file *file, char *buf, size_t size)
435{
436 char *mesg = buf;
437 int rv;
438 struct net *net = netns(file);
439
440 if (size > 0) {
441 int newthreads;
442 rv = get_int(&mesg, &newthreads);
443 if (rv)
444 return rv;
445 if (newthreads < 0)
446 return -EINVAL;
447 rv = nfsd_svc(newthreads, net, file->f_cred);
448 if (rv < 0)
449 return rv;
450 } else
451 rv = nfsd_nrthreads(net);
452
453 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv);
454}
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
479{
480
481
482
483 char *mesg = buf;
484 int i;
485 int rv;
486 int len;
487 int npools;
488 int *nthreads;
489 struct net *net = netns(file);
490
491 mutex_lock(&nfsd_mutex);
492 npools = nfsd_nrpools(net);
493 if (npools == 0) {
494
495
496
497
498
499 mutex_unlock(&nfsd_mutex);
500 strcpy(buf, "0\n");
501 return strlen(buf);
502 }
503
504 nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL);
505 rv = -ENOMEM;
506 if (nthreads == NULL)
507 goto out_free;
508
509 if (size > 0) {
510 for (i = 0; i < npools; i++) {
511 rv = get_int(&mesg, &nthreads[i]);
512 if (rv == -ENOENT)
513 break;
514 if (rv)
515 goto out_free;
516 rv = -EINVAL;
517 if (nthreads[i] < 0)
518 goto out_free;
519 }
520 rv = nfsd_set_nrthreads(i, nthreads, net);
521 if (rv)
522 goto out_free;
523 }
524
525 rv = nfsd_get_nrthreads(npools, nthreads, net);
526 if (rv)
527 goto out_free;
528
529 mesg = buf;
530 size = SIMPLE_TRANSACTION_LIMIT;
531 for (i = 0; i < npools && size > 0; i++) {
532 snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' '));
533 len = strlen(mesg);
534 size -= len;
535 mesg += len;
536 }
537 rv = mesg - buf;
538out_free:
539 kfree(nthreads);
540 mutex_unlock(&nfsd_mutex);
541 return rv;
542}
543
544static ssize_t
545nfsd_print_version_support(struct nfsd_net *nn, char *buf, int remaining,
546 const char *sep, unsigned vers, int minor)
547{
548 const char *format = minor < 0 ? "%s%c%u" : "%s%c%u.%u";
549 bool supported = !!nfsd_vers(nn, vers, NFSD_TEST);
550
551 if (vers == 4 && minor >= 0 &&
552 !nfsd_minorversion(nn, minor, NFSD_TEST))
553 supported = false;
554 if (minor == 0 && supported)
555
556
557
558
559
560 return 0;
561 return snprintf(buf, remaining, format, sep,
562 supported ? '+' : '-', vers, minor);
563}
564
565static ssize_t __write_versions(struct file *file, char *buf, size_t size)
566{
567 char *mesg = buf;
568 char *vers, *minorp, sign;
569 int len, num, remaining;
570 ssize_t tlen = 0;
571 char *sep;
572 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
573
574 if (size>0) {
575 if (nn->nfsd_serv)
576
577
578
579
580 return -EBUSY;
581 if (buf[size-1] != '\n')
582 return -EINVAL;
583 buf[size-1] = 0;
584
585 vers = mesg;
586 len = qword_get(&mesg, vers, size);
587 if (len <= 0) return -EINVAL;
588 do {
589 enum vers_op cmd;
590 unsigned minor;
591 sign = *vers;
592 if (sign == '+' || sign == '-')
593 num = simple_strtol((vers+1), &minorp, 0);
594 else
595 num = simple_strtol(vers, &minorp, 0);
596 if (*minorp == '.') {
597 if (num != 4)
598 return -EINVAL;
599 if (kstrtouint(minorp+1, 0, &minor) < 0)
600 return -EINVAL;
601 }
602
603 cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET;
604 switch(num) {
605 case 2:
606 case 3:
607 nfsd_vers(nn, num, cmd);
608 break;
609 case 4:
610 if (*minorp == '.') {
611 if (nfsd_minorversion(nn, minor, cmd) < 0)
612 return -EINVAL;
613 } else if ((cmd == NFSD_SET) != nfsd_vers(nn, num, NFSD_TEST)) {
614
615
616
617
618
619 minor = 0;
620 while (nfsd_minorversion(nn, minor, cmd) >= 0)
621 minor++;
622 }
623 break;
624 default:
625 return -EINVAL;
626 }
627 vers += len + 1;
628 } while ((len = qword_get(&mesg, vers, size)) > 0);
629
630
631
632 nfsd_reset_versions(nn);
633 }
634
635
636 len = 0;
637 sep = "";
638 remaining = SIMPLE_TRANSACTION_LIMIT;
639 for (num=2 ; num <= 4 ; num++) {
640 int minor;
641 if (!nfsd_vers(nn, num, NFSD_AVAIL))
642 continue;
643
644 minor = -1;
645 do {
646 len = nfsd_print_version_support(nn, buf, remaining,
647 sep, num, minor);
648 if (len >= remaining)
649 goto out;
650 remaining -= len;
651 buf += len;
652 tlen += len;
653 minor++;
654 if (len)
655 sep = " ";
656 } while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION);
657 }
658out:
659 len = snprintf(buf, remaining, "\n");
660 if (len >= remaining)
661 return -EINVAL;
662 return tlen + len;
663}
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697static ssize_t write_versions(struct file *file, char *buf, size_t size)
698{
699 ssize_t rv;
700
701 mutex_lock(&nfsd_mutex);
702 rv = __write_versions(file, buf, size);
703 mutex_unlock(&nfsd_mutex);
704 return rv;
705}
706
707
708
709
710
711static ssize_t __write_ports_names(char *buf, struct net *net)
712{
713 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
714
715 if (nn->nfsd_serv == NULL)
716 return 0;
717 return svc_xprt_names(nn->nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT);
718}
719
720
721
722
723
724
725static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred *cred)
726{
727 char *mesg = buf;
728 int fd, err;
729 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
730
731 err = get_int(&mesg, &fd);
732 if (err != 0 || fd < 0)
733 return -EINVAL;
734
735 if (svc_alien_sock(net, fd)) {
736 printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__);
737 return -EINVAL;
738 }
739
740 err = nfsd_create_serv(net);
741 if (err != 0)
742 return err;
743
744 err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred);
745 if (err < 0) {
746 nfsd_destroy(net);
747 return err;
748 }
749
750
751 nn->nfsd_serv->sv_nrthreads--;
752 return err;
753}
754
755
756
757
758
759static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cred *cred)
760{
761 char transport[16];
762 struct svc_xprt *xprt;
763 int port, err;
764 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
765
766 if (sscanf(buf, "%15s %5u", transport, &port) != 2)
767 return -EINVAL;
768
769 if (port < 1 || port > USHRT_MAX)
770 return -EINVAL;
771
772 err = nfsd_create_serv(net);
773 if (err != 0)
774 return err;
775
776 err = svc_create_xprt(nn->nfsd_serv, transport, net,
777 PF_INET, port, SVC_SOCK_ANONYMOUS, cred);
778 if (err < 0)
779 goto out_err;
780
781 err = svc_create_xprt(nn->nfsd_serv, transport, net,
782 PF_INET6, port, SVC_SOCK_ANONYMOUS, cred);
783 if (err < 0 && err != -EAFNOSUPPORT)
784 goto out_close;
785
786
787 nn->nfsd_serv->sv_nrthreads--;
788 return 0;
789out_close:
790 xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port);
791 if (xprt != NULL) {
792 svc_close_xprt(xprt);
793 svc_xprt_put(xprt);
794 }
795out_err:
796 nfsd_destroy(net);
797 return err;
798}
799
800static ssize_t __write_ports(struct file *file, char *buf, size_t size,
801 struct net *net)
802{
803 if (size == 0)
804 return __write_ports_names(buf, net);
805
806 if (isdigit(buf[0]))
807 return __write_ports_addfd(buf, net, file->f_cred);
808
809 if (isalpha(buf[0]))
810 return __write_ports_addxprt(buf, net, file->f_cred);
811
812 return -EINVAL;
813}
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858static ssize_t write_ports(struct file *file, char *buf, size_t size)
859{
860 ssize_t rv;
861
862 mutex_lock(&nfsd_mutex);
863 rv = __write_ports(file, buf, size, netns(file));
864 mutex_unlock(&nfsd_mutex);
865 return rv;
866}
867
868
869int nfsd_max_blksize;
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
893{
894 char *mesg = buf;
895 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
896
897 if (size > 0) {
898 int bsize;
899 int rv = get_int(&mesg, &bsize);
900 if (rv)
901 return rv;
902
903
904
905 bsize = max_t(int, bsize, 1024);
906 bsize = min_t(int, bsize, NFSSVC_MAXBLKSIZE);
907 bsize &= ~(1024-1);
908 mutex_lock(&nfsd_mutex);
909 if (nn->nfsd_serv) {
910 mutex_unlock(&nfsd_mutex);
911 return -EBUSY;
912 }
913 nfsd_max_blksize = bsize;
914 mutex_unlock(&nfsd_mutex);
915 }
916
917 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n",
918 nfsd_max_blksize);
919}
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
942{
943 char *mesg = buf;
944 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
945 unsigned int maxconn = nn->max_connections;
946
947 if (size > 0) {
948 int rv = get_uint(&mesg, &maxconn);
949
950 if (rv)
951 return rv;
952 nn->max_connections = maxconn;
953 }
954
955 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%u\n", maxconn);
956}
957
958#ifdef CONFIG_NFSD_V4
959static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
960 time64_t *time, struct nfsd_net *nn)
961{
962 char *mesg = buf;
963 int rv, i;
964
965 if (size > 0) {
966 if (nn->nfsd_serv)
967 return -EBUSY;
968 rv = get_int(&mesg, &i);
969 if (rv)
970 return rv;
971
972
973
974
975
976
977
978
979
980
981
982
983 if (i < 10 || i > 3600)
984 return -EINVAL;
985 *time = i;
986 }
987
988 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%lld\n", *time);
989}
990
991static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
992 time64_t *time, struct nfsd_net *nn)
993{
994 ssize_t rv;
995
996 mutex_lock(&nfsd_mutex);
997 rv = __nfsd4_write_time(file, buf, size, time, nn);
998 mutex_unlock(&nfsd_mutex);
999 return rv;
1000}
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
1024{
1025 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1026 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
1027}
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
1040{
1041 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1042 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
1043}
1044
1045static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
1046 struct nfsd_net *nn)
1047{
1048 char *mesg = buf;
1049 char *recdir;
1050 int len, status;
1051
1052 if (size > 0) {
1053 if (nn->nfsd_serv)
1054 return -EBUSY;
1055 if (size > PATH_MAX || buf[size-1] != '\n')
1056 return -EINVAL;
1057 buf[size-1] = 0;
1058
1059 recdir = mesg;
1060 len = qword_get(&mesg, recdir, size);
1061 if (len <= 0)
1062 return -EINVAL;
1063
1064 status = nfs4_reset_recoverydir(recdir);
1065 if (status)
1066 return status;
1067 }
1068
1069 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s\n",
1070 nfs4_recoverydir());
1071}
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
1095{
1096 ssize_t rv;
1097 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1098
1099 mutex_lock(&nfsd_mutex);
1100 rv = __write_recoverydir(file, buf, size, nn);
1101 mutex_unlock(&nfsd_mutex);
1102 return rv;
1103}
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
1126{
1127 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1128
1129 if (size > 0) {
1130 switch(buf[0]) {
1131 case 'Y':
1132 case 'y':
1133 case '1':
1134 if (!nn->nfsd_serv)
1135 return -EBUSY;
1136 nfsd4_end_grace(nn);
1137 break;
1138 default:
1139 return -EINVAL;
1140 }
1141 }
1142
1143 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%c\n",
1144 nn->grace_ended ? 'Y' : 'N');
1145}
1146
1147#endif
1148
1149
1150
1151
1152
1153
1154
1155static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode)
1156{
1157 struct inode *inode = new_inode(sb);
1158 if (!inode)
1159 return NULL;
1160
1161 inode->i_ino = iunique(sb, NFSD_MaxReserved);
1162 inode->i_mode = mode;
1163 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
1164 switch (mode & S_IFMT) {
1165 case S_IFDIR:
1166 inode->i_fop = &simple_dir_operations;
1167 inode->i_op = &simple_dir_inode_operations;
1168 inc_nlink(inode);
1169 default:
1170 break;
1171 }
1172 return inode;
1173}
1174
1175static int __nfsd_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, struct nfsdfs_client *ncl)
1176{
1177 struct inode *inode;
1178
1179 inode = nfsd_get_inode(dir->i_sb, mode);
1180 if (!inode)
1181 return -ENOMEM;
1182 if (ncl) {
1183 inode->i_private = ncl;
1184 kref_get(&ncl->cl_ref);
1185 }
1186 d_add(dentry, inode);
1187 inc_nlink(dir);
1188 fsnotify_mkdir(dir, dentry);
1189 return 0;
1190}
1191
1192static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *ncl, char *name)
1193{
1194 struct inode *dir = parent->d_inode;
1195 struct dentry *dentry;
1196 int ret = -ENOMEM;
1197
1198 inode_lock(dir);
1199 dentry = d_alloc_name(parent, name);
1200 if (!dentry)
1201 goto out_err;
1202 ret = __nfsd_mkdir(d_inode(parent), dentry, S_IFDIR | 0600, ncl);
1203 if (ret)
1204 goto out_err;
1205out:
1206 inode_unlock(dir);
1207 return dentry;
1208out_err:
1209 dput(dentry);
1210 dentry = ERR_PTR(ret);
1211 goto out;
1212}
1213
1214static void clear_ncl(struct inode *inode)
1215{
1216 struct nfsdfs_client *ncl = inode->i_private;
1217
1218 inode->i_private = NULL;
1219 kref_put(&ncl->cl_ref, ncl->cl_release);
1220}
1221
1222static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode)
1223{
1224 struct nfsdfs_client *nc = inode->i_private;
1225
1226 if (nc)
1227 kref_get(&nc->cl_ref);
1228 return nc;
1229}
1230
1231struct nfsdfs_client *get_nfsdfs_client(struct inode *inode)
1232{
1233 struct nfsdfs_client *nc;
1234
1235 inode_lock_shared(inode);
1236 nc = __get_nfsdfs_client(inode);
1237 inode_unlock_shared(inode);
1238 return nc;
1239}
1240
1241static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry)
1242{
1243 int ret;
1244
1245 clear_ncl(d_inode(dentry));
1246 dget(dentry);
1247 ret = simple_unlink(dir, dentry);
1248 d_delete(dentry);
1249 dput(dentry);
1250 WARN_ON_ONCE(ret);
1251}
1252
1253static void nfsdfs_remove_files(struct dentry *root)
1254{
1255 struct dentry *dentry, *tmp;
1256
1257 list_for_each_entry_safe(dentry, tmp, &root->d_subdirs, d_child) {
1258 if (!simple_positive(dentry)) {
1259 WARN_ON_ONCE(1);
1260 continue;
1261 }
1262 nfsdfs_remove_file(d_inode(root), dentry);
1263 }
1264}
1265
1266
1267
1268static int nfsdfs_create_files(struct dentry *root,
1269 const struct tree_descr *files)
1270{
1271 struct inode *dir = d_inode(root);
1272 struct inode *inode;
1273 struct dentry *dentry;
1274 int i;
1275
1276 inode_lock(dir);
1277 for (i = 0; files->name && files->name[0]; i++, files++) {
1278 if (!files->name)
1279 continue;
1280 dentry = d_alloc_name(root, files->name);
1281 if (!dentry)
1282 goto out;
1283 inode = nfsd_get_inode(d_inode(root)->i_sb,
1284 S_IFREG | files->mode);
1285 if (!inode) {
1286 dput(dentry);
1287 goto out;
1288 }
1289 inode->i_fop = files->ops;
1290 inode->i_private = __get_nfsdfs_client(dir);
1291 d_add(dentry, inode);
1292 fsnotify_create(dir, dentry);
1293 }
1294 inode_unlock(dir);
1295 return 0;
1296out:
1297 nfsdfs_remove_files(root);
1298 inode_unlock(dir);
1299 return -ENOMEM;
1300}
1301
1302
1303struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
1304 struct nfsdfs_client *ncl, u32 id,
1305 const struct tree_descr *files)
1306{
1307 struct dentry *dentry;
1308 char name[11];
1309 int ret;
1310
1311 sprintf(name, "%u", id);
1312
1313 dentry = nfsd_mkdir(nn->nfsd_client_dir, ncl, name);
1314 if (IS_ERR(dentry))
1315 return NULL;
1316 ret = nfsdfs_create_files(dentry, files);
1317 if (ret) {
1318 nfsd_client_rmdir(dentry);
1319 return NULL;
1320 }
1321 return dentry;
1322}
1323
1324
1325void nfsd_client_rmdir(struct dentry *dentry)
1326{
1327 struct inode *dir = d_inode(dentry->d_parent);
1328 struct inode *inode = d_inode(dentry);
1329 int ret;
1330
1331 inode_lock(dir);
1332 nfsdfs_remove_files(dentry);
1333 clear_ncl(inode);
1334 dget(dentry);
1335 ret = simple_rmdir(dir, dentry);
1336 WARN_ON_ONCE(ret);
1337 fsnotify_rmdir(dir, dentry);
1338 d_delete(dentry);
1339 dput(dentry);
1340 inode_unlock(dir);
1341}
1342
1343static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
1344{
1345 struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
1346 nfsd_net_id);
1347 struct dentry *dentry;
1348 int ret;
1349
1350 static const struct tree_descr nfsd_files[] = {
1351 [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
1352
1353 [NFSD_Export_Stats] = {"export_stats", &exports_nfsd_operations, S_IRUGO},
1354 [NFSD_Export_features] = {"export_features",
1355 &export_features_operations, S_IRUGO},
1356 [NFSD_FO_UnlockIP] = {"unlock_ip",
1357 &transaction_ops, S_IWUSR|S_IRUSR},
1358 [NFSD_FO_UnlockFS] = {"unlock_filesystem",
1359 &transaction_ops, S_IWUSR|S_IRUSR},
1360 [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
1361 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
1362 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
1363 [NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO},
1364 [NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO},
1365 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
1366 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
1367 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
1368 [NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO},
1369#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
1370 [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
1371#endif
1372#ifdef CONFIG_NFSD_V4
1373 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
1374 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
1375 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
1376 [NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
1377#endif
1378 {""}
1379 };
1380
1381 ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
1382 if (ret)
1383 return ret;
1384 dentry = nfsd_mkdir(sb->s_root, NULL, "clients");
1385 if (IS_ERR(dentry))
1386 return PTR_ERR(dentry);
1387 nn->nfsd_client_dir = dentry;
1388 return 0;
1389}
1390
1391static int nfsd_fs_get_tree(struct fs_context *fc)
1392{
1393 return get_tree_keyed(fc, nfsd_fill_super, get_net(fc->net_ns));
1394}
1395
1396static void nfsd_fs_free_fc(struct fs_context *fc)
1397{
1398 if (fc->s_fs_info)
1399 put_net(fc->s_fs_info);
1400}
1401
1402static const struct fs_context_operations nfsd_fs_context_ops = {
1403 .free = nfsd_fs_free_fc,
1404 .get_tree = nfsd_fs_get_tree,
1405};
1406
1407static int nfsd_init_fs_context(struct fs_context *fc)
1408{
1409 put_user_ns(fc->user_ns);
1410 fc->user_ns = get_user_ns(fc->net_ns->user_ns);
1411 fc->ops = &nfsd_fs_context_ops;
1412 return 0;
1413}
1414
1415static void nfsd_umount(struct super_block *sb)
1416{
1417 struct net *net = sb->s_fs_info;
1418
1419 kill_litter_super(sb);
1420 put_net(net);
1421}
1422
1423static struct file_system_type nfsd_fs_type = {
1424 .owner = THIS_MODULE,
1425 .name = "nfsd",
1426 .init_fs_context = nfsd_init_fs_context,
1427 .kill_sb = nfsd_umount,
1428};
1429MODULE_ALIAS_FS("nfsd");
1430
1431int get_nfsdfs(struct net *net)
1432{
1433 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1434 struct vfsmount *mnt;
1435
1436 mnt = vfs_kern_mount(&nfsd_fs_type, SB_KERNMOUNT, "nfsd", NULL);
1437 if (IS_ERR(mnt))
1438 return PTR_ERR(mnt);
1439 nn->nfsd_mnt = mnt;
1440 return 0;
1441}
1442
1443#ifdef CONFIG_PROC_FS
1444static int create_proc_exports_entry(void)
1445{
1446 struct proc_dir_entry *entry;
1447
1448 entry = proc_mkdir("fs/nfs", NULL);
1449 if (!entry)
1450 return -ENOMEM;
1451 entry = proc_create("exports", 0, entry, &exports_proc_ops);
1452 if (!entry) {
1453 remove_proc_entry("fs/nfs", NULL);
1454 return -ENOMEM;
1455 }
1456 return 0;
1457}
1458#else
1459static int create_proc_exports_entry(void)
1460{
1461 return 0;
1462}
1463#endif
1464
1465unsigned int nfsd_net_id;
1466
1467static __net_init int nfsd_init_net(struct net *net)
1468{
1469 int retval;
1470 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1471
1472 retval = nfsd_export_init(net);
1473 if (retval)
1474 goto out_export_error;
1475 retval = nfsd_idmap_init(net);
1476 if (retval)
1477 goto out_idmap_error;
1478 nn->nfsd_versions = NULL;
1479 nn->nfsd4_minorversions = NULL;
1480 retval = nfsd_reply_cache_init(nn);
1481 if (retval)
1482 goto out_drc_error;
1483 nn->nfsd4_lease = 90;
1484 nn->nfsd4_grace = 90;
1485 nn->somebody_reclaimed = false;
1486 nn->track_reclaim_completes = false;
1487 nn->clverifier_counter = prandom_u32();
1488 nn->clientid_base = prandom_u32();
1489 nn->clientid_counter = nn->clientid_base + 1;
1490 nn->s2s_cp_cl_id = nn->clientid_counter++;
1491
1492 atomic_set(&nn->ntf_refcnt, 0);
1493 init_waitqueue_head(&nn->ntf_wq);
1494 seqlock_init(&nn->boot_lock);
1495
1496 return 0;
1497
1498out_drc_error:
1499 nfsd_idmap_shutdown(net);
1500out_idmap_error:
1501 nfsd_export_shutdown(net);
1502out_export_error:
1503 return retval;
1504}
1505
1506static __net_exit void nfsd_exit_net(struct net *net)
1507{
1508 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1509
1510 nfsd_reply_cache_shutdown(nn);
1511 nfsd_idmap_shutdown(net);
1512 nfsd_export_shutdown(net);
1513 nfsd_netns_free_versions(net_generic(net, nfsd_net_id));
1514}
1515
1516static struct pernet_operations nfsd_net_ops = {
1517 .init = nfsd_init_net,
1518 .exit = nfsd_exit_net,
1519 .id = &nfsd_net_id,
1520 .size = sizeof(struct nfsd_net),
1521};
1522
1523static int __init init_nfsd(void)
1524{
1525 int retval;
1526 printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
1527
1528 retval = register_cld_notifier();
1529 if (retval)
1530 return retval;
1531 retval = nfsd4_init_slabs();
1532 if (retval)
1533 goto out_unregister_notifier;
1534 retval = nfsd4_init_pnfs();
1535 if (retval)
1536 goto out_free_slabs;
1537 retval = nfsd_stat_init();
1538 if (retval)
1539 goto out_free_pnfs;
1540 retval = nfsd_drc_slab_create();
1541 if (retval)
1542 goto out_free_stat;
1543 nfsd_lockd_init();
1544 retval = create_proc_exports_entry();
1545 if (retval)
1546 goto out_free_lockd;
1547 retval = register_filesystem(&nfsd_fs_type);
1548 if (retval)
1549 goto out_free_exports;
1550 retval = register_pernet_subsys(&nfsd_net_ops);
1551 if (retval < 0)
1552 goto out_free_all;
1553 return 0;
1554out_free_all:
1555 unregister_pernet_subsys(&nfsd_net_ops);
1556out_free_exports:
1557 remove_proc_entry("fs/nfs/exports", NULL);
1558 remove_proc_entry("fs/nfs", NULL);
1559out_free_lockd:
1560 nfsd_lockd_shutdown();
1561 nfsd_drc_slab_free();
1562out_free_stat:
1563 nfsd_stat_shutdown();
1564out_free_pnfs:
1565 nfsd4_exit_pnfs();
1566out_free_slabs:
1567 nfsd4_free_slabs();
1568out_unregister_notifier:
1569 unregister_cld_notifier();
1570 return retval;
1571}
1572
1573static void __exit exit_nfsd(void)
1574{
1575 unregister_pernet_subsys(&nfsd_net_ops);
1576 nfsd_drc_slab_free();
1577 remove_proc_entry("fs/nfs/exports", NULL);
1578 remove_proc_entry("fs/nfs", NULL);
1579 nfsd_stat_shutdown();
1580 nfsd_lockd_shutdown();
1581 nfsd4_free_slabs();
1582 nfsd4_exit_pnfs();
1583 unregister_filesystem(&nfsd_fs_type);
1584 unregister_cld_notifier();
1585}
1586
1587MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
1588MODULE_LICENSE("GPL");
1589module_init(init_nfsd)
1590module_exit(exit_nfsd)
1591