Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+49 -25
+33 -10
fs/nfsd/nfsctl.c
··· 538 538 539 539 static ssize_t 540 540 nfsd_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 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 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 556 return snprintf(buf, remaining, format, sep, 549 557 supported ? '+' : '-', vers, minor); 550 558 } ··· 562 554 char *mesg = buf; 563 555 char *vers, *minorp, sign; 564 556 int len, num, remaining; 565 - unsigned minor; 566 557 ssize_t tlen = 0; 567 558 char *sep; 568 559 struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); ··· 582 575 if (len <= 0) return -EINVAL; 583 576 do { 584 577 enum vers_op cmd; 578 + unsigned minor; 585 579 sign = *vers; 586 580 if (sign == '+' || sign == '-') 587 581 num = simple_strtol((vers+1), &minorp, 0); ··· 593 585 return -EINVAL; 594 586 if (kstrtouint(minorp+1, 0, &minor) < 0) 595 587 return -EINVAL; 596 - } else 597 - minor = 0; 588 + } 589 + 598 590 cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET; 599 591 switch(num) { 600 592 case 2: ··· 602 594 nfsd_vers(num, cmd); 603 595 break; 604 596 case 4: 605 - if (nfsd_minorversion(minor, cmd) >= 0) 606 - break; 597 + if (*minorp == '.') { 598 + if (nfsd_minorversion(minor, cmd) < 0) 599 + return -EINVAL; 600 + } else if ((cmd == NFSD_SET) != nfsd_vers(num, NFSD_TEST)) { 601 + /* 602 + * Either we have +4 and no minors are enabled, 603 + * or we have -4 and at least one minor is enabled. 604 + * In either case, propagate 'cmd' to all minors. 605 + */ 606 + minor = 0; 607 + while (nfsd_minorversion(minor, cmd) >= 0) 608 + minor++; 609 + } 610 + break; 607 611 default: 608 612 return -EINVAL; 609 613 } ··· 632 612 sep = ""; 633 613 remaining = SIMPLE_TRANSACTION_LIMIT; 634 614 for (num=2 ; num <= 4 ; num++) { 615 + int minor; 635 616 if (!nfsd_vers(num, NFSD_AVAIL)) 636 617 continue; 637 - minor = 0; 618 + 619 + minor = -1; 638 620 do { 639 621 len = nfsd_print_version_support(buf, remaining, 640 622 sep, num, minor); ··· 646 624 buf += len; 647 625 tlen += len; 648 626 minor++; 649 - sep = " "; 627 + if (len) 628 + sep = " "; 650 629 } while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION); 651 630 } 652 631 out:
+1
fs/nfsd/nfsproc.c
··· 786 786 { nfserr_serverfault, -ESERVERFAULT }, 787 787 { nfserr_serverfault, -ENFILE }, 788 788 { nfserr_io, -EUCLEAN }, 789 + { nfserr_perm, -ENOKEY }, 789 790 }; 790 791 int i; 791 792
+13 -15
fs/nfsd/nfssvc.c
··· 167 167 168 168 int 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 172 return -1; 172 173 switch(change) { 173 174 case NFSD_SET: ··· 416 415 417 416 void nfsd_reset_versions(void) 418 417 { 419 - int found_one = 0; 420 418 int i; 421 419 422 - for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) { 423 - if (nfsd_program.pg_vers[i]) 424 - found_one = 1; 425 - } 420 + for (i = 0; i < NFSD_NRVERS; i++) 421 + if (nfsd_vers(i, NFSD_TEST)) 422 + return; 426 423 427 - if (!found_one) { 428 - for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) 429 - nfsd_program.pg_vers[i] = nfsd_version[i]; 430 - #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 431 - for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) 432 - nfsd_acl_program.pg_vers[i] = 433 - nfsd_acl_version[i]; 434 - #endif 435 - } 424 + for (i = 0; i < NFSD_NRVERS; i++) 425 + if (i != 4) 426 + nfsd_vers(i, NFSD_SET); 427 + else { 428 + int minor = 0; 429 + while (nfsd_minorversion(minor, NFSD_SET) >= 0) 430 + minor++; 431 + } 436 432 } 437 433 438 434 /*
+1
net/sunrpc/svcsock.c
··· 1635 1635 1636 1636 xprt = &svsk->sk_xprt; 1637 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 1640 serv->sv_bc_xprt = xprt; 1640 1641
+1
net/sunrpc/xprtrdma/svc_rdma_transport.c
··· 127 127 xprt = &cma_xprt->sc_xprt; 128 128 129 129 svc_xprt_init(net, &svc_rdma_bc_class, xprt, serv); 130 + set_bit(XPT_CONG_CTRL, &xprt->xpt_flags); 130 131 serv->sv_bc_xprt = xprt; 131 132 132 133 dprintk("svcrdma: %s(%p)\n", __func__, xprt);