diff options
author | Trond Myklebust <trondmy@gmail.com> | 2020-01-27 15:58:17 +0100 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2020-02-03 22:35:07 +0100 |
commit | b7b7dac6843e483b6fe8e29cef99e3dbb7594a53 (patch) | |
tree | b396f0c64ae98720ed8c7afb8edcfa57e71569ad /fs/nfs/delegation.c | |
parent | NFS: Clear NFS_DELEGATION_RETURN_IF_CLOSED when the delegation is returned (diff) | |
download | linux-b7b7dac6843e483b6fe8e29cef99e3dbb7594a53.tar.xz linux-b7b7dac6843e483b6fe8e29cef99e3dbb7594a53.zip |
NFSv4: Try to return the delegation immediately when marked for return on close
Add a routine to return the delegation immediately upon close of the
file if it was marked for return-on-close.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r-- | fs/nfs/delegation.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index b5b14618b73e..90e50f32f3e0 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -640,6 +640,39 @@ int nfs4_inode_return_delegation(struct inode *inode) } /** + * nfs_inode_return_delegation_on_close - asynchronously return a delegation + * @inode: inode to process + * + * This routine is called on file close in order to determine if the + * inode delegation needs to be returned immediately. + */ +void nfs4_inode_return_delegation_on_close(struct inode *inode) +{ + struct nfs_delegation *delegation; + struct nfs_delegation *ret = NULL; + + if (!inode) + return; + rcu_read_lock(); + delegation = nfs4_get_valid_delegation(inode); + if (!delegation) + goto out; + if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) { + spin_lock(&delegation->lock); + if (delegation->inode && + list_empty(&NFS_I(inode)->open_files) && + !test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) { + clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags); + ret = delegation; + } + spin_unlock(&delegation->lock); + } +out: + rcu_read_unlock(); + nfs_end_delegation_return(inode, ret, 0); +} + +/** * nfs4_inode_make_writeable * @inode: pointer to inode * |