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