Commit d3635ff0 authored by Trond Myklebust's avatar Trond Myklebust Committed by J. Bruce Fields

nfsd: fix configuration of supported minor versions

When the user turns off all minor versions of NFSv4, that should be
equivalent to turning off NFSv4 support, so a mount attempt using NFSv4
should get RPC_PROG_MISMATCH, not NFSERR_MINOR_VERS_MISMATCH.

Allow the user to use either '4.0' or '4' to enable or disable minor
version 0.  Other minor versions are still enabled or disabled using the
'4.x' format.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 7259f1df
...@@ -561,6 +561,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) ...@@ -561,6 +561,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
len = qword_get(&mesg, vers, size); len = qword_get(&mesg, vers, size);
if (len <= 0) return -EINVAL; if (len <= 0) return -EINVAL;
do { do {
enum vers_op cmd;
sign = *vers; sign = *vers;
if (sign == '+' || sign == '-') if (sign == '+' || sign == '-')
num = simple_strtol((vers+1), &minorp, 0); num = simple_strtol((vers+1), &minorp, 0);
...@@ -571,21 +572,20 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) ...@@ -571,21 +572,20 @@ 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;
if (nfsd_minorversion(minor, sign == '-' ? } else
NFSD_CLEAR : NFSD_SET) < 0) minor = 0;
return -EINVAL; cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET;
goto next;
}
switch(num) { switch(num) {
case 2: case 2:
case 3: case 3:
case 4: nfsd_vers(num, cmd);
nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET);
break; break;
case 4:
if (nfsd_minorversion(minor, cmd) >= 0)
break;
default: default:
return -EINVAL; return -EINVAL;
} }
next:
vers += len + 1; vers += len + 1;
} while ((len = qword_get(&mesg, vers, size)) > 0); } while ((len = qword_get(&mesg, vers, size)) > 0);
/* If all get turned off, turn them back on, as /* If all get turned off, turn them back on, as
......
...@@ -153,6 +153,18 @@ int nfsd_vers(int vers, enum vers_op change) ...@@ -153,6 +153,18 @@ int nfsd_vers(int vers, enum vers_op change)
return 0; return 0;
} }
static void
nfsd_adjust_nfsd_versions4(void)
{
unsigned i;
for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++) {
if (nfsd_supported_minorversions[i])
return;
}
nfsd_vers(4, NFSD_CLEAR);
}
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)
...@@ -160,9 +172,11 @@ int nfsd_minorversion(u32 minorversion, enum vers_op change) ...@@ -160,9 +172,11 @@ int nfsd_minorversion(u32 minorversion, enum vers_op change)
switch(change) { switch(change) {
case NFSD_SET: case NFSD_SET:
nfsd_supported_minorversions[minorversion] = true; nfsd_supported_minorversions[minorversion] = true;
nfsd_vers(4, NFSD_SET);
break; break;
case NFSD_CLEAR: case NFSD_CLEAR:
nfsd_supported_minorversions[minorversion] = false; nfsd_supported_minorversions[minorversion] = false;
nfsd_adjust_nfsd_versions4();
break; break;
case NFSD_TEST: case NFSD_TEST:
return nfsd_supported_minorversions[minorversion]; return nfsd_supported_minorversions[minorversion];
......
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