diff options
| author | Trond Myklebust <trond.myklebust@primarydata.com> | 2017-02-22 18:35:32 -0500 |
|---|---|---|
| committer | J. Bruce Fields <bfields@redhat.com> | 2017-02-27 18:04:08 -0500 |
| commit | d3635ff07e8ca598d44f72bbf5d6c65b8ebeeb46 (patch) | |
| tree | b0de5bf1afd7508f312d2ea60183e5a9c8b58222 | |
| parent | 7259f1dfe718234fee3f87d98d082e7f98d1d712 (diff) | |
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>
| -rw-r--r-- | fs/nfsd/nfsctl.c | 16 | ||||
| -rw-r--r-- | fs/nfsd/nfssvc.c | 14 |
2 files changed, 22 insertions, 8 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index d54fb0e3f30e..4bbba88416dc 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
| @@ -561,6 +561,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) | |||
| 561 | len = qword_get(&mesg, vers, size); | 561 | len = qword_get(&mesg, vers, size); |
| 562 | if (len <= 0) return -EINVAL; | 562 | if (len <= 0) return -EINVAL; |
| 563 | do { | 563 | do { |
| 564 | enum vers_op cmd; | ||
| 564 | sign = *vers; | 565 | sign = *vers; |
| 565 | if (sign == '+' || sign == '-') | 566 | if (sign == '+' || sign == '-') |
| 566 | num = simple_strtol((vers+1), &minorp, 0); | 567 | 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 | return -EINVAL; | 572 | return -EINVAL; |
| 572 | if (kstrtouint(minorp+1, 0, &minor) < 0) | 573 | if (kstrtouint(minorp+1, 0, &minor) < 0) |
| 573 | return -EINVAL; | 574 | return -EINVAL; |
| 574 | if (nfsd_minorversion(minor, sign == '-' ? | 575 | } else |
| 575 | NFSD_CLEAR : NFSD_SET) < 0) | 576 | minor = 0; |
| 576 | return -EINVAL; | 577 | cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET; |
| 577 | goto next; | ||
| 578 | } | ||
| 579 | switch(num) { | 578 | switch(num) { |
| 580 | case 2: | 579 | case 2: |
| 581 | case 3: | 580 | case 3: |
| 582 | case 4: | 581 | nfsd_vers(num, cmd); |
| 583 | nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET); | ||
| 584 | break; | 582 | break; |
| 583 | case 4: | ||
| 584 | if (nfsd_minorversion(minor, cmd) >= 0) | ||
| 585 | break; | ||
| 585 | default: | 586 | default: |
| 586 | return -EINVAL; | 587 | return -EINVAL; |
| 587 | } | 588 | } |
| 588 | next: | ||
| 589 | vers += len + 1; | 589 | vers += len + 1; |
| 590 | } while ((len = qword_get(&mesg, vers, size)) > 0); | 590 | } while ((len = qword_get(&mesg, vers, size)) > 0); |
| 591 | /* If all get turned off, turn them back on, as | 591 | /* If all get turned off, turn them back on, as |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 2e378d0479ad..efd66da99201 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
| @@ -153,6 +153,18 @@ int nfsd_vers(int vers, enum vers_op change) | |||
| 153 | return 0; | 153 | return 0; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | static void | ||
| 157 | nfsd_adjust_nfsd_versions4(void) | ||
| 158 | { | ||
| 159 | unsigned i; | ||
| 160 | |||
| 161 | for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++) { | ||
| 162 | if (nfsd_supported_minorversions[i]) | ||
| 163 | return; | ||
| 164 | } | ||
| 165 | nfsd_vers(4, NFSD_CLEAR); | ||
| 166 | } | ||
| 167 | |||
| 156 | int nfsd_minorversion(u32 minorversion, enum vers_op change) | 168 | int nfsd_minorversion(u32 minorversion, enum vers_op change) |
| 157 | { | 169 | { |
| 158 | if (minorversion > NFSD_SUPPORTED_MINOR_VERSION) | 170 | if (minorversion > NFSD_SUPPORTED_MINOR_VERSION) |
| @@ -160,9 +172,11 @@ int nfsd_minorversion(u32 minorversion, enum vers_op change) | |||
| 160 | switch(change) { | 172 | switch(change) { |
| 161 | case NFSD_SET: | 173 | case NFSD_SET: |
| 162 | nfsd_supported_minorversions[minorversion] = true; | 174 | nfsd_supported_minorversions[minorversion] = true; |
| 175 | nfsd_vers(4, NFSD_SET); | ||
| 163 | break; | 176 | break; |
| 164 | case NFSD_CLEAR: | 177 | case NFSD_CLEAR: |
| 165 | nfsd_supported_minorversions[minorversion] = false; | 178 | nfsd_supported_minorversions[minorversion] = false; |
| 179 | nfsd_adjust_nfsd_versions4(); | ||
| 166 | break; | 180 | break; |
| 167 | case NFSD_TEST: | 181 | case NFSD_TEST: |
| 168 | return nfsd_supported_minorversions[minorversion]; | 182 | return nfsd_supported_minorversions[minorversion]; |
