aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2010-12-14 10:11:57 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-01-11 14:17:09 -0500
commit357f54d6b38252737116a6d631f6ac28ded018ed (patch)
tree9f2774fb0685659b4fa2f65b9dee3318902d24c9
parent68c404b18f6fba404b2753622d0459c68ee128ae (diff)
NFS fix the setting of exchange id flag
Indicate support for referrals. Do not set any PNFS roles. Check the flags returned by the server for validity. Do not use exchange flags from an old client ID instance when recovering a client ID. Update the EXCHID4_FLAG_XXX set to RFC 5661. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c25
-rw-r--r--include/linux/nfs4.h8
2 files changed, 27 insertions, 6 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f2b92f6a7efb..9d992b0346e3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4519,6 +4519,25 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4519 4519
4520#ifdef CONFIG_NFS_V4_1 4520#ifdef CONFIG_NFS_V4_1
4521/* 4521/*
4522 * Check the exchange flags returned by the server for invalid flags, having
4523 * both PNFS and NON_PNFS flags set, and not having one of NON_PNFS, PNFS, or
4524 * DS flags set.
4525 */
4526static int nfs4_check_cl_exchange_flags(u32 flags)
4527{
4528 if (flags & ~EXCHGID4_FLAG_MASK_R)
4529 goto out_inval;
4530 if ((flags & EXCHGID4_FLAG_USE_PNFS_MDS) &&
4531 (flags & EXCHGID4_FLAG_USE_NON_PNFS))
4532 goto out_inval;
4533 if (!(flags & (EXCHGID4_FLAG_MASK_PNFS)))
4534 goto out_inval;
4535 return NFS_OK;
4536out_inval:
4537 return -NFS4ERR_INVAL;
4538}
4539
4540/*
4522 * nfs4_proc_exchange_id() 4541 * nfs4_proc_exchange_id()
4523 * 4542 *
4524 * Since the clientid has expired, all compounds using sessions 4543 * Since the clientid has expired, all compounds using sessions
@@ -4531,7 +4550,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4531 nfs4_verifier verifier; 4550 nfs4_verifier verifier;
4532 struct nfs41_exchange_id_args args = { 4551 struct nfs41_exchange_id_args args = {
4533 .client = clp, 4552 .client = clp,
4534 .flags = clp->cl_exchange_flags, 4553 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER,
4535 }; 4554 };
4536 struct nfs41_exchange_id_res res = { 4555 struct nfs41_exchange_id_res res = {
4537 .client = clp, 4556 .client = clp,
@@ -4548,9 +4567,6 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4548 dprintk("--> %s\n", __func__); 4567 dprintk("--> %s\n", __func__);
4549 BUG_ON(clp == NULL); 4568 BUG_ON(clp == NULL);
4550 4569
4551 /* Remove server-only flags */
4552 args.flags &= ~EXCHGID4_FLAG_CONFIRMED_R;
4553
4554 p = (u32 *)verifier.data; 4570 p = (u32 *)verifier.data;
4555 *p++ = htonl((u32)clp->cl_boot_time.tv_sec); 4571 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4556 *p = htonl((u32)clp->cl_boot_time.tv_nsec); 4572 *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)
4576 break; 4592 break;
4577 } 4593 }
4578 4594
4595 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
4579 dprintk("<-- %s status= %d\n", __func__, status); 4596 dprintk("<-- %s status= %d\n", __func__, status);
4580 return status; 4597 return status;
4581} 4598}
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 4925b22219d2..9b46300b4305 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -111,9 +111,13 @@
111 111
112#define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001 112#define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001
113#define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002 113#define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002
114#define EXCHGID4_FLAG_BIND_PRINC_STATEID 0x00000100
115
114#define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000 116#define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000
115#define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000 117#define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000
116#define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000 118#define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000
119#define EXCHGID4_FLAG_MASK_PNFS 0x00070000
120
117#define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000 121#define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000
118#define EXCHGID4_FLAG_CONFIRMED_R 0x80000000 122#define EXCHGID4_FLAG_CONFIRMED_R 0x80000000
119/* 123/*
@@ -121,8 +125,8 @@
121 * they're set in the argument or response, have separate 125 * they're set in the argument or response, have separate
122 * invalid flag masks for arg (_A) and resp (_R). 126 * invalid flag masks for arg (_A) and resp (_R).
123 */ 127 */
124#define EXCHGID4_FLAG_MASK_A 0x40070003 128#define EXCHGID4_FLAG_MASK_A 0x40070103
125#define EXCHGID4_FLAG_MASK_R 0x80070003 129#define EXCHGID4_FLAG_MASK_R 0x80070103
126 130
127#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001 131#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001
128#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002 132#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002