resp->tag = args->tag;
        resp->opcnt = 0;
        resp->rqstp = rqstp;
+       resp->cstate.minorversion = args->minorversion;
        resp->cstate.replay_owner = NULL;
        fh_init(&resp->cstate.current_fh, NFS4_FHSIZE);
        fh_init(&resp->cstate.save_fh, NFS4_FHSIZE);
 
        return NULL;
 }
 
-static inline int access_valid(u32 x)
+static inline int access_valid(u32 x, u32 minorversion)
 {
-       if (x < NFS4_SHARE_ACCESS_READ)
+       if ((x & NFS4_SHARE_ACCESS_MASK) < NFS4_SHARE_ACCESS_READ)
                return 0;
-       if (x > NFS4_SHARE_ACCESS_BOTH)
+       if ((x & NFS4_SHARE_ACCESS_MASK) > NFS4_SHARE_ACCESS_BOTH)
+               return 0;
+       x &= ~NFS4_SHARE_ACCESS_MASK;
+       if (minorversion && x) {
+               if ((x & NFS4_SHARE_WANT_MASK) > NFS4_SHARE_WANT_CANCEL)
+                       return 0;
+               if ((x & NFS4_SHARE_WHEN_MASK) > NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED)
+                       return 0;
+               x &= ~(NFS4_SHARE_WANT_MASK | NFS4_SHARE_WHEN_MASK);
+       }
+       if (x)
                return 0;
        return 1;
 }
        __be32 status;
 
        status = nfserr_inval;
-       if (!access_valid(open->op_share_access)
+       if (!access_valid(open->op_share_access, resp->cstate.minorversion)
                        || !deny_valid(open->op_share_deny))
                goto out;
        /*
                        (int)cstate->current_fh.fh_dentry->d_name.len,
                        cstate->current_fh.fh_dentry->d_name.name);
 
-       if (!access_valid(od->od_share_access)
+       if (!access_valid(od->od_share_access, cstate->minorversion)
                        || !deny_valid(od->od_share_deny))
                return nfserr_inval;