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 break;
1170 default:
1171 break;
1172 }
1173 return inode;
1174}
1175
1176static int __nfsd_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, struct nfsdfs_client *ncl)
1177{
1178 struct inode *inode;
1179
1180 inode = nfsd_get_inode(dir->i_sb, mode);
1181 if (!inode)
1182 return -ENOMEM;
1183 if (ncl) {
1184 inode->i_private = ncl;
1185 kref_get(&ncl->cl_ref);
1186 }
1187 d_add(dentry, inode);
1188 inc_nlink(dir);
1189 fsnotify_mkdir(dir, dentry);
1190 return 0;
1191}
1192
1193static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *ncl, char *name)
1194{
1195 struct inode *dir = parent->d_inode;
1196 struct dentry *dentry;
1197 int ret = -ENOMEM;
1198
1199 inode_lock(dir);
1200 dentry = d_alloc_name(parent, name);
1201 if (!dentry)
1202 goto out_err;
1203 ret = __nfsd_mkdir(d_inode(parent), dentry, S_IFDIR | 0600, ncl);
1204 if (ret)
1205 goto out_err;
1206out:
1207 inode_unlock(dir);
1208 return dentry;
1209out_err:
1210 dput(dentry);
1211 dentry = ERR_PTR(ret);
1212 goto out;
1213}
1214
1215static void clear_ncl(struct inode *inode)
1216{
1217 struct nfsdfs_client *ncl = inode->i_private;
1218
1219 inode->i_private = NULL;
1220 kref_put(&ncl->cl_ref, ncl->cl_release);
1221}
1222
1223static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode)
1224{
1225 struct nfsdfs_client *nc = inode->i_private;
1226
1227 if (nc)
1228 kref_get(&nc->cl_ref);
1229 return nc;
1230}
1231
1232struct nfsdfs_client *get_nfsdfs_client(struct inode *inode)
1233{
1234 struct nfsdfs_client *nc;
1235
1236 inode_lock_shared(inode);
1237 nc = __get_nfsdfs_client(inode);
1238 inode_unlock_shared(inode);
1239 return nc;
1240}
1241
1242static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry)
1243{
1244 int ret;
1245
1246 clear_ncl(d_inode(dentry));
1247 dget(dentry);
1248 ret = simple_unlink(dir, dentry);
1249 d_delete(dentry);
1250 dput(dentry);
1251 WARN_ON_ONCE(ret);
1252}
1253
1254static void nfsdfs_remove_files(struct dentry *root)
1255{
1256 struct dentry *dentry, *tmp;
1257
1258 list_for_each_entry_safe(dentry, tmp, &root->d_subdirs, d_child) {
1259 if (!simple_positive(dentry)) {
1260 WARN_ON_ONCE(1);
1261 continue;
1262 }
1263 nfsdfs_remove_file(d_inode(root), dentry);
1264 }
1265}
1266
1267
1268
1269static int nfsdfs_create_files(struct dentry *root,
1270 const struct tree_descr *files,
1271 struct dentry **fdentries)
1272{
1273 struct inode *dir = d_inode(root);
1274 struct inode *inode;
1275 struct dentry *dentry;
1276 int i;
1277
1278 inode_lock(dir);
1279 for (i = 0; files->name && files->name[0]; i++, files++) {
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 if (fdentries)
1294 fdentries[i] = dentry;
1295 }
1296 inode_unlock(dir);
1297 return 0;
1298out:
1299 nfsdfs_remove_files(root);
1300 inode_unlock(dir);
1301 return -ENOMEM;
1302}
1303
1304
1305struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
1306 struct nfsdfs_client *ncl, u32 id,
1307 const struct tree_descr *files,
1308 struct dentry **fdentries)
1309{
1310 struct dentry *dentry;
1311 char name[11];
1312 int ret;
1313
1314 sprintf(name, "%u", id);
1315
1316 dentry = nfsd_mkdir(nn->nfsd_client_dir, ncl, name);
1317 if (IS_ERR(dentry))
1318 return NULL;
1319 ret = nfsdfs_create_files(dentry, files, fdentries);
1320 if (ret) {
1321 nfsd_client_rmdir(dentry);
1322 return NULL;
1323 }
1324 return dentry;
1325}
1326
1327
1328void nfsd_client_rmdir(struct dentry *dentry)
1329{
1330 struct inode *dir = d_inode(dentry->d_parent);
1331 struct inode *inode = d_inode(dentry);
1332 int ret;
1333
1334 inode_lock(dir);
1335 nfsdfs_remove_files(dentry);
1336 clear_ncl(inode);
1337 dget(dentry);
1338 ret = simple_rmdir(dir, dentry);
1339 WARN_ON_ONCE(ret);
1340 fsnotify_rmdir(dir, dentry);
1341 d_delete(dentry);
1342 dput(dentry);
1343 inode_unlock(dir);
1344}
1345
1346static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
1347{
1348 struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
1349 nfsd_net_id);
1350 struct dentry *dentry;
1351 int ret;
1352
1353 static const struct tree_descr nfsd_files[] = {
1354 [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
1355
1356 [NFSD_Export_Stats] = {"export_stats", &exports_nfsd_operations, S_IRUGO},
1357 [NFSD_Export_features] = {"export_features",
1358 &export_features_operations, S_IRUGO},
1359 [NFSD_FO_UnlockIP] = {"unlock_ip",
1360 &transaction_ops, S_IWUSR|S_IRUSR},
1361 [NFSD_FO_UnlockFS] = {"unlock_filesystem",
1362 &transaction_ops, S_IWUSR|S_IRUSR},
1363 [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
1364 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
1365 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
1366 [NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO},
1367 [NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO},
1368 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
1369 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
1370 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
1371 [NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO},
1372#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
1373 [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
1374#endif
1375#ifdef CONFIG_NFSD_V4
1376 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
1377 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
1378 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
1379 [NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
1380#endif
1381 {""}
1382 };
1383
1384 ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
1385 if (ret)
1386 return ret;
1387 dentry = nfsd_mkdir(sb->s_root, NULL, "clients");
1388 if (IS_ERR(dentry))
1389 return PTR_ERR(dentry);
1390 nn->nfsd_client_dir = dentry;
1391 return 0;
1392}
1393
1394static int nfsd_fs_get_tree(struct fs_context *fc)
1395{
1396 return get_tree_keyed(fc, nfsd_fill_super, get_net(fc->net_ns));
1397}
1398
1399static void nfsd_fs_free_fc(struct fs_context *fc)
1400{
1401 if (fc->s_fs_info)
1402 put_net(fc->s_fs_info);
1403}
1404
1405static const struct fs_context_operations nfsd_fs_context_ops = {
1406 .free = nfsd_fs_free_fc,
1407 .get_tree = nfsd_fs_get_tree,
1408};
1409
1410static int nfsd_init_fs_context(struct fs_context *fc)
1411{
1412 put_user_ns(fc->user_ns);
1413 fc->user_ns = get_user_ns(fc->net_ns->user_ns);
1414 fc->ops = &nfsd_fs_context_ops;
1415 return 0;
1416}
1417
1418static void nfsd_umount(struct super_block *sb)
1419{
1420 struct net *net = sb->s_fs_info;
1421
1422 nfsd_shutdown_threads(net);
1423
1424 kill_litter_super(sb);
1425 put_net(net);
1426}
1427
1428static struct file_system_type nfsd_fs_type = {
1429 .owner = THIS_MODULE,
1430 .name = "nfsd",
1431 .init_fs_context = nfsd_init_fs_context,
1432 .kill_sb = nfsd_umount,
1433};
1434MODULE_ALIAS_FS("nfsd");
1435
1436#ifdef CONFIG_PROC_FS
1437static int create_proc_exports_entry(void)
1438{
1439 struct proc_dir_entry *entry;
1440
1441 entry = proc_mkdir("fs/nfs", NULL);
1442 if (!entry)
1443 return -ENOMEM;
1444 entry = proc_create("exports", 0, entry, &exports_proc_ops);
1445 if (!entry) {
1446 remove_proc_entry("fs/nfs", NULL);
1447 return -ENOMEM;
1448 }
1449 return 0;
1450}
1451#else
1452static int create_proc_exports_entry(void)
1453{
1454 return 0;
1455}
1456#endif
1457
1458unsigned int nfsd_net_id;
1459
1460static __net_init int nfsd_init_net(struct net *net)
1461{
1462 int retval;
1463 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1464
1465 retval = nfsd_export_init(net);
1466 if (retval)
1467 goto out_export_error;
1468 retval = nfsd_idmap_init(net);
1469 if (retval)
1470 goto out_idmap_error;
1471 nn->nfsd_versions = NULL;
1472 nn->nfsd4_minorversions = NULL;
1473 retval = nfsd_reply_cache_init(nn);
1474 if (retval)
1475 goto out_drc_error;
1476 nn->nfsd4_lease = 90;
1477 nn->nfsd4_grace = 90;
1478 nn->somebody_reclaimed = false;
1479 nn->track_reclaim_completes = false;
1480 nn->clverifier_counter = prandom_u32();
1481 nn->clientid_base = prandom_u32();
1482 nn->clientid_counter = nn->clientid_base + 1;
1483 nn->s2s_cp_cl_id = nn->clientid_counter++;
1484
1485 atomic_set(&nn->ntf_refcnt, 0);
1486 init_waitqueue_head(&nn->ntf_wq);
1487 seqlock_init(&nn->boot_lock);
1488
1489 return 0;
1490
1491out_drc_error:
1492 nfsd_idmap_shutdown(net);
1493out_idmap_error:
1494 nfsd_export_shutdown(net);
1495out_export_error:
1496 return retval;
1497}
1498
1499static __net_exit void nfsd_exit_net(struct net *net)
1500{
1501 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1502
1503 nfsd_reply_cache_shutdown(nn);
1504 nfsd_idmap_shutdown(net);
1505 nfsd_export_shutdown(net);
1506 nfsd_netns_free_versions(net_generic(net, nfsd_net_id));
1507}
1508
1509static struct pernet_operations nfsd_net_ops = {
1510 .init = nfsd_init_net,
1511 .exit = nfsd_exit_net,
1512 .id = &nfsd_net_id,
1513 .size = sizeof(struct nfsd_net),
1514};
1515
1516static int __init init_nfsd(void)
1517{
1518 int retval;
1519 printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
1520
1521 retval = register_cld_notifier();
1522 if (retval)
1523 return retval;
1524 retval = nfsd4_init_slabs();
1525 if (retval)
1526 goto out_unregister_notifier;
1527 retval = nfsd4_init_pnfs();
1528 if (retval)
1529 goto out_free_slabs;
1530 retval = nfsd_stat_init();
1531 if (retval)
1532 goto out_free_pnfs;
1533 retval = nfsd_drc_slab_create();
1534 if (retval)
1535 goto out_free_stat;
1536 nfsd_lockd_init();
1537 retval = create_proc_exports_entry();
1538 if (retval)
1539 goto out_free_lockd;
1540 retval = register_filesystem(&nfsd_fs_type);
1541 if (retval)
1542 goto out_free_exports;
1543 retval = register_pernet_subsys(&nfsd_net_ops);
1544 if (retval < 0)
1545 goto out_free_all;
1546 return 0;
1547out_free_all:
1548 unregister_pernet_subsys(&nfsd_net_ops);
1549out_free_exports:
1550 remove_proc_entry("fs/nfs/exports", NULL);
1551 remove_proc_entry("fs/nfs", NULL);
1552out_free_lockd:
1553 nfsd_lockd_shutdown();
1554 nfsd_drc_slab_free();
1555out_free_stat:
1556 nfsd_stat_shutdown();
1557out_free_pnfs:
1558 nfsd4_exit_pnfs();
1559out_free_slabs:
1560 nfsd4_free_slabs();
1561out_unregister_notifier:
1562 unregister_cld_notifier();
1563 return retval;
1564}
1565
1566static void __exit exit_nfsd(void)
1567{
1568 unregister_pernet_subsys(&nfsd_net_ops);
1569 nfsd_drc_slab_free();
1570 remove_proc_entry("fs/nfs/exports", NULL);
1571 remove_proc_entry("fs/nfs", NULL);
1572 nfsd_stat_shutdown();
1573 nfsd_lockd_shutdown();
1574 nfsd4_free_slabs();
1575 nfsd4_exit_pnfs();
1576 unregister_filesystem(&nfsd_fs_type);
1577 unregister_cld_notifier();
1578}
1579
1580MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
1581MODULE_LICENSE("GPL");
1582module_init(init_nfsd)
1583module_exit(exit_nfsd)
1584