|
@@ -4518,6 +4518,25 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
|
|
|
}
|
|
|
|
|
|
#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()
|
|
|
*
|
|
@@ -4531,7 +4550,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
|
|
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,
|
|
@@ -4548,9 +4567,6 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
|
|
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);
|
|
@@ -4576,6 +4592,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+ status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
|
|
|
dprintk("<-- %s status= %d\n", __func__, status);
|
|
|
return status;
|
|
|
}
|