diff options
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r-- | fs/nfs/delegation.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 07b839560576..6ec2f78c1e19 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -850,16 +850,23 @@ nfs_delegation_find_inode_server(struct nfs_server *server, | |||
850 | const struct nfs_fh *fhandle) | 850 | const struct nfs_fh *fhandle) |
851 | { | 851 | { |
852 | struct nfs_delegation *delegation; | 852 | struct nfs_delegation *delegation; |
853 | struct inode *res = NULL; | 853 | struct inode *freeme, *res = NULL; |
854 | 854 | ||
855 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { | 855 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { |
856 | spin_lock(&delegation->lock); | 856 | spin_lock(&delegation->lock); |
857 | if (delegation->inode != NULL && | 857 | if (delegation->inode != NULL && |
858 | nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { | 858 | nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { |
859 | res = igrab(delegation->inode); | 859 | freeme = igrab(delegation->inode); |
860 | if (freeme && nfs_sb_active(freeme->i_sb)) | ||
861 | res = freeme; | ||
860 | spin_unlock(&delegation->lock); | 862 | spin_unlock(&delegation->lock); |
861 | if (res != NULL) | 863 | if (res != NULL) |
862 | return res; | 864 | return res; |
865 | if (freeme) { | ||
866 | rcu_read_unlock(); | ||
867 | iput(freeme); | ||
868 | rcu_read_lock(); | ||
869 | } | ||
863 | return ERR_PTR(-EAGAIN); | 870 | return ERR_PTR(-EAGAIN); |
864 | } | 871 | } |
865 | spin_unlock(&delegation->lock); | 872 | spin_unlock(&delegation->lock); |