NFS: Don't copy read delegation stateids in setattr
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Thu, 8 Mar 2012 22:16:12 +0000 (17:16 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 9 Mar 2012 03:37:12 +0000 (22:37 -0500)
The server will just return an NFS4ERR_OPENMODE anyway.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/delegation.c
fs/nfs/delegation.h
fs/nfs/nfs4proc.c

index 97d53574bf531ca39faedef321aa6035f08d482b..e27c0972f94e2bc44b61d5d615d171bb0b6654c5 100644 (file)
@@ -694,21 +694,25 @@ int nfs_delegations_present(struct nfs_client *clp)
  * nfs4_copy_delegation_stateid - Copy inode's state ID information
  * @dst: stateid data structure to fill in
  * @inode: inode to check
+ * @flags: delegation type requirement
  *
- * Returns one and fills in "dst->data" * if inode had a delegation,
- * otherwise zero is returned.
+ * Returns "true" and fills in "dst->data" * if inode had a delegation,
+ * 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_delegation *delegation;
-       int ret = 0;
+       bool ret;
 
+       flags &= FMODE_READ|FMODE_WRITE;
        rcu_read_lock();
        delegation = rcu_dereference(nfsi->delegation);
-       if (delegation != NULL) {
+       ret = (delegation != NULL && (delegation->type & flags) == flags);
+       if (ret) {
                nfs4_stateid_copy(dst, &delegation->stateid);
-               ret = 1;
+               nfs_mark_delegation_referenced(delegation);
        }
        rcu_read_unlock();
        return ret;
index 691a796091842bfcde8de961a8d1b97a1190cd70..e193012123e76c11ea43b8a07b2109f83cf8611d 100644 (file)
@@ -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_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_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);
 int nfs_have_delegation(struct inode *inode, fmode_t flags);
index a8dd04db764f28d78d7284de96c1761335e8d3cd..3578ad36a5b813705cce576413b2bfd08d5ea6c0 100644 (file)
@@ -1929,7 +1929,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
 
        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 */
        } else if (state != NULL) {
                nfs4_select_rw_stateid(&arg.stateid, state, current->files, current->tgid);