NFSv4: Add lease breakpoints in case of a delegation recall or return

When we add support for application level leases and knfsd delegations
to the NFS client, we we want to have them safely underpinned by a
"real" delegation to provide the caching guarantees. If that real
delegation is recalled, then we need to ensure that the application
leases/delegations are recalled too.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
Trond Myklebust 2021-05-07 09:14:37 -04:00
parent be20037725
commit 6b4befc0a0
1 changed files with 17 additions and 6 deletions

View File

@ -530,11 +530,18 @@ out:
static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation *delegation, int issync)
{
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
unsigned int mode = O_WRONLY | O_RDWR;
int err = 0;
if (delegation == NULL)
return 0;
do {
if (!issync)
mode |= O_NONBLOCK;
/* Recall of any remaining application leases */
err = break_lease(inode, mode);
while (err == 0) {
if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
break;
err = nfs_delegation_claim_opens(inode, &delegation->stateid,
@ -545,7 +552,7 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation
* Guard against state recovery
*/
err = nfs4_wait_clnt_recover(clp);
} while (err == 0);
}
if (err) {
nfs_abort_delegation_return(delegation, clp, err);
@ -746,13 +753,14 @@ int nfs4_inode_return_delegation(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_delegation *delegation;
int err = 0;
nfs_wb_all(inode);
delegation = nfs_start_delegation_return(nfsi);
/* Synchronous recall of any application leases */
break_lease(inode, O_WRONLY | O_RDWR);
nfs_wb_all(inode);
if (delegation != NULL)
err = nfs_end_delegation_return(inode, delegation, 1);
return err;
return nfs_end_delegation_return(inode, delegation, 1);
return 0;
}
/**
@ -1051,6 +1059,9 @@ int nfs_async_inode_return_delegation(struct inode *inode,
nfs_mark_return_delegation(server, delegation);
rcu_read_unlock();
/* If there are any application leases or delegations, recall them */
break_lease(inode, O_WRONLY | O_RDWR | O_NONBLOCK);
nfs_delegation_run_state_manager(clp);
return 0;
out_enoent: