diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-06-07 14:22:00 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-06-08 16:36:10 -0400 |
commit | 6c342655022d5189c45e4f7ed0cc8048c9ad9815 (patch) | |
tree | 7bc991f16509269bffcc2d5e086b50c8930afb8d /fs/nfs/delegation.c | |
parent | 025bb9f8720577b3815263dd961cdebe0c823080 (diff) |
NFSv4: Return NFS4ERR_DELAY when a delegation recall fails due to igrab()
If the attempt to recall the delegation fails because the inode is
in the process of being evicted from cache, then use NFS4ERR_DELAY
to ask the server to retry later.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r-- | fs/nfs/delegation.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 91c3737d69df..bbd0465535eb 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -856,12 +856,14 @@ nfs_delegation_find_inode_server(struct nfs_server *server, if (delegation->inode != NULL && nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { res = igrab(delegation->inode); + spin_unlock(&delegation->lock); + if (res != NULL) + return res; + return ERR_PTR(-EAGAIN); } spin_unlock(&delegation->lock); - if (res != NULL) - break; } - return res; + return ERR_PTR(-ENOENT); } /** @@ -876,16 +878,16 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle) { struct nfs_server *server; - struct inode *res = NULL; + struct inode *res; rcu_read_lock(); list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { res = nfs_delegation_find_inode_server(server, fhandle); - if (res != NULL) - break; + if (res != ERR_PTR(-ENOENT)) + return res; } rcu_read_unlock(); - return res; + return ERR_PTR(-ENOENT); } static void nfs_delegation_mark_reclaim_server(struct nfs_server *server) |