diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-10-21 14:22:14 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-11-03 21:28:46 -0500 |
commit | d51f91d262aae047ea3b1496e333a83ce70bb48a (patch) | |
tree | 44aad6ad90239d2925683dc087c7b71368708c5e /fs/nfs/delegation.c | |
parent | f2d47b5502054749b278cdaf9cb9a60415cf884a (diff) | |
download | linux-rpi-d51f91d262aae047ea3b1496e333a83ce70bb48a.tar.gz linux-rpi-d51f91d262aae047ea3b1496e333a83ce70bb48a.tar.bz2 linux-rpi-d51f91d262aae047ea3b1496e333a83ce70bb48a.zip |
NFSv4: Revoke the delegation on success in nfs4_delegreturn_done()
If the delegation was successfully returned, then mark it as revoked.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r-- | fs/nfs/delegation.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index aff2416dc277..8c176c921554 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -806,6 +806,42 @@ void nfs_remove_bad_delegation(struct inode *inode, } EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation); +void nfs_delegation_mark_returned(struct inode *inode, + const nfs4_stateid *stateid) +{ + struct nfs_delegation *delegation; + + if (!inode) + return; + + rcu_read_lock(); + delegation = rcu_dereference(NFS_I(inode)->delegation); + if (!delegation) + goto out_rcu_unlock; + + spin_lock(&delegation->lock); + if (!nfs4_stateid_match_other(stateid, &delegation->stateid)) + goto out_spin_unlock; + if (stateid->seqid) { + /* If delegation->stateid is newer, dont mark as returned */ + if (nfs4_stateid_is_newer(&delegation->stateid, stateid)) + goto out_clear_returning; + if (delegation->stateid.seqid != stateid->seqid) + delegation->stateid.seqid = stateid->seqid; + } + + set_bit(NFS_DELEGATION_REVOKED, &delegation->flags); + +out_clear_returning: + clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags); +out_spin_unlock: + spin_unlock(&delegation->lock); +out_rcu_unlock: + rcu_read_unlock(); + + nfs_inode_find_state_and_recover(inode, stateid); +} + /** * nfs_expire_unused_delegation_types * @clp: client to process |