* According to RFC3010, this takes precedence over all other errors.
         */
        status = nfserr_minor_vers_mismatch;
-       if (args->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
+       if (args->minorversion > nfsd_supported_minorversion)
                goto out;
 
        if (!nfs41_op_ordering_ok(args)) {
 
 static ssize_t __write_versions(struct file *file, char *buf, size_t size)
 {
        char *mesg = buf;
-       char *vers, sign;
+       char *vers, *minorp, sign;
        int len, num;
+       unsigned minor;
        ssize_t tlen = 0;
        char *sep;
 
                do {
                        sign = *vers;
                        if (sign == '+' || sign == '-')
-                               num = simple_strtol((vers+1), NULL, 0);
+                               num = simple_strtol((vers+1), &minorp, 0);
                        else
-                               num = simple_strtol(vers, NULL, 0);
+                               num = simple_strtol(vers, &minorp, 0);
+                       if (*minorp == '.') {
+                               if (num < 4)
+                                       return -EINVAL;
+                               minor = simple_strtoul(minorp+1, NULL, 0);
+                               if (minor == 0)
+                                       return -EINVAL;
+                               if (nfsd_minorversion(minor, sign == '-' ?
+                                                    NFSD_CLEAR : NFSD_SET) < 0)
+                                       return -EINVAL;
+                               goto next;
+                       }
                        switch(num) {
                        case 2:
                        case 3:
                        default:
                                return -EINVAL;
                        }
+               next:
                        vers += len + 1;
                        tlen += len;
                } while ((len = qword_get(&mesg, vers, size)) > 0);
                                       num);
                        sep = " ";
                }
+       if (nfsd_vers(4, NFSD_AVAIL))
+               for (minor = 1; minor <= NFSD_SUPPORTED_MINOR_VERSION; minor++)
+                       len += sprintf(buf+len, " %c4.%u",
+                                       (nfsd_vers(4, NFSD_TEST) &&
+                                        nfsd_minorversion(minor, NFSD_TEST)) ?
+                                               '+' : '-',
+                                       minor);
        len += sprintf(buf+len, "\n");
        return len;
 }
 
 
 };
 
+u32 nfsd_supported_minorversion;
+
 int nfsd_vers(int vers, enum vers_op change)
 {
        if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
        }
        return 0;
 }
+
+int nfsd_minorversion(u32 minorversion, enum vers_op change)
+{
+       if (minorversion > NFSD_SUPPORTED_MINOR_VERSION)
+               return -1;
+       switch(change) {
+       case NFSD_SET:
+               nfsd_supported_minorversion = minorversion;
+               break;
+       case NFSD_CLEAR:
+               if (minorversion == 0)
+                       return -1;
+               nfsd_supported_minorversion = minorversion - 1;
+               break;
+       case NFSD_TEST:
+               return minorversion <= nfsd_supported_minorversion;
+       case NFSD_AVAIL:
+               return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
+       }
+       return 0;
+}
+
 /*
  * Maximum number of nfsd processes
  */
 
 extern struct svc_program      nfsd_program;
 extern struct svc_version      nfsd_version2, nfsd_version3,
                                nfsd_version4;
+extern u32                     nfsd_supported_minorversion;
 extern struct mutex            nfsd_mutex;
 extern struct svc_serv         *nfsd_serv;
 
 
 enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
 int nfsd_vers(int vers, enum vers_op change);
+int nfsd_minorversion(u32 minorversion, enum vers_op change);
 void nfsd_reset_versions(void);
 int nfsd_create_serv(void);