aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-04-01 13:43:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-04-01 13:43:37 -0400
commit09c8b3d1d6433860e9c51f5fc72f22a9b56ebb52 (patch)
tree0c33c895c216ba2f367da356cde71f5c6b93c323
parentfe8e12b5032536d37751c47e1c0446f17e974e5c (diff)
parent23abec20aa7034c5d49b62c0a668f7291c819fab (diff)
Merge tag 'nfsd-4.11-1' of git://linux-nfs.org/~bfields/linux
Pull nfsd fixes from Bruce Fields: "The restriction of NFSv4 to TCP went overboard and also broke the backchannel; fix. Also some minor refinements to the nfsd version-setting interface that we'd like to get fixed before release" * tag 'nfsd-4.11-1' of git://linux-nfs.org/~bfields/linux: svcrdma: set XPT_CONG_CTRL flag for bc xprt NFSD: fix nfsd_reset_versions for NFSv4. NFSD: fix nfsd_minorversion(.., NFSD_AVAIL) NFSD: further refinement of content of /proc/fs/nfsd/versions nfsd: map the ENOKEY to nfserr_perm for avoiding warning SUNRPC/backchanel: set XPT_CONG_CTRL flag for bc xprt
-rw-r--r--fs/nfsd/nfsctl.c43
-rw-r--r--fs/nfsd/nfsproc.c1
-rw-r--r--fs/nfsd/nfssvc.c28
-rw-r--r--net/sunrpc/svcsock.c1
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c1
5 files changed, 49 insertions, 25 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 73e75ac90525..8bf8f667a8cf 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -538,13 +538,21 @@ out_free:
538 538
539static ssize_t 539static ssize_t
540nfsd_print_version_support(char *buf, int remaining, const char *sep, 540nfsd_print_version_support(char *buf, int remaining, const char *sep,
541 unsigned vers, unsigned minor) 541 unsigned vers, int minor)
542{ 542{
543 const char *format = (minor == 0) ? "%s%c%u" : "%s%c%u.%u"; 543 const char *format = minor < 0 ? "%s%c%u" : "%s%c%u.%u";
544 bool supported = !!nfsd_vers(vers, NFSD_TEST); 544 bool supported = !!nfsd_vers(vers, NFSD_TEST);
545 545
546 if (vers == 4 && !nfsd_minorversion(minor, NFSD_TEST)) 546 if (vers == 4 && minor >= 0 &&
547 !nfsd_minorversion(minor, NFSD_TEST))
547 supported = false; 548 supported = false;
549 if (minor == 0 && supported)
550 /*
551 * special case for backward compatability.
552 * +4.0 is never reported, it is implied by
553 * +4, unless -4.0 is present.
554 */
555 return 0;
548 return snprintf(buf, remaining, format, sep, 556 return snprintf(buf, remaining, format, sep,
549 supported ? '+' : '-', vers, minor); 557 supported ? '+' : '-', vers, minor);
550} 558}
@@ -554,7 +562,6 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
554 char *mesg = buf; 562 char *mesg = buf;
555 char *vers, *minorp, sign; 563 char *vers, *minorp, sign;
556 int len, num, remaining; 564 int len, num, remaining;
557 unsigned minor;
558 ssize_t tlen = 0; 565 ssize_t tlen = 0;
559 char *sep; 566 char *sep;
560 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); 567 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
@@ -575,6 +582,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
575 if (len <= 0) return -EINVAL; 582 if (len <= 0) return -EINVAL;
576 do { 583 do {
577 enum vers_op cmd; 584 enum vers_op cmd;
585 unsigned minor;
578 sign = *vers; 586 sign = *vers;
579 if (sign == '+' || sign == '-') 587 if (sign == '+' || sign == '-')
580 num = simple_strtol((vers+1), &minorp, 0); 588 num = simple_strtol((vers+1), &minorp, 0);
@@ -585,8 +593,8 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
585 return -EINVAL; 593 return -EINVAL;
586 if (kstrtouint(minorp+1, 0, &minor) < 0) 594 if (kstrtouint(minorp+1, 0, &minor) < 0)
587 return -EINVAL; 595 return -EINVAL;
588 } else 596 }
589 minor = 0; 597
590 cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET; 598 cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET;
591 switch(num) { 599 switch(num) {
592 case 2: 600 case 2:
@@ -594,8 +602,20 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
594 nfsd_vers(num, cmd); 602 nfsd_vers(num, cmd);
595 break; 603 break;
596 case 4: 604 case 4:
597 if (nfsd_minorversion(minor, cmd) >= 0) 605 if (*minorp == '.') {
598 break; 606 if (nfsd_minorversion(minor, cmd) < 0)
607 return -EINVAL;
608 } else if ((cmd == NFSD_SET) != nfsd_vers(num, NFSD_TEST)) {
609 /*
610 * Either we have +4 and no minors are enabled,
611 * or we have -4 and at least one minor is enabled.
612 * In either case, propagate 'cmd' to all minors.
613 */
614 minor = 0;
615 while (nfsd_minorversion(minor, cmd) >= 0)
616 minor++;
617 }
618 break;
599 default: 619 default:
600 return -EINVAL; 620 return -EINVAL;
601 } 621 }
@@ -612,9 +632,11 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
612 sep = ""; 632 sep = "";
613 remaining = SIMPLE_TRANSACTION_LIMIT; 633 remaining = SIMPLE_TRANSACTION_LIMIT;
614 for (num=2 ; num <= 4 ; num++) { 634 for (num=2 ; num <= 4 ; num++) {
635 int minor;
615 if (!nfsd_vers(num, NFSD_AVAIL)) 636 if (!nfsd_vers(num, NFSD_AVAIL))
616 continue; 637 continue;
617 minor = 0; 638
639 minor = -1;
618 do { 640 do {
619 len = nfsd_print_version_support(buf, remaining, 641 len = nfsd_print_version_support(buf, remaining,
620 sep, num, minor); 642 sep, num, minor);
@@ -624,7 +646,8 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
624 buf += len; 646 buf += len;
625 tlen += len; 647 tlen += len;
626 minor++; 648 minor++;
627 sep = " "; 649 if (len)
650 sep = " ";
628 } while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION); 651 } while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION);
629 } 652 }
630out: 653out:
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index fa82b7707e85..03a7e9da4da0 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -786,6 +786,7 @@ nfserrno (int errno)
786 { nfserr_serverfault, -ESERVERFAULT }, 786 { nfserr_serverfault, -ESERVERFAULT },
787 { nfserr_serverfault, -ENFILE }, 787 { nfserr_serverfault, -ENFILE },
788 { nfserr_io, -EUCLEAN }, 788 { nfserr_io, -EUCLEAN },
789 { nfserr_perm, -ENOKEY },
789 }; 790 };
790 int i; 791 int i;
791 792
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 786a4a2cb2d7..31e1f9593457 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -167,7 +167,8 @@ nfsd_adjust_nfsd_versions4(void)
167 167
168int nfsd_minorversion(u32 minorversion, enum vers_op change) 168int nfsd_minorversion(u32 minorversion, enum vers_op change)
169{ 169{
170 if (minorversion > NFSD_SUPPORTED_MINOR_VERSION) 170 if (minorversion > NFSD_SUPPORTED_MINOR_VERSION &&
171 change != NFSD_AVAIL)
171 return -1; 172 return -1;
172 switch(change) { 173 switch(change) {
173 case NFSD_SET: 174 case NFSD_SET:
@@ -415,23 +416,20 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
415 416
416void nfsd_reset_versions(void) 417void nfsd_reset_versions(void)
417{ 418{
418 int found_one = 0;
419 int i; 419 int i;
420 420
421 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) { 421 for (i = 0; i < NFSD_NRVERS; i++)
422 if (nfsd_program.pg_vers[i]) 422 if (nfsd_vers(i, NFSD_TEST))
423 found_one = 1; 423 return;
424 }
425 424
426 if (!found_one) { 425 for (i = 0; i < NFSD_NRVERS; i++)
427 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) 426 if (i != 4)
428 nfsd_program.pg_vers[i] = nfsd_version[i]; 427 nfsd_vers(i, NFSD_SET);
429#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 428 else {
430 for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) 429 int minor = 0;
431 nfsd_acl_program.pg_vers[i] = 430 while (nfsd_minorversion(minor, NFSD_SET) >= 0)
432 nfsd_acl_version[i]; 431 minor++;
433#endif 432 }
434 }
435} 433}
436 434
437/* 435/*
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 8931e33b6541..2b720fa35c4f 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1635,6 +1635,7 @@ static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
1635 1635
1636 xprt = &svsk->sk_xprt; 1636 xprt = &svsk->sk_xprt;
1637 svc_xprt_init(net, &svc_tcp_bc_class, xprt, serv); 1637 svc_xprt_init(net, &svc_tcp_bc_class, xprt, serv);
1638 set_bit(XPT_CONG_CTRL, &svsk->sk_xprt.xpt_flags);
1638 1639
1639 serv->sv_bc_xprt = xprt; 1640 serv->sv_bc_xprt = xprt;
1640 1641
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index c13a5c35ce14..fc8f14c7bfec 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -127,6 +127,7 @@ static struct svc_xprt *svc_rdma_bc_create(struct svc_serv *serv,
127 xprt = &cma_xprt->sc_xprt; 127 xprt = &cma_xprt->sc_xprt;
128 128
129 svc_xprt_init(net, &svc_rdma_bc_class, xprt, serv); 129 svc_xprt_init(net, &svc_rdma_bc_class, xprt, serv);
130 set_bit(XPT_CONG_CTRL, &xprt->xpt_flags);
130 serv->sv_bc_xprt = xprt; 131 serv->sv_bc_xprt = xprt;
131 132
132 dprintk("svcrdma: %s(%p)\n", __func__, xprt); 133 dprintk("svcrdma: %s(%p)\n", __func__, xprt);