NFSv4: Don't use synchronous delegation recall in exception handling
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sun, 20 Sep 2015 18:58:42 +0000 (14:58 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 8 Oct 2015 14:45:53 +0000 (10:45 -0400)
The code needs to be able to work from inside an asynchronous context.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/delegation.c
fs/nfs/nfs4proc.c

index be806ead7f4d4abfde04321b78ebace12043925e..5166adcfc0fb2379ed75c37b0aa09c8da7550607 100644 (file)
@@ -721,14 +721,12 @@ int nfs_async_inode_return_delegation(struct inode *inode,
        struct nfs_client *clp = server->nfs_client;
        struct nfs_delegation *delegation;
 
-       filemap_flush(inode->i_mapping);
-
        rcu_read_lock();
        delegation = rcu_dereference(NFS_I(inode)->delegation);
        if (delegation == NULL)
                goto out_enoent;
-
-       if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid))
+       if (stateid != NULL &&
+           !clp->cl_mvops->match_stateid(&delegation->stateid, stateid))
                goto out_enoent;
        nfs_mark_return_delegation(server, delegation);
        rcu_read_unlock();
index ae5cde62195446903e6e7214f5e4f74bd9f637e1..2a155ec05f6d022b9a1aa807b6046970b0b8e646 100644 (file)
@@ -362,11 +362,9 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
                case -NFS4ERR_DELEG_REVOKED:
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_BAD_STATEID:
-                       if (inode && nfs4_have_delegation(inode, FMODE_READ)) {
-                               nfs4_inode_return_delegation(inode);
-                               exception->retry = 1;
-                               return 0;
-                       }
+                       if (inode && nfs_async_inode_return_delegation(inode,
+                                               NULL) == 0)
+                               goto wait_on_recovery;
                        if (state == NULL)
                                break;
                        ret = nfs4_schedule_stateid_recovery(server, state);