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 if (!list_empty(&nn->nfsd_serv->sv_permsocks))
797 nn->nfsd_serv->sv_nrthreads--;
798 else
799 nfsd_destroy(net);
800 return err;
801}
802
803static ssize_t __write_ports(struct file *file, char *buf, size_t size,
804 struct net *net)
805{
806 if (size == 0)
807 return __write_ports_names(buf, net);
808
809 if (isdigit(buf[0]))
810 return __write_ports_addfd(buf, net, file->f_cred);
811
812 if (isalpha(buf[0]))
813 return __write_ports_addxprt(buf, net, file->f_cred);
814
815 return -EINVAL;
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
858
859
860
861static ssize_t write_ports(struct file *file, char *buf, size_t size)
862{
863 ssize_t rv;
864
865 mutex_lock(&nfsd_mutex);
866 rv = __write_ports(file, buf, size, netns(file));
867 mutex_unlock(&nfsd_mutex);
868 return rv;
869}
870
871
872int nfsd_max_blksize;
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
896{
897 char *mesg = buf;
898 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
899
900 if (size > 0) {
901 int bsize;
902 int rv = get_int(&mesg, &bsize);
903 if (rv)
904 return rv;
905
906
907
908 bsize = max_t(int, bsize, 1024);
909 bsize = min_t(int, bsize, NFSSVC_MAXBLKSIZE);
910 bsize &= ~(1024-1);
911 mutex_lock(&nfsd_mutex);
912 if (nn->nfsd_serv) {
913 mutex_unlock(&nfsd_mutex);
914 return -EBUSY;
915 }
916 nfsd_max_blksize = bsize;
917 mutex_unlock(&nfsd_mutex);
918 }
919
920 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n",
921 nfsd_max_blksize);
922}
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
945{
946 char *mesg = buf;
947 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
948 unsigned int maxconn = nn->max_connections;
949
950 if (size > 0) {
951 int rv = get_uint(&mesg, &maxconn);
952
953 if (rv)
954 return rv;
955 nn->max_connections = maxconn;
956 }
957
958 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%u\n", maxconn);
959}
960
961#ifdef CONFIG_NFSD_V4
962static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
963 time64_t *time, struct nfsd_net *nn)
964{
965 char *mesg = buf;
966 int rv, i;
967
968 if (size > 0) {
969 if (nn->nfsd_serv)
970 return -EBUSY;
971 rv = get_int(&mesg, &i);
972 if (rv)
973 return rv;
974
975
976
977
978
979
980
981
982
983
984
985
986 if (i < 10 || i > 3600)
987 return -EINVAL;
988 *time = i;
989 }
990
991 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%lld\n", *time);
992}
993
994static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
995 time64_t *time, struct nfsd_net *nn)
996{
997 ssize_t rv;
998
999 mutex_lock(&nfsd_mutex);
1000 rv = __nfsd4_write_time(file, buf, size, time, nn);
1001 mutex_unlock(&nfsd_mutex);
1002 return rv;
1003}
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
1027{
1028 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1029 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
1030}
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
1043{
1044 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1045 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
1046}
1047
1048static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
1049 struct nfsd_net *nn)
1050{
1051 char *mesg = buf;
1052 char *recdir;
1053 int len, status;
1054
1055 if (size > 0) {
1056 if (nn->nfsd_serv)
1057 return -EBUSY;
1058 if (size > PATH_MAX || buf[size-1] != '\n')
1059 return -EINVAL;
1060 buf[size-1] = 0;
1061
1062 recdir = mesg;
1063 len = qword_get(&mesg, recdir, size);
1064 if (len <= 0)
1065 return -EINVAL;
1066
1067 status = nfs4_reset_recoverydir(recdir);
1068 if (status)
1069 return status;
1070 }
1071
1072 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s\n",
1073 nfs4_recoverydir());
1074}
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
1098{
1099 ssize_t rv;
1100 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1101
1102 mutex_lock(&nfsd_mutex);
1103 rv = __write_recoverydir(file, buf, size, nn);
1104 mutex_unlock(&nfsd_mutex);
1105 return rv;
1106}
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
1129{
1130 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1131
1132 if (size > 0) {
1133 switch(buf[0]) {
1134 case 'Y':
1135 case 'y':
1136 case '1':
1137 if (!nn->nfsd_serv)
1138 return -EBUSY;
1139 nfsd4_end_grace(nn);
1140 break;
1141 default:
1142 return -EINVAL;
1143 }
1144 }
1145
1146 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%c\n",
1147 nn->grace_ended ? 'Y' : 'N');
1148}
1149
1150#endif
1151
1152
1153
1154
1155
1156
1157
1158static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode)
1159{
1160 struct inode *inode = new_inode(sb);
1161 if (!inode)
1162 return NULL;
1163
1164 inode->i_ino = iunique(sb, NFSD_MaxReserved);
1165 inode->i_mode = mode;
1166 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
1167 switch (mode & S_IFMT) {
1168 case S_IFDIR:
1169 inode->i_fop = &simple_dir_operations;
1170 inode->i_op = &simple_dir_inode_operations;
1171 inc_nlink(inode);
1172 break;
1173 default:
1174 break;
1175 }
1176 return inode;
1177}
1178
1179static int __nfsd_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, struct nfsdfs_client *ncl)
1180{
1181 struct inode *inode;
1182
1183 inode = nfsd_get_inode(dir->i_sb, mode);
1184 if (!inode)
1185 return -ENOMEM;
1186 if (ncl) {
1187 inode->i_private = ncl;
1188 kref_get(&ncl->cl_ref);
1189 }
1190 d_add(dentry, inode);
1191 inc_nlink(dir);
1192 fsnotify_mkdir(dir, dentry);
1193 return 0;
1194}
1195
1196static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *ncl, char *name)
1197{
1198 struct inode *dir = parent->d_inode;
1199 struct dentry *dentry;
1200 int ret = -ENOMEM;
1201
1202 inode_lock(dir);
1203 dentry = d_alloc_name(parent, name);
1204 if (!dentry)
1205 goto out_err;
1206 ret = __nfsd_mkdir(d_inode(parent), dentry, S_IFDIR | 0600, ncl);
1207 if (ret)
1208 goto out_err;
1209out:
1210 inode_unlock(dir);
1211 return dentry;
1212out_err:
1213 dput(dentry);
1214 dentry = ERR_PTR(ret);
1215 goto out;
1216}
1217
1218static void clear_ncl(struct inode *inode)
1219{
1220 struct nfsdfs_client *ncl = inode->i_private;
1221
1222 inode->i_private = NULL;
1223 kref_put(&ncl->cl_ref, ncl->cl_release);
1224}
1225
1226static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode)
1227{
1228 struct nfsdfs_client *nc = inode->i_private;
1229
1230 if (nc)
1231 kref_get(&nc->cl_ref);
1232 return nc;
1233}
1234
1235struct nfsdfs_client *get_nfsdfs_client(struct inode *inode)
1236{
1237 struct nfsdfs_client *nc;
1238
1239 inode_lock_shared(inode);
1240 nc = __get_nfsdfs_client(inode);
1241 inode_unlock_shared(inode);
1242 return nc;
1243}
1244
1245static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry)
1246{
1247 int ret;
1248
1249 clear_ncl(d_inode(dentry));
1250 dget(dentry);
1251 ret = simple_unlink(dir, dentry);
1252 d_delete(dentry);
1253 dput(dentry);
1254 WARN_ON_ONCE(ret);
1255}
1256
1257static void nfsdfs_remove_files(struct dentry *root)
1258{
1259 struct dentry *dentry, *tmp;
1260
1261 list_for_each_entry_safe(dentry, tmp, &root->d_subdirs, d_child) {
1262 if (!simple_positive(dentry)) {
1263 WARN_ON_ONCE(1);
1264 continue;
1265 }
1266 nfsdfs_remove_file(d_inode(root), dentry);
1267 }
1268}
1269
1270
1271
1272static int nfsdfs_create_files(struct dentry *root,
1273 const struct tree_descr *files,
1274 struct dentry **fdentries)
1275{
1276 struct inode *dir = d_inode(root);
1277 struct inode *inode;
1278 struct dentry *dentry;
1279 int i;
1280
1281 inode_lock(dir);
1282 for (i = 0; files->name && files->name[0]; i++, files++) {
1283 dentry = d_alloc_name(root, files->name);
1284 if (!dentry)
1285 goto out;
1286 inode = nfsd_get_inode(d_inode(root)->i_sb,
1287 S_IFREG | files->mode);
1288 if (!inode) {
1289 dput(dentry);
1290 goto out;
1291 }
1292 inode->i_fop = files->ops;
1293 inode->i_private = __get_nfsdfs_client(dir);
1294 d_add(dentry, inode);
1295 fsnotify_create(dir, dentry);
1296 if (fdentries)
1297 fdentries[i] = dentry;
1298 }
1299 inode_unlock(dir);
1300 return 0;
1301out:
1302 nfsdfs_remove_files(root);
1303 inode_unlock(dir);
1304 return -ENOMEM;
1305}
1306
1307
1308struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
1309 struct nfsdfs_client *ncl, u32 id,
1310 const struct tree_descr *files,
1311 struct dentry **fdentries)
1312{
1313 struct dentry *dentry;
1314 char name[11];
1315 int ret;
1316
1317 sprintf(name, "%u", id);
1318
1319 dentry = nfsd_mkdir(nn->nfsd_client_dir, ncl, name);
1320 if (IS_ERR(dentry))
1321 return NULL;
1322 ret = nfsdfs_create_files(dentry, files, fdentries);
1323 if (ret) {
1324 nfsd_client_rmdir(dentry);
1325 return NULL;
1326 }
1327 return dentry;
1328}
1329
1330
1331void nfsd_client_rmdir(struct dentry *dentry)
1332{
1333 struct inode *dir = d_inode(dentry->d_parent);
1334 struct inode *inode = d_inode(dentry);
1335 int ret;
1336
1337 inode_lock(dir);
1338 nfsdfs_remove_files(dentry);
1339 clear_ncl(inode);
1340 dget(dentry);
1341 ret = simple_rmdir(dir, dentry);
1342 WARN_ON_ONCE(ret);
1343 fsnotify_rmdir(dir, dentry);
1344 d_delete(dentry);
1345 dput(dentry);
1346 inode_unlock(dir);
1347}
1348
1349static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
1350{
1351 struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
1352 nfsd_net_id);
1353 struct dentry *dentry;
1354 int ret;
1355
1356 static const struct tree_descr nfsd_files[] = {
1357 [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
1358
1359 [NFSD_Export_Stats] = {"export_stats", &exports_nfsd_operations, S_IRUGO},
1360 [NFSD_Export_features] = {"export_features",
1361 &export_features_operations, S_IRUGO},
1362 [NFSD_FO_UnlockIP] = {"unlock_ip",
1363 &transaction_ops, S_IWUSR|S_IRUSR},
1364 [NFSD_FO_UnlockFS] = {"unlock_filesystem",
1365 &transaction_ops, S_IWUSR|S_IRUSR},
1366 [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
1367 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
1368 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
1369 [NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO},
1370 [NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO},
1371 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
1372 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
1373 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
1374 [NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO},
1375#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
1376 [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
1377#endif
1378#ifdef CONFIG_NFSD_V4
1379 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
1380 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
1381 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
1382 [NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
1383#endif
1384 {""}
1385 };
1386
1387 ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
1388 if (ret)
1389 return ret;
1390 dentry = nfsd_mkdir(sb->s_root, NULL, "clients");
1391 if (IS_ERR(dentry))
1392 return PTR_ERR(dentry);
1393 nn->nfsd_client_dir = dentry;
1394 return 0;
1395}
1396
1397static int nfsd_fs_get_tree(struct fs_context *fc)
1398{
1399 return get_tree_keyed(fc, nfsd_fill_super, get_net(fc->net_ns));
1400}
1401
1402static void nfsd_fs_free_fc(struct fs_context *fc)
1403{
1404 if (fc->s_fs_info)
1405 put_net(fc->s_fs_info);
1406}
1407
1408static const struct fs_context_operations nfsd_fs_context_ops = {
1409 .free = nfsd_fs_free_fc,
1410 .get_tree = nfsd_fs_get_tree,
1411};
1412
1413static int nfsd_init_fs_context(struct fs_context *fc)
1414{
1415 put_user_ns(fc->user_ns);
1416 fc->user_ns = get_user_ns(fc->net_ns->user_ns);
1417 fc->ops = &nfsd_fs_context_ops;
1418 return 0;
1419}
1420
1421static void nfsd_umount(struct super_block *sb)
1422{
1423 struct net *net = sb->s_fs_info;
1424
1425 nfsd_shutdown_threads(net);
1426
1427 kill_litter_super(sb);
1428 put_net(net);
1429}
1430
1431static struct file_system_type nfsd_fs_type = {
1432 .owner = THIS_MODULE,
1433 .name = "nfsd",
1434 .init_fs_context = nfsd_init_fs_context,
1435 .kill_sb = nfsd_umount,
1436};
1437MODULE_ALIAS_FS("nfsd");
1438
1439#ifdef CONFIG_PROC_FS
1440static int create_proc_exports_entry(void)
1441{
1442 struct proc_dir_entry *entry;
1443
1444 entry = proc_mkdir("fs/nfs", NULL);
1445 if (!entry)
1446 return -ENOMEM;
1447 entry = proc_create("exports", 0, entry, &exports_proc_ops);
1448 if (!entry) {
1449 remove_proc_entry("fs/nfs", NULL);
1450 return -ENOMEM;
1451 }
1452 return 0;
1453}
1454#else
1455static int create_proc_exports_entry(void)
1456{
1457 return 0;
1458}
1459#endif
1460
1461unsigned int nfsd_net_id;
1462
1463static __net_init int nfsd_init_net(struct net *net)
1464{
1465 int retval;
1466 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1467
1468 retval = nfsd_export_init(net);
1469 if (retval)
1470 goto out_export_error;
1471 retval = nfsd_idmap_init(net);
1472 if (retval)
1473 goto out_idmap_error;
1474 nn->nfsd_versions = NULL;
1475 nn->nfsd4_minorversions = NULL;
1476 retval = nfsd_reply_cache_init(nn);
1477 if (retval)
1478 goto out_drc_error;
1479 nn->nfsd4_lease = 90;
1480 nn->nfsd4_grace = 90;
1481 nn->somebody_reclaimed = false;
1482 nn->track_reclaim_completes = false;
1483 nn->clverifier_counter = prandom_u32();
1484 nn->clientid_base = prandom_u32();
1485 nn->clientid_counter = nn->clientid_base + 1;
1486 nn->s2s_cp_cl_id = nn->clientid_counter++;
1487
1488 atomic_set(&nn->ntf_refcnt, 0);
1489 init_waitqueue_head(&nn->ntf_wq);
1490 seqlock_init(&nn->boot_lock);
1491
1492 return 0;
1493
1494out_drc_error:
1495 nfsd_idmap_shutdown(net);
1496out_idmap_error:
1497 nfsd_export_shutdown(net);
1498out_export_error:
1499 return retval;
1500}
1501
1502static __net_exit void nfsd_exit_net(struct net *net)
1503{
1504 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1505
1506 nfsd_reply_cache_shutdown(nn);
1507 nfsd_idmap_shutdown(net);
1508 nfsd_export_shutdown(net);
1509 nfsd_netns_free_versions(net_generic(net, nfsd_net_id));
1510}
1511
1512static struct pernet_operations nfsd_net_ops = {
1513 .init = nfsd_init_net,
1514 .exit = nfsd_exit_net,
1515 .id = &nfsd_net_id,
1516 .size = sizeof(struct nfsd_net),
1517};
1518
1519static int __init init_nfsd(void)
1520{
1521 int retval;
1522 printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
1523
1524 retval = register_cld_notifier();
1525 if (retval)
1526 return retval;
1527 retval = nfsd4_init_slabs();
1528 if (retval)
1529 goto out_unregister_notifier;
1530 retval = nfsd4_init_pnfs();
1531 if (retval)
1532 goto out_free_slabs;
1533 retval = nfsd_stat_init();
1534 if (retval)
1535 goto out_free_pnfs;
1536 retval = nfsd_drc_slab_create();
1537 if (retval)
1538 goto out_free_stat;
1539 nfsd_lockd_init();
1540 retval = create_proc_exports_entry();
1541 if (retval)
1542 goto out_free_lockd;
1543 retval = register_filesystem(&nfsd_fs_type);
1544 if (retval)
1545 goto out_free_exports;
1546 retval = register_pernet_subsys(&nfsd_net_ops);
1547 if (retval < 0)
1548 goto out_free_all;
1549 return 0;
1550out_free_all:
1551 unregister_filesystem(&nfsd_fs_type);
1552out_free_exports:
1553 remove_proc_entry("fs/nfs/exports", NULL);
1554 remove_proc_entry("fs/nfs", NULL);
1555out_free_lockd:
1556 nfsd_lockd_shutdown();
1557 nfsd_drc_slab_free();
1558out_free_stat:
1559 nfsd_stat_shutdown();
1560out_free_pnfs:
1561 nfsd4_exit_pnfs();
1562out_free_slabs:
1563 nfsd4_free_slabs();
1564out_unregister_notifier:
1565 unregister_cld_notifier();
1566 return retval;
1567}
1568
1569static void __exit exit_nfsd(void)
1570{
1571 unregister_pernet_subsys(&nfsd_net_ops);
1572 nfsd_drc_slab_free();
1573 remove_proc_entry("fs/nfs/exports", NULL);
1574 remove_proc_entry("fs/nfs", NULL);
1575 nfsd_stat_shutdown();
1576 nfsd_lockd_shutdown();
1577 nfsd4_free_slabs();
1578 nfsd4_exit_pnfs();
1579 unregister_filesystem(&nfsd_fs_type);
1580 unregister_cld_notifier();
1581}
1582
1583MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
1584MODULE_LICENSE("GPL");
1585module_init(init_nfsd)
1586module_exit(exit_nfsd)
1587