diff mbox

NFS: Fix an rcu deadlock in nfs_delegation_find_inode()

Message ID 20180614133917.27656-1-Anna.Schumaker@Netapp.com (mailing list archive)
State New, archived
Headers show

Commit Message

Anna Schumaker June 14, 2018, 1:39 p.m. UTC
From: Anna Schumaker <Anna.Schumaker@Netapp.com>

I was able to reproduce this pretty regularily using xfstests
generic/013 on NFS v4.0.

Reported-by: Ross Zwisler <Ross.Zwisler@linux.intel.com>
Fixes: a337fe91 (NFSv4: Return NFS4ERR_DELAY when a delegation recall fails due to igrab())
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
---
 fs/nfs/delegation.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Trond Myklebust June 14, 2018, 4:26 p.m. UTC | #1
On Thu, 2018-06-14 at 09:39 -0400, schumaker.anna@gmail.com wrote:
> From: Anna Schumaker <Anna.Schumaker@Netapp.com>

> 

> I was able to reproduce this pretty regularily using xfstests

> generic/013 on NFS v4.0.

> 

> Reported-by: Ross Zwisler <Ross.Zwisler@linux.intel.com>

> Fixes: a337fe91 (NFSv4: Return NFS4ERR_DELAY when a delegation recall

> fails due to igrab())

> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>

> ---

>  fs/nfs/delegation.c | 4 +++-

>  1 file changed, 3 insertions(+), 1 deletion(-)

> 

> diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c

> index bbd0465535eb..f033f3a69a3b 100644

> --- a/fs/nfs/delegation.c

> +++ b/fs/nfs/delegation.c

> @@ -883,8 +883,10 @@ struct inode *nfs_delegation_find_inode(struct

> nfs_client *clp,

>  	rcu_read_lock();

>  	list_for_each_entry_rcu(server, &clp->cl_superblocks,

> client_link) {

>  		res = nfs_delegation_find_inode_server(server,

> fhandle);

> -		if (res != ERR_PTR(-ENOENT))

> +		if (res != ERR_PTR(-ENOENT)) {

> +			rcu_read_unlock();

>  			return res;

> +		}

>  	}

>  	rcu_read_unlock();

>  	return ERR_PTR(-ENOENT);


Oh, duh... Thanks for spotting that!

-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@hammerspace.com
diff mbox

Patch

diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index bbd0465535eb..f033f3a69a3b 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -883,8 +883,10 @@  struct inode *nfs_delegation_find_inode(struct nfs_client *clp,
 	rcu_read_lock();
 	list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
 		res = nfs_delegation_find_inode_server(server, fhandle);
-		if (res != ERR_PTR(-ENOENT))
+		if (res != ERR_PTR(-ENOENT)) {
+			rcu_read_unlock();
 			return res;
+		}
 	}
 	rcu_read_unlock();
 	return ERR_PTR(-ENOENT);