5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit f92214e4c312f6ea9d78650cc6291d200f17abb6 ]
If the call to nfs_delegation_grab_inode() fails, we will not have dropped any locks that require us to rescan the list.
Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Reviewed-by: Jeff Layton jlayton@kernel.org Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/delegation.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 1eb6c7a142ff..c15188d0b6b3 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -609,6 +609,9 @@ static int nfs_server_return_marked_delegations(struct nfs_server *server, prev = delegation; continue; } + inode = nfs_delegation_grab_inode(delegation); + if (inode == NULL) + continue;
if (prev) { struct inode *tmp = nfs_delegation_grab_inode(prev); @@ -619,12 +622,6 @@ static int nfs_server_return_marked_delegations(struct nfs_server *server, } }
- inode = nfs_delegation_grab_inode(delegation); - if (inode == NULL) { - rcu_read_unlock(); - iput(to_put); - goto restart; - } delegation = nfs_start_delegation_return_locked(NFS_I(inode)); rcu_read_unlock();
@@ -1140,7 +1137,6 @@ static int nfs_server_reap_unclaimed_delegations(struct nfs_server *server, struct inode *inode; restart: rcu_read_lock(); -restart_locked: list_for_each_entry_rcu(delegation, &server->delegations, super_list) { if (test_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags) || @@ -1151,7 +1147,7 @@ static int nfs_server_reap_unclaimed_delegations(struct nfs_server *server, continue; inode = nfs_delegation_grab_inode(delegation); if (inode == NULL) - goto restart_locked; + continue; delegation = nfs_start_delegation_return_locked(NFS_I(inode)); rcu_read_unlock(); if (delegation != NULL) { @@ -1272,7 +1268,6 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server, nfs4_stateid stateid; restart: rcu_read_lock(); -restart_locked: list_for_each_entry_rcu(delegation, &server->delegations, super_list) { if (test_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags) || @@ -1283,7 +1278,7 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server, continue; inode = nfs_delegation_grab_inode(delegation); if (inode == NULL) - goto restart_locked; + continue; spin_lock(&delegation->lock); cred = get_cred_rcu(delegation->cred); nfs4_stateid_copy(&stateid, &delegation->stateid);