open->op_truncate = 0;
 
        if (open->op_create) {
+               /* FIXME: check session persistence and pnfs flags.
+                * The nfsv4.1 spec requires the following semantics:
+                *
+                * Persistent   | pNFS   | Server REQUIRED | Client Allowed
+                * Reply Cache  | server |                 |
+                * -------------+--------+-----------------+--------------------
+                * no           | no     | EXCLUSIVE4_1    | EXCLUSIVE4_1
+                *              |        |                 | (SHOULD)
+                *              |        | and EXCLUSIVE4  | or EXCLUSIVE4
+                *              |        |                 | (SHOULD NOT)
+                * no           | yes    | EXCLUSIVE4_1    | EXCLUSIVE4_1
+                * yes          | no     | GUARDED4        | GUARDED4
+                * yes          | yes    | GUARDED4        | GUARDED4
+                */
+
                /*
                 * Note: create modes (UNCHECKED,GUARDED...) are the same
                 * in NFSv4 as in v3.
 
        NFSD_WRITEABLE_ATTRS_WORD2
 };
 
+static u32 nfsd41_ex_attrmask[] = {
+       NFSD_SUPPATTR_EXCLCREAT_WORD0,
+       NFSD_SUPPATTR_EXCLCREAT_WORD1,
+       NFSD_SUPPATTR_EXCLCREAT_WORD2
+};
+
 static __be32
 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
                   struct iattr *iattr, struct nfs4_acl **acl)
                        READ_BUF(8);
                        COPYMEM(open->op_verf.data, 8);
                        break;
+               case NFS4_CREATE_EXCLUSIVE4_1:
+                       if (argp->minorversion < 1)
+                               goto xdr_error;
+                       READ_BUF(8);
+                       COPYMEM(open->op_verf.data, 8);
+                       status = nfsd4_decode_fattr(argp, open->op_bmval,
+                               nfsd41_ex_attrmask, &open->op_iattr,
+                               &open->op_acl);
+                       if (status)
+                               goto out;
+                       break;
                default:
                        goto xdr_error;
                }
 
 enum createmode4 {
        NFS4_CREATE_UNCHECKED = 0,
        NFS4_CREATE_GUARDED = 1,
-       NFS4_CREATE_EXCLUSIVE = 2
+       NFS4_CREATE_EXCLUSIVE = 2,
+       /*
+        * New to NFSv4.1. If session is persistent,
+        * GUARDED4 MUST be used. Otherwise, use
+        * EXCLUSIVE4_1 instead of EXCLUSIVE4.
+        */
+       NFS4_CREATE_EXCLUSIVE4_1 = 3
 };
 
 enum limit_by4 {
 
        u32             op_create;          /* request */
        u32             op_createmode;      /* request */
        u32             op_bmval[3];        /* request */
-       union {                             /* request */
-               struct iattr    iattr;                      /* UNCHECKED4,GUARDED4 */
-               nfs4_verifier   verf;                                /* EXCLUSIVE4 */
-       } u;
+       struct iattr    iattr;              /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
+       nfs4_verifier   verf;               /* EXCLUSIVE4 */
        clientid_t      op_clientid;        /* request */
        struct xdr_netobj op_owner;           /* request */
        u32             op_seqid;           /* request */
        struct nfs4_stateowner *op_stateowner; /* used during processing */
        struct nfs4_acl *op_acl;
 };
-#define op_iattr       u.iattr
-#define op_verf                u.verf
+#define op_iattr       iattr
+#define op_verf                verf
 
 struct nfsd4_open_confirm {
        stateid_t       oc_req_stateid          /* request */;