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: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
7259f1dfe7
commit
d3635ff07e
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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];
|
||||||
|
|
Loading…
Reference in New Issue