Skip to content

Commit 357f54d

Browse files
androsadamsonTrond Myklebust
authored andcommitted
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>
1 parent 68c404b commit 357f54d

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

fs/nfs/nfs4proc.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4518,6 +4518,25 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
45184518
}
45194519

45204520
#ifdef CONFIG_NFS_V4_1
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+
*/
4526+
static 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;
4536+
out_inval:
4537+
return -NFS4ERR_INVAL;
4538+
}
4539+
45214540
/*
45224541
* nfs4_proc_exchange_id()
45234542
*
@@ -4531,7 +4550,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
45314550
nfs4_verifier verifier;
45324551
struct nfs41_exchange_id_args args = {
45334552
.client = clp,
4534-
.flags = clp->cl_exchange_flags,
4553+
.flags = EXCHGID4_FLAG_SUPP_MOVED_REFER,
45354554
};
45364555
struct nfs41_exchange_id_res res = {
45374556
.client = clp,
@@ -4548,9 +4567,6 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
45484567
dprintk("--> %s\n", __func__);
45494568
BUG_ON(clp == NULL);
45504569

4551-
/* Remove server-only flags */
4552-
args.flags &= ~EXCHGID4_FLAG_CONFIRMED_R;
4553-
45544570
p = (u32 *)verifier.data;
45554571
*p++ = htonl((u32)clp->cl_boot_time.tv_sec);
45564572
*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)
45764592
break;
45774593
}
45784594

4595+
status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
45794596
dprintk("<-- %s status= %d\n", __func__, status);
45804597
return status;
45814598
}

include/linux/nfs4.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,18 +111,22 @@
111111

112112
#define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001
113113
#define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002
114+
#define EXCHGID4_FLAG_BIND_PRINC_STATEID 0x00000100
115+
114116
#define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000
115117
#define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000
116118
#define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000
119+
#define EXCHGID4_FLAG_MASK_PNFS 0x00070000
120+
117121
#define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000
118122
#define EXCHGID4_FLAG_CONFIRMED_R 0x80000000
119123
/*
120124
* Since the validity of these bits depends on whether
121125
* they're set in the argument or response, have separate
122126
* invalid flag masks for arg (_A) and resp (_R).
123127
*/
124-
#define EXCHGID4_FLAG_MASK_A 0x40070003
125-
#define EXCHGID4_FLAG_MASK_R 0x80070003
128+
#define EXCHGID4_FLAG_MASK_A 0x40070103
129+
#define EXCHGID4_FLAG_MASK_R 0x80070103
126130

127131
#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001
128132
#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002

0 commit comments

Comments
 (0)