}
 
 #ifdef CONFIG_NFS_V4_1
+/*
+ * Check the exchange flags returned by the server for invalid flags, having
+ * both PNFS and NON_PNFS flags set, and not having one of NON_PNFS, PNFS, or
+ * DS flags set.
+ */
+static int nfs4_check_cl_exchange_flags(u32 flags)
+{
+       if (flags & ~EXCHGID4_FLAG_MASK_R)
+               goto out_inval;
+       if ((flags & EXCHGID4_FLAG_USE_PNFS_MDS) &&
+           (flags & EXCHGID4_FLAG_USE_NON_PNFS))
+               goto out_inval;
+       if (!(flags & (EXCHGID4_FLAG_MASK_PNFS)))
+               goto out_inval;
+       return NFS_OK;
+out_inval:
+       return -NFS4ERR_INVAL;
+}
+
 /*
  * nfs4_proc_exchange_id()
  *
        nfs4_verifier verifier;
        struct nfs41_exchange_id_args args = {
                .client = clp,
-               .flags = clp->cl_exchange_flags,
+               .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER,
        };
        struct nfs41_exchange_id_res res = {
                .client = clp,
        dprintk("--> %s\n", __func__);
        BUG_ON(clp == NULL);
 
-       /* Remove server-only flags */
-       args.flags &= ~EXCHGID4_FLAG_CONFIRMED_R;
-
        p = (u32 *)verifier.data;
        *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
        *p = htonl((u32)clp->cl_boot_time.tv_nsec);
                        break;
        }
 
+       status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
        dprintk("<-- %s status= %d\n", __func__, status);
        return status;
 }
 
 
 #define EXCHGID4_FLAG_SUPP_MOVED_REFER         0x00000001
 #define EXCHGID4_FLAG_SUPP_MOVED_MIGR          0x00000002
+#define EXCHGID4_FLAG_BIND_PRINC_STATEID       0x00000100
+
 #define EXCHGID4_FLAG_USE_NON_PNFS             0x00010000
 #define EXCHGID4_FLAG_USE_PNFS_MDS             0x00020000
 #define EXCHGID4_FLAG_USE_PNFS_DS              0x00040000
+#define EXCHGID4_FLAG_MASK_PNFS                        0x00070000
+
 #define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A      0x40000000
 #define EXCHGID4_FLAG_CONFIRMED_R              0x80000000
 /*
  * they're set in the argument or response, have separate
  * invalid flag masks for arg (_A) and resp (_R).
  */
-#define EXCHGID4_FLAG_MASK_A                   0x40070003
-#define EXCHGID4_FLAG_MASK_R                   0x80070003
+#define EXCHGID4_FLAG_MASK_A                   0x40070103
+#define EXCHGID4_FLAG_MASK_R                   0x80070103
 
 #define SEQ4_STATUS_CB_PATH_DOWN               0x00000001
 #define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING   0x00000002