Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: b757144fd77c ("NFSv4: Be less aggressive about returning delegations for open files")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>

+18 -15
+18 -15
fs/nfs/delegation.c
··· 590 590 591 591 if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags)) 592 592 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); 604 593 if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags) || 605 594 test_bit(NFS_DELEGATION_RETURN_DELAYED, &delegation->flags) || 606 595 test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) ··· 867 878 return nfs4_inode_return_delegation(inode); 868 879 } 869 880 870 - static void nfs_mark_return_if_closed_delegation(struct nfs_server *server, 871 - struct nfs_delegation *delegation) 881 + static void 882 + nfs_mark_return_if_closed_delegation(struct nfs_server *server, 883 + struct nfs_delegation *delegation) 872 884 { 873 - set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags); 874 - set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state); 885 + struct inode *inode; 886 + 887 + if (test_bit(NFS_DELEGATION_RETURN, &delegation->flags) || 888 + test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) 889 + return; 890 + spin_lock(&delegation->lock); 891 + inode = delegation->inode; 892 + if (!inode) 893 + goto out; 894 + if (list_empty(&NFS_I(inode)->open_files)) 895 + nfs_mark_return_delegation(server, delegation); 896 + else 897 + set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags); 898 + out: 899 + spin_unlock(&delegation->lock); 875 900 } 876 901 877 902 static bool nfs_server_mark_return_all_delegations(struct nfs_server *server)