Skip to content

Commit 47acca8

Browse files
author
Trond Myklebust
committed
NFSv4: Don't trigger uneccessary scans for return-on-close delegations
The amount of looping through the list of delegations is occasionally leading to soft lockups. Avoid at least some loops by not requiring the NFSv4 state manager to scan for delegations that are marked for return-on-close. Instead, either mark them for immediate return (if possible) or else leave it up to nfs4_inode_return_delegation_on_close() to return them once the file is closed by the application. Fixes: b757144 ("NFSv4: Be less aggressive about returning delegations for open files") Signed-off-by: Trond Myklebust <[email protected]>
1 parent 4701f33 commit 47acca8

File tree

1 file changed

+18
-15
lines changed

1 file changed

+18
-15
lines changed

fs/nfs/delegation.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -590,17 +590,6 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
590590

591591
if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
592592
ret = true;
593-
else if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) {
594-
struct inode *inode;
595-
596-
spin_lock(&delegation->lock);
597-
inode = delegation->inode;
598-
if (inode && list_empty(&NFS_I(inode)->open_files))
599-
ret = true;
600-
spin_unlock(&delegation->lock);
601-
}
602-
if (ret)
603-
clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
604593
if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags) ||
605594
test_bit(NFS_DELEGATION_RETURN_DELAYED, &delegation->flags) ||
606595
test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
@@ -878,11 +867,25 @@ int nfs4_inode_make_writeable(struct inode *inode)
878867
return nfs4_inode_return_delegation(inode);
879868
}
880869

881-
static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
882-
struct nfs_delegation *delegation)
870+
static void
871+
nfs_mark_return_if_closed_delegation(struct nfs_server *server,
872+
struct nfs_delegation *delegation)
883873
{
884-
set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
885-
set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
874+
struct inode *inode;
875+
876+
if (test_bit(NFS_DELEGATION_RETURN, &delegation->flags) ||
877+
test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags))
878+
return;
879+
spin_lock(&delegation->lock);
880+
inode = delegation->inode;
881+
if (!inode)
882+
goto out;
883+
if (list_empty(&NFS_I(inode)->open_files))
884+
nfs_mark_return_delegation(server, delegation);
885+
else
886+
set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
887+
out:
888+
spin_unlock(&delegation->lock);
886889
}
887890

888891
static bool nfs_server_mark_return_all_delegations(struct nfs_server *server)

0 commit comments

Comments
 (0)