Commit 09c8b3d1 authored by Linus Torvalds's avatar Linus Torvalds

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
parents fe8e12b5 23abec20
...@@ -538,13 +538,21 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size) ...@@ -538,13 +538,21 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
static ssize_t static ssize_t
nfsd_print_version_support(char *buf, int remaining, const char *sep, nfsd_print_version_support(char *buf, int remaining, const char *sep,
unsigned vers, unsigned minor) unsigned vers, int minor)
{ {
const char *format = (minor == 0) ? "%s%c%u" : "%s%c%u.%u"; const char *format = minor < 0 ? "%s%c%u" : "%s%c%u.%u";
bool supported = !!nfsd_vers(vers, NFSD_TEST); bool supported = !!nfsd_vers(vers, NFSD_TEST);
if (vers == 4 && !nfsd_minorversion(minor, NFSD_TEST)) if (vers == 4 && minor >= 0 &&
!nfsd_minorversion(minor, NFSD_TEST))
supported = false; supported = false;
if (minor == 0 && supported)
/*
* special case for backward compatability.
* +4.0 is never reported, it is implied by
* +4, unless -4.0 is present.
*/
return 0;
return snprintf(buf, remaining, format, sep, return snprintf(buf, remaining, format, sep,
supported ? '+' : '-', vers, minor); supported ? '+' : '-', vers, minor);
} }
...@@ -554,7 +562,6 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) ...@@ -554,7 +562,6 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
char *mesg = buf; char *mesg = buf;
char *vers, *minorp, sign; char *vers, *minorp, sign;
int len, num, remaining; int len, num, remaining;
unsigned minor;
ssize_t tlen = 0; ssize_t tlen = 0;
char *sep; char *sep;
struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); 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,6 +582,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
if (len <= 0) return -EINVAL; if (len <= 0) return -EINVAL;
do { do {
enum vers_op cmd; enum vers_op cmd;
unsigned minor;
sign = *vers; sign = *vers;
if (sign == '+' || sign == '-') if (sign == '+' || sign == '-')
num = simple_strtol((vers+1), &minorp, 0); 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,8 +593,8 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
return -EINVAL; return -EINVAL;
if (kstrtouint(minorp+1, 0, &minor) < 0) if (kstrtouint(minorp+1, 0, &minor) < 0)
return -EINVAL; return -EINVAL;
} else }
minor = 0;
cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET; cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET;
switch(num) { switch(num) {
case 2: case 2:
...@@ -594,8 +602,20 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) ...@@ -594,8 +602,20 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
nfsd_vers(num, cmd); nfsd_vers(num, cmd);
break; break;
case 4: case 4:
if (nfsd_minorversion(minor, cmd) >= 0) if (*minorp == '.') {
break; if (nfsd_minorversion(minor, cmd) < 0)
return -EINVAL;
} else if ((cmd == NFSD_SET) != nfsd_vers(num, NFSD_TEST)) {
/*
* Either we have +4 and no minors are enabled,
* or we have -4 and at least one minor is enabled.
* In either case, propagate 'cmd' to all minors.
*/
minor = 0;
while (nfsd_minorversion(minor, cmd) >= 0)
minor++;
}
break;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -612,9 +632,11 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) ...@@ -612,9 +632,11 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
sep = ""; sep = "";
remaining = SIMPLE_TRANSACTION_LIMIT; remaining = SIMPLE_TRANSACTION_LIMIT;
for (num=2 ; num <= 4 ; num++) { for (num=2 ; num <= 4 ; num++) {
int minor;
if (!nfsd_vers(num, NFSD_AVAIL)) if (!nfsd_vers(num, NFSD_AVAIL))
continue; continue;
minor = 0;
minor = -1;
do { do {
len = nfsd_print_version_support(buf, remaining, len = nfsd_print_version_support(buf, remaining,
sep, num, minor); sep, num, minor);
...@@ -624,7 +646,8 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) ...@@ -624,7 +646,8 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
buf += len; buf += len;
tlen += len; tlen += len;
minor++; minor++;
sep = " "; if (len)
sep = " ";
} while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION); } while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION);
} }
out: out:
......
...@@ -786,6 +786,7 @@ nfserrno (int errno) ...@@ -786,6 +786,7 @@ nfserrno (int errno)
{ nfserr_serverfault, -ESERVERFAULT }, { nfserr_serverfault, -ESERVERFAULT },
{ nfserr_serverfault, -ENFILE }, { nfserr_serverfault, -ENFILE },
{ nfserr_io, -EUCLEAN }, { nfserr_io, -EUCLEAN },
{ nfserr_perm, -ENOKEY },
}; };
int i; int i;
......
...@@ -167,7 +167,8 @@ nfsd_adjust_nfsd_versions4(void) ...@@ -167,7 +167,8 @@ nfsd_adjust_nfsd_versions4(void)
int nfsd_minorversion(u32 minorversion, enum vers_op change) int nfsd_minorversion(u32 minorversion, enum vers_op change)
{ {
if (minorversion > NFSD_SUPPORTED_MINOR_VERSION) if (minorversion > NFSD_SUPPORTED_MINOR_VERSION &&
change != NFSD_AVAIL)
return -1; return -1;
switch(change) { switch(change) {
case NFSD_SET: case NFSD_SET:
...@@ -415,23 +416,20 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net) ...@@ -415,23 +416,20 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
void nfsd_reset_versions(void) void nfsd_reset_versions(void)
{ {
int found_one = 0;
int i; int i;
for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) { for (i = 0; i < NFSD_NRVERS; i++)
if (nfsd_program.pg_vers[i]) if (nfsd_vers(i, NFSD_TEST))
found_one = 1; return;
}
if (!found_one) { for (i = 0; i < NFSD_NRVERS; i++)
for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) if (i != 4)
nfsd_program.pg_vers[i] = nfsd_version[i]; nfsd_vers(i, NFSD_SET);
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) else {
for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) int minor = 0;
nfsd_acl_program.pg_vers[i] = while (nfsd_minorversion(minor, NFSD_SET) >= 0)
nfsd_acl_version[i]; minor++;
#endif }
}
} }
/* /*
......
...@@ -1635,6 +1635,7 @@ static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv, ...@@ -1635,6 +1635,7 @@ static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
xprt = &svsk->sk_xprt; xprt = &svsk->sk_xprt;
svc_xprt_init(net, &svc_tcp_bc_class, xprt, serv); svc_xprt_init(net, &svc_tcp_bc_class, xprt, serv);
set_bit(XPT_CONG_CTRL, &svsk->sk_xprt.xpt_flags);
serv->sv_bc_xprt = xprt; serv->sv_bc_xprt = xprt;
......
...@@ -127,6 +127,7 @@ static struct svc_xprt *svc_rdma_bc_create(struct svc_serv *serv, ...@@ -127,6 +127,7 @@ static struct svc_xprt *svc_rdma_bc_create(struct svc_serv *serv,
xprt = &cma_xprt->sc_xprt; xprt = &cma_xprt->sc_xprt;
svc_xprt_init(net, &svc_rdma_bc_class, xprt, serv); svc_xprt_init(net, &svc_rdma_bc_class, xprt, serv);
set_bit(XPT_CONG_CTRL, &xprt->xpt_flags);
serv->sv_bc_xprt = xprt; serv->sv_bc_xprt = xprt;
dprintk("svcrdma: %s(%p)\n", __func__, xprt); dprintk("svcrdma: %s(%p)\n", __func__, xprt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment