Commit 0032a7a7 authored by Trond Myklebust's avatar Trond Myklebust

NFS: Don't copy read delegation stateids in setattr

The server will just return an NFS4ERR_OPENMODE anyway.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 2dc31756
...@@ -694,21 +694,25 @@ int nfs_delegations_present(struct nfs_client *clp) ...@@ -694,21 +694,25 @@ int nfs_delegations_present(struct nfs_client *clp)
* nfs4_copy_delegation_stateid - Copy inode's state ID information * nfs4_copy_delegation_stateid - Copy inode's state ID information
* @dst: stateid data structure to fill in * @dst: stateid data structure to fill in
* @inode: inode to check * @inode: inode to check
* @flags: delegation type requirement
* *
* Returns one and fills in "dst->data" * if inode had a delegation, * Returns "true" and fills in "dst->data" * if inode had a delegation,
* otherwise zero is returned. * otherwise "false" is returned.
*/ */
int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode) bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode,
fmode_t flags)
{ {
struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_delegation *delegation; struct nfs_delegation *delegation;
int ret = 0; bool ret;
flags &= FMODE_READ|FMODE_WRITE;
rcu_read_lock(); rcu_read_lock();
delegation = rcu_dereference(nfsi->delegation); delegation = rcu_dereference(nfsi->delegation);
if (delegation != NULL) { ret = (delegation != NULL && (delegation->type & flags) == flags);
if (ret) {
nfs4_stateid_copy(dst, &delegation->stateid); nfs4_stateid_copy(dst, &delegation->stateid);
ret = 1; nfs_mark_delegation_referenced(delegation);
} }
rcu_read_unlock(); rcu_read_unlock();
return ret; return ret;
......
...@@ -54,7 +54,7 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp); ...@@ -54,7 +54,7 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync); int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync);
int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid); int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid);
int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl); int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl);
int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode); bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, fmode_t flags);
void nfs_mark_delegation_referenced(struct nfs_delegation *delegation); void nfs_mark_delegation_referenced(struct nfs_delegation *delegation);
int nfs_have_delegation(struct inode *inode, fmode_t flags); int nfs_have_delegation(struct inode *inode, fmode_t flags);
......
...@@ -1929,7 +1929,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, ...@@ -1929,7 +1929,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
nfs_fattr_init(fattr); nfs_fattr_init(fattr);
if (nfs4_copy_delegation_stateid(&arg.stateid, inode)) { if (nfs4_copy_delegation_stateid(&arg.stateid, inode, FMODE_WRITE)) {
/* Use that stateid */ /* Use that stateid */
} else if (state != NULL) { } else if (state != NULL) {
nfs4_select_rw_stateid(&arg.stateid, state, current->files, current->tgid); nfs4_select_rw_stateid(&arg.stateid, state, current->files, current->tgid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment