aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfsctl.c
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-12-06 06:23:24 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-12-10 16:25:39 -0500
commit9dd9845f084cda07ce00cca32a5ba8fbcbbfbcaf (patch)
tree1746b995da1b4f203373d72a41909b0eebdbecf6 /fs/nfsd/nfsctl.c
parentb9c0ef8571c6ae33465dcf41d496ce2ad783c49d (diff)
nfsd: make NFSd service structure allocated per net
This patch makes main step in NFSd containerisation. There could be different approaches to how to make NFSd able to handle incoming RPC request from different network namespaces. The two main options are: 1) Share NFSd kthreads betwween all network namespaces. 2) Create separated pool of threads for each namespace. While first approach looks more flexible, second one is simpler and non-racy. This patch implements the second option. To make it possible to allocate separate pools of threads, we have to make it possible to allocate separate NFSd service structures per net. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfsctl.c')
-rw-r--r--fs/nfsd/nfsctl.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 8536100b7fc1..74934284d9a7 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -409,7 +409,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
409 if (rv < 0) 409 if (rv < 0)
410 return rv; 410 return rv;
411 } else 411 } else
412 rv = nfsd_nrthreads(); 412 rv = nfsd_nrthreads(net);
413 413
414 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv); 414 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv);
415} 415}
@@ -450,7 +450,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
450 struct net *net = &init_net; 450 struct net *net = &init_net;
451 451
452 mutex_lock(&nfsd_mutex); 452 mutex_lock(&nfsd_mutex);
453 npools = nfsd_nrpools(); 453 npools = nfsd_nrpools(net);
454 if (npools == 0) { 454 if (npools == 0) {
455 /* 455 /*
456 * NFS is shut down. The admin can start it by 456 * NFS is shut down. The admin can start it by
@@ -483,7 +483,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
483 goto out_free; 483 goto out_free;
484 } 484 }
485 485
486 rv = nfsd_get_nrthreads(npools, nthreads); 486 rv = nfsd_get_nrthreads(npools, nthreads, net);
487 if (rv) 487 if (rv)
488 goto out_free; 488 goto out_free;
489 489
@@ -510,11 +510,13 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
510 unsigned minor; 510 unsigned minor;
511 ssize_t tlen = 0; 511 ssize_t tlen = 0;
512 char *sep; 512 char *sep;
513 struct net *net = &init_net;
514 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
513 515
514 if (size>0) { 516 if (size>0) {
515 if (nfsd_serv) 517 if (nn->nfsd_serv)
516 /* Cannot change versions without updating 518 /* Cannot change versions without updating
517 * nfsd_serv->sv_xdrsize, and reallocing 519 * nn->nfsd_serv->sv_xdrsize, and reallocing
518 * rq_argp and rq_resp 520 * rq_argp and rq_resp
519 */ 521 */
520 return -EBUSY; 522 return -EBUSY;
@@ -645,11 +647,13 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
645 * Zero-length write. Return a list of NFSD's current listener 647 * Zero-length write. Return a list of NFSD's current listener
646 * transports. 648 * transports.
647 */ 649 */
648static ssize_t __write_ports_names(char *buf) 650static ssize_t __write_ports_names(char *buf, struct net *net)
649{ 651{
650 if (nfsd_serv == NULL) 652 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
653
654 if (nn->nfsd_serv == NULL)
651 return 0; 655 return 0;
652 return svc_xprt_names(nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT); 656 return svc_xprt_names(nn->nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT);
653} 657}
654 658
655/* 659/*
@@ -661,6 +665,7 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net)
661{ 665{
662 char *mesg = buf; 666 char *mesg = buf;
663 int fd, err; 667 int fd, err;
668 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
664 669
665 err = get_int(&mesg, &fd); 670 err = get_int(&mesg, &fd);
666 if (err != 0 || fd < 0) 671 if (err != 0 || fd < 0)
@@ -670,14 +675,14 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net)
670 if (err != 0) 675 if (err != 0)
671 return err; 676 return err;
672 677
673 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); 678 err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
674 if (err < 0) { 679 if (err < 0) {
675 nfsd_destroy(net); 680 nfsd_destroy(net);
676 return err; 681 return err;
677 } 682 }
678 683
679 /* Decrease the count, but don't shut down the service */ 684 /* Decrease the count, but don't shut down the service */
680 nfsd_serv->sv_nrthreads--; 685 nn->nfsd_serv->sv_nrthreads--;
681 return err; 686 return err;
682} 687}
683 688
@@ -690,6 +695,7 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net)
690 char transport[16]; 695 char transport[16];
691 struct svc_xprt *xprt; 696 struct svc_xprt *xprt;
692 int port, err; 697 int port, err;
698 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
693 699
694 if (sscanf(buf, "%15s %5u", transport, &port) != 2) 700 if (sscanf(buf, "%15s %5u", transport, &port) != 2)
695 return -EINVAL; 701 return -EINVAL;
@@ -701,21 +707,21 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net)
701 if (err != 0) 707 if (err != 0)
702 return err; 708 return err;
703 709
704 err = svc_create_xprt(nfsd_serv, transport, net, 710 err = svc_create_xprt(nn->nfsd_serv, transport, net,
705 PF_INET, port, SVC_SOCK_ANONYMOUS); 711 PF_INET, port, SVC_SOCK_ANONYMOUS);
706 if (err < 0) 712 if (err < 0)
707 goto out_err; 713 goto out_err;
708 714
709 err = svc_create_xprt(nfsd_serv, transport, net, 715 err = svc_create_xprt(nn->nfsd_serv, transport, net,
710 PF_INET6, port, SVC_SOCK_ANONYMOUS); 716 PF_INET6, port, SVC_SOCK_ANONYMOUS);
711 if (err < 0 && err != -EAFNOSUPPORT) 717 if (err < 0 && err != -EAFNOSUPPORT)
712 goto out_close; 718 goto out_close;
713 719
714 /* Decrease the count, but don't shut down the service */ 720 /* Decrease the count, but don't shut down the service */
715 nfsd_serv->sv_nrthreads--; 721 nn->nfsd_serv->sv_nrthreads--;
716 return 0; 722 return 0;
717out_close: 723out_close:
718 xprt = svc_find_xprt(nfsd_serv, transport, net, PF_INET, port); 724 xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port);
719 if (xprt != NULL) { 725 if (xprt != NULL) {
720 svc_close_xprt(xprt); 726 svc_close_xprt(xprt);
721 svc_xprt_put(xprt); 727 svc_xprt_put(xprt);
@@ -729,7 +735,7 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size,
729 struct net *net) 735 struct net *net)
730{ 736{
731 if (size == 0) 737 if (size == 0)
732 return __write_ports_names(buf); 738 return __write_ports_names(buf, net);
733 739
734 if (isdigit(buf[0])) 740 if (isdigit(buf[0]))
735 return __write_ports_addfd(buf, net); 741 return __write_ports_addfd(buf, net);
@@ -821,6 +827,9 @@ int nfsd_max_blksize;
821static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) 827static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
822{ 828{
823 char *mesg = buf; 829 char *mesg = buf;
830 struct net *net = &init_net;
831 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
832
824 if (size > 0) { 833 if (size > 0) {
825 int bsize; 834 int bsize;
826 int rv = get_int(&mesg, &bsize); 835 int rv = get_int(&mesg, &bsize);
@@ -835,7 +844,7 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
835 bsize = NFSSVC_MAXBLKSIZE; 844 bsize = NFSSVC_MAXBLKSIZE;
836 bsize &= ~(1024-1); 845 bsize &= ~(1024-1);
837 mutex_lock(&nfsd_mutex); 846 mutex_lock(&nfsd_mutex);
838 if (nfsd_serv) { 847 if (nn->nfsd_serv) {
839 mutex_unlock(&nfsd_mutex); 848 mutex_unlock(&nfsd_mutex);
840 return -EBUSY; 849 return -EBUSY;
841 } 850 }
@@ -848,13 +857,14 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
848} 857}
849 858
850#ifdef CONFIG_NFSD_V4 859#ifdef CONFIG_NFSD_V4
851static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time) 860static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
861 time_t *time, struct nfsd_net *nn)
852{ 862{
853 char *mesg = buf; 863 char *mesg = buf;
854 int rv, i; 864 int rv, i;
855 865
856 if (size > 0) { 866 if (size > 0) {
857 if (nfsd_serv) 867 if (nn->nfsd_serv)
858 return -EBUSY; 868 return -EBUSY;
859 rv = get_int(&mesg, &i); 869 rv = get_int(&mesg, &i);
860 if (rv) 870 if (rv)
@@ -879,12 +889,13 @@ static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, tim
879 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time); 889 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time);
880} 890}
881 891
882static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time) 892static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
893 time_t *time, struct nfsd_net *nn)
883{ 894{
884 ssize_t rv; 895 ssize_t rv;
885 896
886 mutex_lock(&nfsd_mutex); 897 mutex_lock(&nfsd_mutex);
887 rv = __nfsd4_write_time(file, buf, size, time); 898 rv = __nfsd4_write_time(file, buf, size, time, nn);
888 mutex_unlock(&nfsd_mutex); 899 mutex_unlock(&nfsd_mutex);
889 return rv; 900 return rv;
890} 901}
@@ -913,7 +924,7 @@ static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, time_
913static ssize_t write_leasetime(struct file *file, char *buf, size_t size) 924static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
914{ 925{
915 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 926 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
916 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease); 927 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
917} 928}
918 929
919/** 930/**
@@ -929,17 +940,18 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
929static ssize_t write_gracetime(struct file *file, char *buf, size_t size) 940static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
930{ 941{
931 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 942 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
932 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace); 943 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
933} 944}
934 945
935static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size) 946static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
947 struct nfsd_net *nn)
936{ 948{
937 char *mesg = buf; 949 char *mesg = buf;
938 char *recdir; 950 char *recdir;
939 int len, status; 951 int len, status;
940 952
941 if (size > 0) { 953 if (size > 0) {
942 if (nfsd_serv) 954 if (nn->nfsd_serv)
943 return -EBUSY; 955 return -EBUSY;
944 if (size > PATH_MAX || buf[size-1] != '\n') 956 if (size > PATH_MAX || buf[size-1] != '\n')
945 return -EINVAL; 957 return -EINVAL;
@@ -983,9 +995,10 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size)
983static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) 995static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
984{ 996{
985 ssize_t rv; 997 ssize_t rv;
998 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
986 999
987 mutex_lock(&nfsd_mutex); 1000 mutex_lock(&nfsd_mutex);
988 rv = __write_recoverydir(file, buf, size); 1001 rv = __write_recoverydir(file, buf, size, nn);
989 mutex_unlock(&nfsd_mutex); 1002 mutex_unlock(&nfsd_mutex);
990 return rv; 1003 return rv;
991} 1004}