return err;
 }
 
+/**
+ * nfs_inode_return_delegation_on_close - asynchronously return a delegation
+ * @inode: inode to process
+ *
+ * This routine is called on file close in order to determine if the
+ * inode delegation needs to be returned immediately.
+ */
+void nfs4_inode_return_delegation_on_close(struct inode *inode)
+{
+       struct nfs_delegation *delegation;
+       struct nfs_delegation *ret = NULL;
+
+       if (!inode)
+               return;
+       rcu_read_lock();
+       delegation = nfs4_get_valid_delegation(inode);
+       if (!delegation)
+               goto out;
+       if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) {
+               spin_lock(&delegation->lock);
+               if (delegation->inode &&
+                   list_empty(&NFS_I(inode)->open_files) &&
+                   !test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
+                       clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
+                       ret = delegation;
+               }
+               spin_unlock(&delegation->lock);
+       }
+out:
+       rcu_read_unlock();
+       nfs_end_delegation_return(inode, ret, 0);
+}
+
 /**
  * nfs4_inode_make_writeable
  * @inode: pointer to inode
 
 void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
                fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit);
 int nfs4_inode_return_delegation(struct inode *inode);
+void nfs4_inode_return_delegation_on_close(struct inode *inode);
 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
 void nfs_inode_evict_delegation(struct inode *inode);
 
 
        list_del(&state->open_states);
        spin_unlock(&inode->i_lock);
        spin_unlock(&owner->so_lock);
+       nfs4_inode_return_delegation_on_close(inode);
        iput(inode);
        nfs4_free_open_state(state);
        nfs4_put_state_owner(owner);