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>
This commit is contained in:
Andy Adamson
2010-12-14 10:11:57 -05:00
committed by Trond Myklebust
parent 68c404b18f
commit 357f54d6b3
2 changed files with 27 additions and 6 deletions

View File

@@ -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;
}